前言
DownloadManager是Android系統自帶的下載管理工具,此工具可以很好的調度好下載。在沒有特殊需求的情況下,一般是推薦使用此工具下載的。另外這個工具下載還有有優勢就是可以在下載app完成后直接跳轉到安裝頁面。
參考:https://www.jianshu.com/p/e0496200769c
需要的權限
需要網絡權限和文件讀寫權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>
創建下載請求
private void down(){ DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse("https://dl.hdslb.com/mobile/latest/iBiliPlayer-html5_app_bili.apk"));//添加下載文件的網絡路徑 request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "iBiliPlayer-html5_app_bili.apk");//添加保存文件路徑與名稱 request.setTitle("測試下載");//添加在通知欄里顯示的標題 request.setDescription("下載中");//添加在通知欄里顯示的描述 request.addRequestHeader("token","11");//如果你的下載需要token,或者有秘鑰要求,可以在此處添加header的 key: value request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);//設置下載的網絡類型 request.setVisibleInDownloadsUi(false);//是否顯示下載 從Android Q開始會被忽略 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);//下載中與下載完成后都會在通知中顯示| 另外可以選 DownloadManager.Request.VISIBILITY_VISIBLE 僅在下載中時顯示在通知中,完成后會自動隱藏 long id = downloadManager.enqueue(request);//加入隊列,會返回一個唯一下載id }
加入列隊后,下載就進行了。我們可以在下拉通知欄里看到正在下載的文件。
另外注意 setDestinationInExternalPublicDir方法已經包含根目錄路徑了,所以直接傳入DIRECTORY_DOWNLOADS就可以了,千萬不要在導入一個 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() 這樣他會自動在創建多層目錄
查詢即將保存的下載文件路徑與文件名稱
private void queryFileName(long id){ DownloadManager downloadManager = (DownloadManager) MainActivity.this.getApplication().getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(id); Cursor cursor = downloadManager.query(query); if (cursor.moveToFirst()) { String file = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI)); Log.e("調試_臨時_log", "this_" + file); } }
監聽下載狀態
AppDownReceiver appDownReceiver = new AppDownReceiver(); registerReceiver(appDownReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
廣播部分代碼
public class DownloadReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (!TextUtils.equals(action, DownloadManager.ACTION_DOWNLOAD_COMPLETE)){ return; } long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (downloadId == -1){ return; } DownloadManager downloadManager = (DownloadManager) context.getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE); int status = getDownloadStatus(downloadManager, downloadId); if (status != DownloadManager.STATUS_SUCCESSFUL){ //下載狀態不等於成功就跳出 return; } Uri uri = downloadManager.getUriForDownloadedFile(downloadId);//獲取下載完成文件uri if (uri == null){ return; } } /** * 獲取下載狀態 * @param downloadManager * @param downloadId * @return */ private int getDownloadStatus(DownloadManager downloadManager, long downloadId) { DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor c = downloadManager.query(query); if (c != null) { try { if (c.moveToFirst()) { return c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)); } } finally { c.close(); } } return -1; } }
下載狀態查詢
/** * 獲取下載狀態 * * @param downloadId an ID for the download, unique across the system. * This ID is used to make future calls related to this download. * @return int * @see DownloadManager#STATUS_PENDING 下載等待開始時 * @see DownloadManager#STATUS_PAUSED 下載暫停 * @see DownloadManager#STATUS_RUNNING 正在下載中 * @see DownloadManager#STATUS_SUCCESSFUL 下載成功 * @see DownloadManager#STATUS_FAILED 下載失敗 */ public int getDownloadStatus(long downloadId) { DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor c = downloadManager.query(query); if (c != null) { try { if (c.moveToFirst()) { return c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)); } } finally { c.close(); } } return -1; }
下載進度查詢
/** * 獲取當前下載進度 * * @return */ private int getDownloadProgress() { DownloadManager.Query query = new DownloadManager.Query().setFilterById(mDownloadId); Cursor c = mDownloadManager.query(query); if (c != null) { try { if (c.moveToFirst()) { return c.getInt(c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); } } finally { c.close(); } } return -1; } /** * 獲取下載總大小 * * @return */ private int getDownloadTotal() { DownloadManager.Query query = new DownloadManager.Query().setFilterById(mDownloadId); Cursor c = mDownloadManager.query(query); if (c != null) { try { if (c.moveToFirst()) { return c.getInt(c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); } } finally { c.close(); } } return -1; }
安裝下載完成的App
/** * 安裝apk */ private void installApk(long id) { Uri uri = mDownloadManager.getUriForDownloadedFile(id); Intent install = new Intent(Intent.ACTION_VIEW); install.setDataAndType(uri, "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION); getApplication().startActivity(install); }
END