完整實現
public class DownloadActivity extends Activity {
private DownloadManager downloadManager;
private long downloadId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download);
downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
// 註冊下載完成廣播
registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
public void startDownload(View view) {
String url = "https://example.com/file.apk";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
.setTitle("文件下載")
.setDescription("正在下載...")
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "file.apk")
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false);
downloadId = downloadManager.enqueue(request);
}
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (id == downloadId) {
Toast.makeText(context, "下載完成", Toast.LENGTH_SHORT).show();
// 可選:打開文件
openDownloadedFile(id);
}
}
};
private void openDownloadedFile(long id) {
DownloadManager.Query query = new DownloadManager.Query().setFilterById(id);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
String uriString = cursor.getString(columnIndex);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(uriString), "application/vnd.android.package-archive"); // apk
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
cursor.close();
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(onDownloadComplete);
}
}
Manifest 權限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Android 9 及以下 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
優勢
- **系統級下載**:斷點續傳、網絡切換自動恢復、通知欄進度、電源管理優化。
- **無需自己寫線程、HTTP、文件流**。
- 下載完成自動掃描 MediaStore,畫廊/文件管理器可見。
注意
- Android 10+ 目標目錄建議用 `setDestinationInExternalFilesDir` (私有目錄) 或 `MediaStore` 插入 (公共目錄)。
- 大文件下載建議設置 `setRequiresCharging(false)`、`setRequiredNetworkType` 等策略。