これが私の問題です。 Asynctaskを介してダウンロードマネージャーインテントを使用してサーバーからファイルをダウンロードしようとしています。 asynctaskクラスのdoInBackgroundで、ダウンロードマネージャーのインテントを呼び出しました。ダウンロードが終了すると(成功または失敗)、doinBackgroundはブール値を返します。これが私のコードです
protected Boolean doInBackground(String... f_url) {
boolean flag = true;
boolean downloading =true;
try{
DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Request mRqRequest = new Request(
Uri.parse("http://"+model.getDownloadURL()));
long idDownLoad=mManager.enqueue(mRqRequest);
DownloadManager.Query query = null;
query = new DownloadManager.Query();
Cursor c = null;
if(query!=null) {
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PAUSED|DownloadManager.STATUS_SUCCESSFUL|
DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_PENDING);
} else {
return flag;
}
c = mManager.query(query);
if(c.moveToFirst()) {
int status =c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
while (downloading)
{ Log.i ("FLAG","Downloading");
if (status==DownloadManager.STATUS_SUCCESSFUL)
{ Log.i ("FLAG","done");
downloading = false;
flag=true;
break;
}
if (status==DownloadManager.STATUS_FAILED)
{Log.i ("FLAG","Fail");
downloading = false;
flag=false;
break;
}
c.moveToFirst();
}
}
return flag;
}
catch (Exception e)
{
flag = false;
return flag;
}
}
ただし、DownloadManagerのステータスがDownloadManager.STATUS_SUCCESSFULまたはDownloadManager.STATUS_FAILEDにジャンプすることはありません。
ダウンロードマネージャーを再クエリする必要があります。データが変わってもカーソルは変わりません。このようにしてみてください:
protected Boolean doInBackground(String... f_url) {
boolean flag = true;
boolean downloading =true;
try{
DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Request mRqRequest = new Request(
Uri.parse("http://"+model.getDownloadURL()));
long idDownLoad=mManager.enqueue(mRqRequest);
DownloadManager.Query query = null;
query = new DownloadManager.Query();
Cursor c = null;
if(query!=null) {
query.setFilterByStatus(DownloadManager.STATUS_FAILED|DownloadManager.STATUS_PAUSED|DownloadManager.STATUS_SUCCESSFUL|DownloadManager.STATUS_RUNNING|DownloadManager.STATUS_PENDING);
} else {
return flag;
}
while (downloading) {
c = mManager.query(query);
if(c.moveToFirst()) {
Log.i ("FLAG","Downloading");
int status =c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status==DownloadManager.STATUS_SUCCESSFUL) {
Log.i ("FLAG","done");
downloading = false;
flag=true;
break;
}
if (status==DownloadManager.STATUS_FAILED) {
Log.i ("FLAG","Fail");
downloading = false;
flag=false;
break;
}
}
}
return flag;
}catch (Exception e) {
flag = false;
return flag;
}
}
AsyncTaskや同期クエリは必要ありません。 DownloadManagerはすでに非同期です。ダウンロードが完了した(または失敗した)ときに通知を受け取るように、BroadcastReceiverをACTION_DOWNLOAD_COMPLETEに登録する必要があります。
http://blog.vogella.com/2011/06/14/Android-downloadmanager-example に非常に良い例があります。
ダウンロードマネージャーは、非同期でファイルをダウンロードします。したがって、ダウンロードマネージャーをAsyntask内に配置する必要はありません。
ダウンロードが完了した場合、ダウンロードマネージャーのステータスを取得するためにReceiverを使用できます。
public class CheckDownloadComplete extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
{
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0));
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Cursor cursor = manager.query(query);
if (cursor.moveToFirst()) {
if (cursor.getCount() > 0) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
Long download_id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,0);
// status contain Download Status
// download_id contain current download reference id
if (status == DownloadManager.STATUS_SUCCESSFUL)
{
String file = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
//file contains downloaded file name
// do your stuff here on download success
}
}
}
cursor.close();
}
}
}
マニフェストにレシーバーを追加することを忘れないでください
<receiver
Android:name=".CheckDownloadComplete"
Android:enabled="true"
Android:exported="true" >
<intent-filter>
<action Android:name="Android.intent.action.DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>