原文鏈接
https://blog.stylingandroid.com/downloadmanager-part-1/
安卓開發入門之系統下載管理工具DownloadManager-第一部分
http://blog.csdn.net/zhangxiangliang2/article/details/73691449
安卓開發入門之系統下載管理工具DownloadManager-第二部分
http://blog.csdn.net/zhangxiangliang2/article/details/73693134
安卓開發入門之系統下載管理工具DownloadManager-第三部分
http://blog.csdn.net/zhangxiangliang2/article/details/73695167
安卓開發中的一個普遍需求是從網絡下載文件到設備,此係列三部分研究DownloadManager類是如何以一種極其簡單的方式解決該需求的。
首先,我們要知道DownloadManager類起始於API9,儘管該API有少許毛病,但是其已經很穩定了。
讓我們開始吧騷年!
新建工程,在Activity裏面添加我們下載按鈕,點擊後下載一個PDF文件到本地並打開。
DownloadManager的主要邏輯在Downloader對象中實現,並且在文件下載完成後回調FileDownloaded()方法。同時,要在Activity銷燬的時候調用
UnRegistered()方法。這就是所有要注意的事項。下面是代碼:
public class MainActivity extends AppCompatActivity implements Downloader.Listener {
private static final String URI_STRING = "http://www.cbu.edu.zm/downloads/pdf-sample.pdf";
private Button download;
private Downloader downloader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
download = (Button) findViewById(R.id.download);
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
downloadOrCancel();
}
});
downloader = Downloader.newInstance(this);
}
void downloadOrCancel() {
if (downloader.isDownloading()) {
cancel();
} else {
download();
}
updateUi();
}
private void cancel() {
downloader.cancel();
}
private void download() {
Uri uri = Uri.parse(URI_STRING);
downloader.download(uri);
}
@Override
public void fileDownloaded(Uri uri, String mimeType) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mimeType);
startActivity(intent);
updateUi();
}
@Override
public Context getContext() {
return getApplicationContext();
}
private void updateUi() {
if (downloader.isDownloading()) {
download.setText(R.string.cancel);
} else {
download.setText(R.string.download);
}
}
@Override
protected void onDestroy() {
downloader.unregister();//這麼做是因爲我們無法保證用戶退出app的時候已經下載完成,
//除此之外,退出app後還可以繼續下載,這樣就不用創建後臺service來下載了
super.onDestroy();
}
}
運行結果:
源碼下載
https://github.com/StylingAndroid/DownloadManager/tree/Part1
原文鏈接
https://blog.stylingandroid.com/downloadmanager-part-1/
怎麼樣?是不是簡單易用?
如果你滿足於此,下面的內容你可以不用看了。
DownloadManager類究竟做了什麼來實現如此神奇的效果呢?
讓我們潛入Downloader類的源碼,附有詳細的註釋。
class Downloader implements DownloadReceiver.Listener {
private final Listener listener;
private final DownloadManager downloadManager;
private DownloadReceiver receiver = null;
private long downloadId = -1;
static Downloader newInstance(Listener listener) {
Context context = listener.getContext();
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);//獲取DownloadManager實例
return new Downloader(downloadManager, listener);
}
Downloader(DownloadManager downloadManager, Listener listener) {
this.downloadManager = downloadManager;
this.listener = listener;
}
void download(Uri uri) {
if (!isDownloading()) {
register();//首先註冊BroadcastReceiver用來通知下載完成
DownloadManager.Request request = new DownloadManager.Request(uri);//通過傳參uri獲取DownloadManager.Request
downloadId = downloadManager.enqueue(request);//通過enqueue將該request放入隊列,並且獲取下載請求的唯一ID
}
}
boolean isDownloading() {
return downloadId >= 0;
}
void register() {
if (receiver == null && isDownloading()) {
receiver = new DownloadReceiver(this);
receiver.register(listener.getContext());
}
}
@Override
public void downloadComplete(long completedDownloadId) {//下載完成後調用此方法
if (downloadId == completedDownloadId) {//首先檢查ID是否我們的下載ID,如果是,再通過下面代碼拿到結果,下面代碼同樣適用於多個併發下載
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
downloadId = -1;
unregister();
Cursor cursor = downloadManager.query(query);
while (cursor.moveToNext()) {
getFileInfo(cursor);
}
cursor.close();
}
}
void unregister() {
if (receiver != null) {
receiver.unregister(listener.getContext());//反註冊BroadcastReceiver
}
receiver = null;
}
private void getFileInfo(Cursor cursor) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL) {//通過檢查status屬性來判斷是否下載成功,當然還有其他屬性供我們自定義,
Long id = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID));
Uri uri = downloadManager.getUriForDownloadedFile(id);//獲取uri
String mimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));//獲取MIME類型
listener.fileDownloaded(uri, mimeType);
}
}
void cancel() {
if (isDownloading()) {
downloadManager.remove(downloadId);//通過downloadId來取消下載
downloadId = -1;
unregister();
}
}
interface Listener {
void fileDownloaded(Uri uri, String mimeType);
Context getContext();
}
}
再看看BroadcastReceiver,看代碼註釋
class DownloadReceiver extends BroadcastReceiver {
private final Listener listener;
DownloadReceiver(Listener listener) {
this.listener = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
listener.downloadComplete(downloadId);
}
public void register(Context context) {
IntentFilter downloadFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);//註冊類型DownloadManager.ACTION_DOWNLOAD_COMPLETE
//我們將能獲取下載成功事件,我們還可以註冊其他事件,比如說用戶點擊下載通知後跳轉到我們的app頁面
context.registerReceiver(this, downloadFilter); }
public void unregister(Context context)
{ context.unregisterReceiver(this); }
interface Listener { void downloadComplete(long downloadId); }}
下一篇文章中,我們將進一步探索DownloadManager類,並且見識到許多很有用的方法,期待吧。。。
原文鏈接
https://blog.stylingandroid.com/downloadmanager-part-1/
安卓開發入門之系統下載管理工具DownloadManager-第一部分
http://blog.csdn.net/zhangxiangliang2/article/details/73691449
安卓開發入門之系統下載管理工具DownloadManager-第二部分
http://blog.csdn.net/zhangxiangliang2/article/details/73693134
安卓開發入門之系統下載管理工具DownloadManager-第三部分
http://blog.csdn.net/zhangxiangliang2/article/details/73695167