지금 만들고 있는게 네트워크에 접속해서 xml파일을 10.1에 다운받고 서버에 있는 xml이랑 비교해서
더 최신인 파일이 있는지 체크해서 해당 파일을 10.1로 다운받게 하는 그런 거거든요.
근데 문제는 20개 정도 다운로드 받을게 나오면 그 중에 4~5개정도는 실패한다는거예요. 100% 성공해야되거든요.
실패하는 이유를 모르겠습니다. 고수님들 좀 도와주세요 ㅠㅠ
해당 부분 소스는 이렇습니다.
(url은 실제 주소를 올리지 못하는 점 양해 바랍니다.)
public class DownloadManagerWebView extends Activity
{
/** Called when the activity is first created. */
WebView mWeb;
//파일 다운로드에 쓰이는 변수
private long latestId = -1;
private DownloadManager downloadManager;
private DownloadManager.Request request;
private Uri urlToDownload;
long stateId = -1;
int downFileCnt = 0;
int finalCnt = -1;
//무선 네트워크 관련 변수
ConnectivityManager cManager;
NetworkInfo mobile;
NetworkInfo wifi;
NetworkInfo ni;
String netName = "";
//fileinfo.xml(서버와 로컬)을 대조후 더 최신파일을 서버에서 다운받는 기능을 구현한 클래스
Parser parser;
private BroadcastReceiver completeReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent) {
Log.d("dd", "브로드캐스트리시버 호출~!!!!!!!");
finalCnt++;
Log.d("dd", "finalCnt = " + finalCnt);
//여러개의 파일이 다운로드 될 때 마다 토스트를 띄우는 것을 방지하기 위함~!!
if (finalCnt == downFileCnt)
{
Log.d("dd", "다운로드 완료 토스트 띄우기~!!!!!!!");
Toast.makeText(context, "다운로드가 완료되었습니다.", Toast.LENGTH_SHORT).show();
}
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWeb = (WebView)findViewById(R.id.web);
//액티비티 안의 웹 뷰에 사이트가 열린다.
mWeb.setWebViewClient(new MyWebClient());
mWeb.setWebChromeClient(new WebChromeClient()
{
@Override
public void onReachedMaxAppCacheSize(long spaceNeeded, long totalUsedQuota, QuotaUpdater quotaUpdater)
{
quotaUpdater.updateQuota(spaceNeeded * 2);
}
});
/////// 웹뷰 세부사항 설정하는 부분 ///////
WebSettings set = mWeb.getSettings();
set.setJavaScriptEnabled(true); //--- JavaScript 허용
set.setBuiltInZoomControls(true);
set.setGeolocationEnabled(true); //--- 위치 정보 사용 허용
set.setJavaScriptCanOpenWindowsAutomatically(true);
set.setLoadsImagesAutomatically(true);
//set.setPluginsEnabled(true);
set.setPluginState(WebSettings.PluginState.ON);
set.setLightTouchEnabled(true);
set.setSupportZoom(true);
//--- HTML5에서 Database를 설정 한다.
set.setDatabaseEnabled(true); //--- HTML5에서 Database 허용
//--- Database를 위해 WebChromeClient.onExceededDatabaseQuota(~) 함수도 같이 설정할 것
set.setDatabasePath("/mnt/sdcard/Android/data/com.DownloadManagerWebView/database");
//--- HTML5에서 DOM Storage를 설정 한다.
set.setDomStorageEnabled(true); //--- HTML5 DOM Storage 허용
//--- HTML5에서 Cache 설정을 한다.
//--- Database를 위해 WebChromeClient.onReachedMaxAppCacheSize(~) 함수도 같이 설정할 것
set.setAppCacheMaxSize(1024 * 1024 * 8); //--- Default Cache Size를 8 MB로 설정
set.setAppCachePath("/mnt/sdcard/Android/data/com.DownloadManagerWebView/cache");
set.setAppCacheEnabled(true);
set.setAllowFileAccess(true);
set.setCacheMode(WebSettings.LOAD_DEFAULT);
/////// 웹뷰 세부사항 설정하는 부분 종료 ///////
mWeb.loadUrl("file://mnt/sdcard/b/main.html");
//ConnectivityManager로 3G, Wi-Fi 접속 여부를 알아낸다.
cManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
mobile = cManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
wifi = cManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(mobile.isConnected() || wifi.isConnected())
{
//3G 또는 WiFi 에 연결되어 있을 경우
ni = cManager.getActiveNetworkInfo();
netName = ni.getTypeName();
Log.d("dd", "[브로드]" + netName + "에 연결되어있음~!!");
//다운로드매니저로 파일 다운로드기능 활성화
downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
String mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String FileName = mSdPath + "/a/xml/fileinfo.xml";
File f = new File(FileName);
if(!f.exists())
{
downloadXMLFile();
}
parser = new Parser(); //파서를 객체 생성합니다.
new ContentAsync().execute(null, null, null); //AsyncTask를 사용하여 Thread 처리합니다.
} else
{
ni = null;
netName = "None";
Log.d("dd", "[브로드]" + netName + " 에 연결되어있음~!!");
}
}
public class ContentAsync extends AsyncTask<String, String, ArrayList<Files>>
{
boolean bUpdated = false;
@Override
protected ArrayList<Files> doInBackground(String... params) {
return parser.connectFiles(); //파싱 정보를 ArrayList로 가지고 옵니다.
}
@Override
protected void onPostExecute(final ArrayList<Files> result) {
//결과처리 & 출력
int cnt = 0;
final ArrayList<Files> localXML = parser.parsingLocalXMLFile();
//서버의 fileinfo.xml과 로컬을 비교해서 서버가 더 최신인 파일이 있으면 다운받는다.
for (int i = 0; i < result.size(); i++)
{
if (!result.get(i).getVer().equals(localXML.get(i).getVer()))
{
cnt++;
}
}
if (cnt > 0)
{
new AlertDialog.Builder(TechwinWebView.this)
.setTitle("업데이트")
.setMessage("업데이트 하시겠습니까?")
.setPositiveButton("예", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
for (int i = 0; i < result.size(); i++)
{
stateId = -1;
if (!result.get(i).getVer().equals(localXML.get(i).getVer()))
{
stateId = downloadFile(result.get(i).getFileName());
if (stateId != -1)
{
downFileCnt++;
Log.d("dd", "downFileCnt = " + downFileCnt);
}
}
}
bUpdated = true;
if (bUpdated == true)
{
stateId = -1;
stateId = downloadXMLFile();
if (stateId != -1)
{
Log.d("dd", "downloadXMLFile() 완료~!!");
}
}
}
})
.setNegativeButton("아니오", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//Toast.makeText(TechwinWebView.this, "bUpdated : " + bUpdated, Toast.LENGTH_SHORT).show();
}
})
.show();
}
}
}
@Override
public void onResume()
{
Log.d("dd", "onResume()");
super.onResume();
//파일 다운로드 완료후 처리..
IntentFilter completeFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(completeReceiver, completeFilter);
}
//public void downloadXMLFile()
public long downloadXMLFile()
{
long latestId = -1;
Log.d("dd", "downloadXMLFile()");
String DownloadURL = "http://a.com/b/xml/fileinfo.xml";
String mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String downPath = mSdPath + "/b/xml/fileinfo.xml";
urlToDownload = Uri.parse(DownloadURL);
List<String> pathSegments = urlToDownload.getPathSegments();
request = new DownloadManager.Request(urlToDownload)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
//new File(mSdPath + "/downTest").mkdirs();
File f = new File(downPath);
if (f.exists()) {
f.delete();
}
request.setDestinationUri(Uri.fromFile(new File(downPath)));
//request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, pathSegments.get(pathSegments.size()-1));
//Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdirs();
latestId = downloadManager.enqueue(request);
Log.d("dd", latestId + "");
return latestId;
}
//public void downloadFile(String downFileName)
public long downloadFile(String downFileName)
{
long latestId = -1;
Log.d("dd", "downloadFile()");
String DownloadURL = "http://a.com/" + downFileName;
String mSdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String downPath = mSdPath + "/" + downFileName;
urlToDownload = Uri.parse(DownloadURL);
List<String> pathSegments = urlToDownload.getPathSegments();
request = new DownloadManager.Request(urlToDownload)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
Log.d("dd", "downFileName = " + downFileName);
File f = new File(downPath);
if (f.exists()) {
f.delete();
}
request.setDestinationUri(Uri.fromFile(new File(downPath)));
latestId = downloadManager.enqueue(request);
//downFileCnt++;
//Log.d("dd", "downFileCnt = " + downFileCnt);
Log.d("dd", latestId + "");
return latestId;
}
class MyWebClient extends WebViewClient
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl("url);
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
String url;
url = "file://mnt/sdcard/b/main.html";
// The magic redirect
if( url.equals(failingUrl) ) {
// main.html is the place we are redirected to by the server if we are online
//mWeb.loadUrl("url + "index.html");
mWeb.loadUrl("url);
return;
}
//else if( (url + "index.html").equals(failingUrl) ) {
else if( (url).equals(failingUrl) ) {
// The cache failed – We don't have an offline version to show
// This code removes the ugly android's "can't open page"
// and simply shows a dialog stating we have no network
view.loadData("", "text/html", "UTF-8");
//showDialog(DIALOG_NONETWORK);
//showDialog(ERROR_CONNECT);
}
}
}
}
아미 테스트를 많이 해보셔서 대충 느낌이 오셨을테지만..
저도 DownloadManager로 파일 다운로드할려고 했었는데 때려쳤습니다..
DownloadManager를 통해서 파일 다운로드해서 완료됐을때 리시버를 통해서 응답을 보면..
분명 Complete메세지가 오긴 옵니다. 근데 연달아서 Fail도 오고 UnSuccessful도 오더군요..
그리고.. fail, unsuccessful이 들어오면 해당파일은 삭제되는듯 합니다.. 캐쉬나 아님 다른곳에 남아있긴한거 같더군요..
암튼.. DownloadManager를 일줄간 써보고 신뢰할수가 없었습니다.. 걍 새로 짜시거나..
아님 인터넷에서 이미 많이 돌아다니는 Download관련 class를 가져다가 쓰시는게 정신건강에 좋을겁니다..




이걸 다 보기는 힘들고..
다운로드는 Thread를 이용해서 돌릴거 같은데 Thread에 다운 받을 파일경로 Queue가 있을거고
다운받는 중 exception이 발생하면 받던 파일은 삭제하고, 다운 받을 경로를 queue에 넣으면 되지 않을까요?