web-dev-qa-db-ja.com

ダウンロードが成功または失敗するまでダウンロードマネージャーのインテントのステータスを受け取る方法

これが私の問題です。 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にジャンプすることはありません。

11
user3887053

ダウンロードマネージャーを再クエリする必要があります。データが変わってもカーソルは変わりません。このようにしてみてください:

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;
    }    
}
6
Denley Bihari

AsyncTaskや同期クエリは必要ありません。 DownloadManagerはすでに非同期です。ダウンロードが完了した(または失敗した)ときに通知を受け取るように、BroadcastReceiverをACTION_DOWNLOAD_COMPLETEに登録する必要があります。

http://blog.vogella.com/2011/06/14/Android-downloadmanager-example に非常に良い例があります。

8
GreyBeardedGeek

ダウンロードマネージャーは、非同期でファイルをダウンロードします。したがって、ダウンロードマネージャーを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>
3
Amal Dev S I