2013-02-10 12 views
13

ダウンロードマネージャのクラスを自分のアクティビティ内で使用してダウンロードを実行しました。それはうまく動作し、私の次の仕事は私の活動の中で同じ進​​歩率を示すことです。私はそれを行う方法がわかりません。アクティビティ内でダウンロードマネージャの進行状況を表示

私のコード今のところ

public class DownloadSampleBook extends Activity{ 

private long enqueue; 
private DownloadManager dm; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_sample_download); 

    BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { 
       long downloadId = intent.getLongExtra(
         DownloadManager.EXTRA_DOWNLOAD_ID, 0); 
       Query query = new Query(); 
       query.setFilterById(enqueue); 
       Cursor c = dm.query(query); 
       if (c.moveToFirst()) { 
        int columnIndex = c 
          .getColumnIndex(DownloadManager.COLUMN_STATUS); 
        if (DownloadManager.STATUS_SUCCESSFUL == c 
          .getInt(columnIndex)) { 

         view.setImageURI(Uri.parse(uriString)); 
        } 
       } 
      } 
     } 
    }; 

    registerReceiver(receiver, new IntentFilter(
      DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 
} 

public void onClick(View view) { 
    dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); 
    Request request = new Request(
      Uri.parse("http://abc.com/a.png")); 
    enqueue = dm.enqueue(request); 

} 

public void showDownload(View view) { 
    Intent i = new Intent(); 
    i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS); 
    startActivity(i); 
} 
} 

進捗のダウンロード率を与える任意の方法はありますか?

+0

ご存知ですか?これに対する明確な解決策はありません –

答えて

17

queryメソッドを使用して、これまでにダウンロードしたバイト数とダウンロードする必要があるバイト数を照会することができます。これは、サンプルコードのステータスを照会したのとほとんど同じです。これらの値を取得したら、進行状況をパーセンテージとして計算するのはかなり簡単です。

新しいデータが受信されたときに通知を受ける方法はないようですので、一定の間隔でダウンロードマネージャーをポーリングして、監視したい

Query query = new Query(); 
query.setfilterById(downloadId); 

Cursor c = dm.query(query); 
if (c.moveToFirst()) { 
    int sizeIndex = c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES); 
    int downloadedIndex = c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); 
    long size = c.getInt(sizeIndex); 
    long downloaded = c.getInt(downloadedIndex); 
    double progress = 0.0; 
    if (size != -1) progress = downloaded*100.0/size; 
    // At this point you have the progress as a percentage. 
} 

合計サイズは最初は-1になり、ダウンロードが開始されると一度だけ埋められます。上記のサンプルコードでは、-1をチェックし、サイズがまだ設定されていない場合は0に進捗を設定しています。

しかし、場合によっては、合計サイズが返されないことがあります(たとえば、HTTPチャンク転送では、サイズを判別できるContent-Lengthヘッダーはありません)。そのような種類のサーバーをサポートする必要がある場合は、ダウンロードが進行中であり、進捗バーがゼロに止まっているだけでなく、何らかの表示をユーザーに提供する必要があります。あなたは進行状況の更新のためのDownloadManagerを照会するかを決定するためにまともな方法を探している場合は、URI content://downloads/my_downloads

例えばContentObserverの登録を検討

+0

ゼロの値をチェックするべきではありませんか?ダウンロードしたようなもの* 100.0 /(サイズ== 0?1:サイズ) – Fabiano

18

DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); 
manager.enqueue(myRequest); 

Uri myDownloads = Uri.parse("content://downloads/my_downloads"); 
getContentResolver().registerContentObserver(myDownloads, true, new DownloadObserver()); 

... 

public static class DownloadObserver extends ContentObserver { 
    @Override 
    public void onChange(boolean selfChange, Uri uri) { 
     Log.d("DownloadObserver", "Download " + uri + " updated"); 
    } 

これは、次のような出力が得られ長期実行ダウンロードの各チャンクが受信される

D/DownloadObserver(15584): Download content://downloads/my_downloads/437 updated 
D/DownloadObserver(15584): Download content://downloads/my_downloads/437 updated 
D/DownloadObserver(15584): Download content://downloads/my_downloads/437 updated 
D/DownloadObserver(15584): Download content://downloads/my_downloads/437 updated 

ここで、 '437'あなたのダウンロードのIDです。

これはフレームワークで非表示に見えるクラスandroid.provider.Downloadsで定義されたコンテンツURIに従い、すべてのデバイスで一貫して動作しないことに注意してください。 (https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/provider/Downloads.java#89

0

私は複数のファイルのダウンロードを追跡する必要がありました。思考と実験の多くの後、私は次のコードを思い付いた:

private void startDownloadThread(final List<DownloadFile> list) { 

     // Initializing the broadcast receiver ... 
     mBroadCastReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       mFinishedFilesFromNotif.add(intent.getExtras() 
         .getLong(DownloadManager.EXTRA_DOWNLOAD_ID)); 
      } 
     }; 

     IntentFilter intentFilter = new IntentFilter(
       "android.intent.action.DOWNLOAD_COMPLETE"); 
     DownloadProgressUIFragment.this.getActivity().registerReceiver(mBroadCastReceiver, 
       intentFilter); 

     // initializing the download manager instance .... 
     mDownloadManager = (DownloadManager) getActivity() 
       .getSystemService(Context.DOWNLOAD_SERVICE); 

     // adding files to the download manager list ... 
     for(DownloadFile f: list) { 
      mDownloadIds.add(FileUtils.addFileForDownloadInBkg(getApplicationContext(), 
        f.getUrl(), 
        f.getPath())); 
     } 

     // starting the thread to track the progress of the download .. 
     mProgressThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 

       // Preparing the query for the download manager ... 
       DownloadManager.Query q = new DownloadManager.Query(); 
       long[] ids = new long[mDownloadIds.size()]; 
       final List<Long> idsArrList= new ArrayList<>(); 
       int i = 0; 
       for (Long id: mDownloadIds) { 
        ids[i++] = id; 
        idsArrList.add(id); 
       } 
       q.setFilterById(ids); 

       // getting the total size of the data ... 
       Cursor c; 

       while(true) { 

        // check if the downloads are already completed ... 
        // Here I have created a set of download ids from download manager to keep 
        // track of all the files that are dowloaded, which I populate by creating 
        // 
        if(mFinishedFilesFromNotif.containsAll(idsArrList)) { 
         isDownloadSuccess = true; 

         // TODO - Take appropriate action. Download is finished successfully 
         return; 
        } 

        // start iterating and noting progress .. 
        c = mDownloadManager.query(q); 
        if(c != null) { 
         int filesDownloaded = 0; 
         float fileFracs = 0f; // this stores the fraction of all the files in 
         // download 
         final int columnTotalSize = c.getColumnIndex 
           (DownloadManager.COLUMN_TOTAL_SIZE_BYTES); 
         final int columnStatus = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 
         //final int columnId = c.getColumnIndex(DownloadManager.COLUMN_ID); 
         final int columnDwnldSoFar = 
           c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR); 

         while (c.moveToNext()) { 
          // checking the progress .. 
          if(c.getInt(columnStatus) == DownloadManager.STATUS_SUCCESSFUL) { 
           filesDownloaded++; 
          } 
          // If the file is partially downloaded, take its fraction .. 
          else if(c.getInt(columnTotalSize) > 0) { 
           fileFracs += ((c.getInt(columnDwnldSoFar) * 1.0f)/
             c.getInt(columnTotalSize)); 
          } else if(c.getInt(columnStatus) == DownloadManager.STATUS_FAILED) { 
           // TODO - Take appropriate action. Error in downloading one of the 
           // files. 
           return; 
          } 
         } 

         c.close(); 

         // calculate the progress to show ... 
         float progress = (filesDownloaded + fileFracs)/ids.length; 

         // setting the progress text and bar... 
         final int percentage = Math.round(progress * 100.0f); 
         final String txt = "Loading ... " + percentage + "%"; 

         // Show the progress appropriately ... 
        } 
       } 
      } 
     }); 

     mProgressThread.start(); 
    } 

やファイルにエンキューする機能は以下のとおりです。

public static long addFileForDownloadInBkg(Context context, String url, String savePath) { 
     Uri uri = Uri.parse(url); 
     DownloadManager.Request request = new DownloadManager.Request(uri); 
     request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); 
     request.setDestinationUri(Uri.fromFile(new File(savePath))); 

     final DownloadManager m = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); 
     return m.enqueue(request); 
    } 

は基本的に、私はそれぞれに個別に通知を受け取りますダウンロードが終了したファイルをダウンロードし、基本的にセットに追加して、すべてのダウンロードが完了したかどうかを判断するのに役立ちます。私はファイルの数と完了したそれぞれの割合に基づいて進捗状況を追跡します。私はこれが役立つことを願っています

関連する問題