探究在APP中使用DownloadManager完成下载
来源:互联网 发布:淘宝旺铺全屏代码 编辑:程序博客网 时间:2024/05/17 07:57
所谓探究,这里进行逐层深入,想看最终结果的同学,请直接翻看最后部分。这里少量的注释,就在代码中进行添加了.
before add some permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"></uses-permission>
1.使用DownloadManager下载一张简单图片
package com.hang.downloadmanagerdemo;import android.app.DownloadManager;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.ParcelFileDescriptor;import android.support.v7.app.AppCompatActivity;import android.widget.ImageView;import java.io.File;public class MainActivity extends AppCompatActivity { public static final String URL_MUSIC = "http://vfile.dingdongfm.com/2015/1450/2617/4979/145026174979.ssm/145026174979.mp3"; public static final String URL_IMAGE = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3741636297,2352266532&fm=116&gp=0.jpg"; private long myDownloadReference; private DownloadManager downloadManager; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); imageView = new ImageView(this); setContentView(imageView); //1.create downloadManager&&Request add request to downloadManager String serviceNameInString = Context.DOWNLOAD_SERVICE; downloadManager = (DownloadManager) getSystemService(serviceNameInString); Uri uri = Uri.parse(URL_IMAGE); DownloadManager.Request request = new DownloadManager.Request(uri); File destFile = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), "test.mp3"); if (destFile.exists()) { destFile.delete(); } request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath())); //be care if you want to add below code,you must add DOWNLOAD_WITHOUT_NOTIFICATION permission request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); myDownloadReference = downloadManager.enqueue(request); } @Override protected void onResume() { super.onResume(); //2.register receiver detect download finish IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(broadcastReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long downloadCompleteReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); if (myDownloadReference == downloadCompleteReference) { //3.download over ,and show image try { ParcelFileDescriptor parcelFileDescriptor = downloadManager.openDownloadedFile(myDownloadReference); Bitmap bitmap = BitmapFactory.decodeFileDescriptor(parcelFileDescriptor.getFileDescriptor()); imageView.setImageBitmap(bitmap); System.out.println(); } catch (Exception e) { e.printStackTrace(); } } } };}
2.下载大文件并更新下载进度
package com.hang.downloadmanagerdemo;import android.app.DownloadManager;import android.app.ProgressDialog;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.os.ParcelFileDescriptor;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.widget.Toast;import java.io.File;public class MainActivity extends AppCompatActivity { public static final String TAG = "xxxx"; public static final String URL_MUSIC = "http://vfile.dingdongfm.com/2016/1473/4999/6792/147349996792.ssm/147349996792.mp3"; private long myDownloadReference; private DownloadManager downloadManager; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String serviceNameInString = Context.DOWNLOAD_SERVICE; downloadManager = (DownloadManager) getSystemService(serviceNameInString); Uri uri = Uri.parse(URL_MUSIC); DownloadManager.Request request = new DownloadManager.Request(uri); File destFile = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), "test.mp3"); if (destFile.exists()) { destFile.delete(); } request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath())); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); myDownloadReference = downloadManager.enqueue(request); //1.add listener to downloaded progress getContentResolver().registerContentObserver(Uri.parse("content://downloads/"), true, new DownloadObserver(handler, MainActivity.this, myDownloadReference)); //2.use progressDialog&& handler to show download progress progressDialog = new ProgressDialog(this); progressDialog.setProgress(0); progressDialog.setIndeterminate(false); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.show(); } @Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(broadcastReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long downloadCompleteReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); //3.play audio if (myDownloadReference == downloadCompleteReference) { try { ParcelFileDescriptor parcelFileDescriptor = downloadManager.openDownloadedFile(myDownloadReference); MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(parcelFileDescriptor.getFileDescriptor()); mediaPlayer.prepare(); mediaPlayer.start(); System.out.println(); } catch (Exception e) { e.printStackTrace(); } } } }; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (progressDialog != null && msg.what > 0) { progressDialog.setProgress(msg.what); Log.d(TAG, "" + msg.what); } if (msg.what == 100) { progressDialog.dismiss(); Toast.makeText(MainActivity.this, "download finished~", Toast.LENGTH_LONG).show(); } } };}
3.处理Pause/Resume
搜索了一番,没有找到DownloadManager的Pause/Resume方法,找到的一个折中的办法是,通过
public void cancelDownload() { if (downloadManager != null && myDownloadReference > 0) { downloadManager.remove(myDownloadReference); myDownloadReference = 0; } }
将要下载的任务从下载管理器中删除。
通过
myDownloadReference = downloadManager.enqueue(request);
将下载任务“再次”添加到下载管理器。
这里一定要注意以下:重复enqueue而没有调用相应的remove方法,会造成文件的重复下载!
package com.hang.downloadmanagerdemo;import android.app.DownloadManager;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.os.ParcelFileDescriptor;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.LinearLayout;import android.widget.Toast;import com.hang.androidtestdemo.R;import java.io.File;public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = "xxxx"; public static final String URL_MUSIC = "http://vfile.dingdongfm.com/2016/1473/4999/6792/147349996792.ssm/147349996792.mp3"; private DownloadManager downloadManager; private long myDownloadReference; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); LinearLayout totalLayout = (LinearLayout) findViewById(R.id.ll); for (int j = 0; j < totalLayout.getChildCount(); j++) { View view = totalLayout.getChildAt(j); view.setOnClickListener(this); } } public void cancelDownload() { if (downloadManager != null && myDownloadReference > 0) { downloadManager.remove(myDownloadReference); myDownloadReference = 0; } } public void startDownload() { String serviceNameInString = Context.DOWNLOAD_SERVICE; downloadManager = (DownloadManager) getSystemService(serviceNameInString); Uri uri = Uri.parse(URL_MUSIC); DownloadManager.Request request = new DownloadManager.Request(uri); File destFile = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), "test.mp3"); if (destFile.exists()) { destFile.delete(); } request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath()));// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); myDownloadReference = downloadManager.enqueue(request); //1.add listener to downloaded progress getContentResolver().registerContentObserver(Uri.parse("content://downloads/"), true, new DownloadObserver(handler, MainActivity.this, myDownloadReference)); }//be carefult not to download repeatly @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_start: { if (myDownloadReference == 0) { startDownload(); } else { Toast.makeText(MainActivity.this, "already added to downloading queue", Toast.LENGTH_LONG).show(); } break; } case R.id.btn_cancel: { if (myDownloadReference > 0) { cancelDownload(); } break; } } } @Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(broadcastReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long downloadCompleteReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); //3.play audio if (myDownloadReference > 0 && myDownloadReference == downloadCompleteReference) { try { ParcelFileDescriptor parcelFileDescriptor = downloadManager.openDownloadedFile(myDownloadReference); MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setDataSource(parcelFileDescriptor.getFileDescriptor()); mediaPlayer.prepare(); mediaPlayer.start(); System.out.println(); } catch (Exception e) { e.printStackTrace(); } } } }; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Log.d(TAG, "" + msg.what); } };}
4.列表下载
为了方便管理,这里定义一个DownloadBean
package com.hang.downloadmanagerdemo;public class DownloadBean { private String name; private double downloadProgress; private long downloadReference; private String downloadUrl; @Override public boolean equals(Object obj) { boolean isEqual = false; if (obj != null && obj instanceof DownloadBean) { isEqual = (this.downloadReference == ((DownloadBean) obj).downloadReference); } return isEqual; } public DownloadBean(String name, String downloadUrl) { this.name = name; this.downloadUrl = downloadUrl; this.downloadProgress = 0; this.downloadReference = 0; } //TODO getter and setter}
定义Adapter展示下载列表:
为了简化处理,这里使用了ListView的多选模式
package com.hang.downloadmanagerdemo;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import com.hang.androidtestdemo.R;import java.text.DecimalFormat;import java.util.List;public class DownloadAdapter extends BaseAdapter { private List<DownloadBean> beanList; private Context mContext; private ListView listView; DecimalFormat df2 = new DecimalFormat("00.0%"); public DownloadAdapter(Context context, ListView listView) { this.mContext = context; this.listView = listView; } public void setData(List<DownloadBean> beanList) { this.beanList = beanList; notifyDataSetChanged(); } public List<DownloadBean> getData() { return this.beanList; } @Override public int getCount() { return (beanList == null) ? 0 : beanList.size(); } @Override public DownloadBean getItem(int position) { DownloadBean bean = beanList.get(position); return bean; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = null; if (convertView == null) { viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_download, parent, false); viewHolder.checkView = (ImageView) convertView.findViewById(R.id.iv_check); viewHolder.nameView = (TextView) convertView.findViewById(R.id.tv_name); viewHolder.progressView = (TextView) convertView.findViewById(R.id.tv_progress); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } if (listView.isItemChecked(position)) { viewHolder.checkView.setImageResource(R.drawable.download_chosed); } else { viewHolder.checkView.setImageResource(R.drawable.download_unchosed); } DownloadBean item = getItem(position); viewHolder.nameView.setText(item.getName()); viewHolder.progressView.setText("" + df2.format(item.getDownloadProgress())); return convertView; } class ViewHolder { ImageView checkView; TextView nameView; TextView progressView; }}
cell布局文件
<?xml version="1.0" encoding="utf-8"?><!--item_download.xml--><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="64dp" android:gravity="center_vertical" android:paddingLeft="@dimen/distance_16dp" android:paddingRight="@dimen/distance_16dp" android:textColor="@android:color/black" android:textSize="14sp"> <ImageView android:id="@+id/iv_check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:src="@drawable/download_unchosed" /> <TextView android:id="@+id/tv_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="0%" /> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_toLeftOf="@id/tv_progress" android:layout_toRightOf="@id/iv_check" android:gravity="center_vertical" /></RelativeLayout>
最后的Java代码
package com.hang.downloadmanagerdemo;import android.app.DownloadManager;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.util.SparseBooleanArray;import android.view.View;import android.widget.AdapterView;import android.widget.Button;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.Toast;import com.hang.androidtestdemo.R;import java.io.File;import java.util.Arrays;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener { public static final String TAG = "xxxx"; public static final String URL_MUSIC_0 = "http://vfile.dingdongfm.com/2016/1473/4999/6792/147349996792.ssm/147349996792.mp3"; public static final String URL_MUSIC_1 = "http://vfile.dingdongfm.com/2016/1472/6907/0485/147269070485.ssm/147269070485.mp3"; public static final String URL_MUSIC_2 = "http://vfile.dingdongfm.com/2016/1470/3842/4921/147038424921.ssm/147038424921.mp3"; public static final String URL_MUSIC_3 = "http://vfile.dingdongfm.com/2015/1450/2643/2692/145026432692.ssm/145026432692.mp3"; private DownloadAdapter mAdapter; private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); RelativeLayout outLayout = new RelativeLayout(this); setContentView(outLayout); listView = new ListView(this); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setOnItemClickListener(this); outLayout.addView(listView); Button button = new Button(this); button.setId(R.id.btn); button.setText("Download"); outLayout.addView(button); RelativeLayout.LayoutParams buttonParams = (RelativeLayout.LayoutParams) button.getLayoutParams(); buttonParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, R.id.btn); button.setOnClickListener(this); mAdapter = new DownloadAdapter(this, listView); listView.setAdapter(mAdapter); List<DownloadBean> downloadList = Arrays.asList(new DownloadBean("audio 0", URL_MUSIC_0), new DownloadBean("audio 1", URL_MUSIC_1), new DownloadBean("audio 2", URL_MUSIC_2), new DownloadBean("audio 3", URL_MUSIC_3)); mAdapter.setData(downloadList); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn: { SparseBooleanArray booleanArray = listView.getCheckedItemPositions(); for (int j = 0; j < booleanArray.size(); j++) { int key = booleanArray.keyAt(j); if (booleanArray.get(key)) { startDownload(mAdapter.getItem(key), MainActivity.this); Log.d(TAG, "" + key + ": true"); } else { Log.d(TAG, "" + key + ": false"); } } break; } } } public void startDownload(DownloadBean downloadBean, Context mContext) { String serviceNameInString = Context.DOWNLOAD_SERVICE; DownloadManager downloadManager = (DownloadManager) mContext.getSystemService(serviceNameInString); Uri uri = Uri.parse(downloadBean.getDownloadUrl()); DownloadManager.Request request = new DownloadManager.Request(uri); File destFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC), downloadBean.getName()); if (destFile.exists()) { destFile.delete(); } request.setDestinationUri(Uri.parse("file://" + destFile.getAbsolutePath()));// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); long myDownloadReference = downloadManager.enqueue(request); //1.add listener to downloaded progress mContext.getContentResolver().registerContentObserver(Uri.parse("content://downloads/"), true, new DownloadObserver(handler, mContext, myDownloadReference)); downloadBean.setDownloadReference(myDownloadReference); } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { mAdapter.notifyDataSetChanged(); } @Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE); registerReceiver(broadcastReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { long downloadCompleteReference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); List<DownloadBean> beanList = mAdapter.getData(); if (beanList != null) { for (int j = 0; j < beanList.size(); j++) { DownloadBean bean = beanList.get(j); if (bean.getDownloadReference() == downloadCompleteReference) { Toast.makeText(MainActivity.this, bean.getName() + " finish download~", Toast.LENGTH_SHORT).show(); } } } } }; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { //be careful total size may be -1 if (msg.arg2 > 0) { List<DownloadBean> beanList = mAdapter.getData(); for (int j = 0; j < beanList.size(); j++) { DownloadBean bean = beanList.get(j); if (bean.getDownloadReference() == (Long) msg.obj) { bean.setDownloadProgress(msg.arg1 * 1.0 / msg.arg2); mAdapter.notifyDataSetChanged(); break; } } } } };}
这里对DownloadObserver也进行了修改
package com.hang.downloadmanagerdemo;import android.app.DownloadManager;import android.content.Context;import android.database.ContentObserver;import android.database.Cursor;import android.os.Handler;import android.os.Message;import android.util.Log;public class DownloadObserver extends ContentObserver { private long downid; private Handler handler; private Context context; public DownloadObserver(Handler handler, Context context, long downid) { super(handler); this.handler = handler; this.downid = downid; this.context = context; } @Override public void onChange(boolean selfChange) { //每当/data/data/com.android.providers.download/database/database.db变化后,触发onCHANGE,开始具体查询 Log.w("onChangeID", String.valueOf(downid)); super.onChange(selfChange); //实例化查询类,这里需要一个刚刚的downid DownloadManager.Query query = new DownloadManager.Query().setFilterById(downid); DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Cursor cursor = downloadManager.query(query); while (cursor.moveToNext()) { int mDownload_so_far = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int mDownload_all = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));// int mProgress = (int) (mDownload_so_far * 1.0 / mDownload_all);// Log.w(getClass().getSimpleName(), String.valueOf(mProgress)); Message message = Message.obtain(); message.arg1 = mDownload_so_far; message.arg2 = mDownload_all; message.obj = downid; handler.sendMessage(message); } }}
0 0
- 探究在APP中使用DownloadManager完成下载
- 在Android Manifest中注册DownloadManager下载完成发送的广播
- Android中使用DownloadManager进行下载操作
- 使用DownloadManager下载
- 使用Downloadmanager进行下载
- Android使用Downloadmanager进行下载时,鉴别取消下载和下载完成的广播
- Android DownloadManager 下载完成并安装
- Android中使用DownloadManager类来管理数据下载
- Android中使用DownloadManager下载并安装apk
- WebView中实现下载DownloadManager
- 使用DownloadManager进行文件下载
- 使用DownloadManager实现下载功能
- [Android开发] 使用DownloadManager下载
- 文件下载之使用DownloadManager
- 使用DownloadManager实现文件下载
- 使用DownloadManager实现下载更新
- Android使用DownloadManager下载文件
- DownloadManager实现下载、安装更新app功能
- 非插件,css + jquery 实现tab页效果
- 随笔小记
- uniq
- React-Native-源码分析
- FLV封装格式分析器
- 探究在APP中使用DownloadManager完成下载
- POJ2479 DP
- Android中各种形状
- 设计模式之迭代器模式
- hdu 3555 Bomb(数位DP)
- Hibernate对Oracle中 Clob的使用
- Python日期和时间函数
- 广告轮播图
- React-Native-源码分析二-JSX如何渲染成原生页面(上)