系统自带DownloadManager详解

    xiaoxiao2021-03-25  227

    原创:http://blog.csdn.net/u012209506/article/details/56012744

    前言:

    还在自己写DownloadUtils吗?有了DownloadManger.你只需将UI画好,其他的事情,交给他来做就好了。

    简介:

    DownloadManager是android2.3以后,系统下载的方法,是处理长期运行的HTTP下载的系统服务。客户端可以请求的URI被下载到一个特定的目标文件。客户端将会在后台与http交互进行下载,或者在下载失败,或者连接改变,重新启动系统后重新下载。还可以进入系统的下载管理界面查看进度。DownloadManger有两个内部类,Request 和Query。Request类可设置下载的一些属性。Query类可查询当前下载的进度,下载地址,文件存放目录等数据。

    DownloadManager

    1、所需权限

    <uses-permission android:name="android.permission.INTERNET" />; <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>; 123 123

    2、获得对象,开始下载

    DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl)); long id = downloadManager.enqueue(request); //每下载的一个文件对应一个id,通过此id可以查询数据。 1234 1234

    Request类

    1.指定下载位置,及文件名称

    /** * 方法1: * 目录: Android -> data -> com.app -> files -> Download -> dxtj.apk * 这个文件是你的应用所专用的,软件卸载后,下载的文件将随着卸载全部被删除 */ request.setDestinationInExternalFilesDir( this , Environment.DIRECTORY_DOWNLOADS , "dxtj.apk" ); /** * 方法2: * 下载的文件存放地址 SD卡 download文件夹,dxtj.apk * 软件卸载后,下载的文件会保留 */ //在SD卡上创建一个文件夹 request.setDestinationInExternalPublicDir( "/epmyg/" , "dxtj.apk" ) ; /** * 方法3: * 如果下载的文件希望被其他的应用共享 * 特别是那些你下载下来希望被Media Scanner扫描到的文件(比如音乐文件) */ request.setDestinationInExternalPublicDir( Environment.DIRECTORY_MUSIC, "告白气球.mp3" ); /** * 方法4 * 文件将存放在外部存储的确实download文件内,如果无此文件夹,创建之,如果有,下面将返回false。 * 系统有个下载文件夹,比如小米手机系统下载文件夹 SD卡--> Download文件夹 */ //创建目录 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdir() ; //设置文件存放路径 request.setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS , "dxtj.apk" ) ; } 12345678910111213141516171819202122232425262728293031323334 12345678910111213141516171819202122232425262728293031323334

    2、指定下载的网络类型

    //指定在WIFI状态下,执行下载操作。 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); //指定在MOBILE状态下,执行下载操作 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE); //是否允许漫游状态下,执行下载操作 request.setAllowedOverRoaming(boolean); //是否允许“计量式的网络连接”执行下载操作 request.setAllowedOverMetered(boolean); //默认是允许的。 12345678 12345678

    3、定制Notification样式

    //设置Notification的标题和描述 request.setTitle("标题"); request.setDescription("描述"); //设置Notification的显示,和隐藏。 request.setNotificationVisibility(visibility); 12345 12345 VISIBILTY_HIDDEN: Notification:将不会显示,如果设置该属性的话,必须要添加权限  Android .permission.DOWNLOAD_WITHOUT_NOTIFICATION.  VISIBILITY_VISIBLE: Notification显示,但是只是在下载任务执行的过程中显示,下载完成自动消失。(默认值)  VISIBILITY_VISIBLE_NOTIFY_COMPLETED : Notification显示,下载进行时,和完成之后都会显示。  VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION :只有当任务完成时,Notification才会显示。  对Notification的设定方法相对较少。

    4、设置下载文件类型:

    request.setMimeType("application/vnd.android.package-archive"); 1 1

    这是安卓.apk文件的类型。有些机型必须设置此方法,才能在下载完成后,点击通知栏的Notification时,才能正确的打开安装界面。不然会弹出一个Toast(can not open file).其他文件类型的MimeType ,自行百度吧 。

    5、添加请求下载的网络链接的http头,比如User-Agent,gzip压缩等:

    request.addRequestHeader(String header, String value); 12 12

    Query 类

    我们的需求,可能不只是在Notification 中显示进度就好了,也许,在app中也需要获取实时下载进度。所以Query类就是提供查询的一些方法。  但API中就只有两个方法,原来,他把数据保存在数据库中去了。我们需要获得一个Cursor 结果集,通过结果集获得我们想要的数据。

    DownloadManager.Query query = new DownloadManager.Query(); Cursor cursor = downloadManager.query(query.setFilterById(id)); if (cursor != null && cursor.moveToFirst()) { //下载的文件到本地的目录 String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); //已经下载的字节数 int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); //总需下载的字节数 int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); //Notification 标题 String title =cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE)); //描述 String description =cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION)); //下载对应id long id =cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID)); //下载文件名称 String filename =cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME)); //下载文件的URL链接 String url =cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_URI)); } 1234567891011121314151617181920 1234567891011121314151617181920

    这只能获取一次,数据库中的信息。我们可以使用Timer类,每隔一段时间去查询数据库即可。也可以使用ContentProvider去访问。

    实现相关代码:

    DownloadActivity.Java

    package com.dx.demi.activity; import android.app.Activity; import android.app.DownloadManager; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.ProgressBar; import android.widget.TextView; import com.dx.demi.R; import java.io.File; import java.util.Timer; import java.util.TimerTask; /** * Created by demi on 2017/2/16. */ public class DownloadActivity extends Activity implements View.OnClickListener { private TextView down; private TextView progress; private TextView file_name; private ProgressBar pb_update; private DownloadManager downloadManager; private DownloadManager.Request request; public static String downloadUrl = "http://ucdl.25pp.com/fs08/2017/01/20/2/2_87a290b5f041a8b512f0bc51595f839a.apk"; Timer timer; long id; TimerTask task; Handler handler =new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bundle bundle = msg.getData(); int pro = bundle.getInt("pro"); String name = bundle.getString("name"); pb_update.setProgress(pro); progress.setText(String.valueOf(pro)+"%"); file_name.setText(name); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_download); down = (TextView) findViewById(R.id.down); progress = (TextView) findViewById(R.id.progress); file_name = (TextView) findViewById(R.id.file_name); pb_update = (ProgressBar) findViewById(R.id.pb_update); down.setOnClickListener(this); downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); request = new DownloadManager.Request(Uri.parse(downloadUrl)); request.setTitle("大象投教"); request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); request.setAllowedOverRoaming(false); request.setMimeType("application/vnd.android.package-archive"); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //创建目录 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdir() ; //设置文件存放路径 request.setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS , "app-release.apk" ) ; pb_update.setMax(100); final DownloadManager.Query query = new DownloadManager.Query(); timer = new Timer(); task = new TimerTask() { @Override public void run() { Cursor cursor = downloadManager.query(query.setFilterById(id)); if (cursor != null && cursor.moveToFirst()) { if (cursor.getInt( cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) { pb_update.setProgress(100); install(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/app-release.apk" ); task.cancel(); } String title = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_TITLE)); String address = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); int bytes_downloaded = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); int bytes_total = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); int pro = (bytes_downloaded * 100) / bytes_total; Message msg =Message.obtain(); Bundle bundle = new Bundle(); bundle.putInt("pro",pro); bundle.putString("name",title); msg.setData(bundle); handler.sendMessage(msg); } cursor.close(); } }; timer.schedule(task, 0,1000); } @Override public void onClick(View v) { id = downloadManager.enqueue(request); task.run(); down.setClickable(false); down.setBackgroundResource(R.drawable.btn_disable_shape); } private void install(String path) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse("file://" + path), "application/vnd.android.package-archive"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//4.0以上系统弹出安装成功打开界面 startActivity(intent); } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119

    activity_download.xml

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:gravity="center" android:layout_height="match_parent"> <TextView android:id="@+id/file_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:text="dxtj.apk"/> <ProgressBar android:id="@+id/pb_update" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="10dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" android:max="100" android:progress="0" android:progressDrawable="@drawable/progressbar_color" android:layout_marginBottom="20dp" /> <TextView android:id="@+id/progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_marginBottom="20dp" android:text="0%"/> <TextView android:id="@+id/down" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:paddingTop="10dp" android:paddingBottom="10dp" android:paddingLeft="30dp" android:paddingRight="30dp" android:background="@drawable/btn_red_selector" android:textColor="@color/white" android:text="立即下载"/> </LinearLayout> 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 12345678910111213141516171819202122232425262728293031323334353637383940414243444546

    progressbar_color.xml

    <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@android:id/background"> <shape> <corners android:radius="10dip" /> <gradient android:angle="0" android:centerColor="#e4e4e4" android:centerY="0.75" android:endColor="#e4e4e4" android:startColor="#e4e4e4" /> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="10dip" /> <gradient android:angle="0" android:centerColor="#e4e4e4" android:centerY="0.75" android:endColor="#e4e4e4" android:startColor="#e4e4e4" /> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="10dip" /> <gradient android:angle="0" android:endColor="@color/red" android:startColor="@color/red" /> </shape> </clip> </item> </layer-list> 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253

    转载请注明原文地址: https://ju.6miu.com/read-7227.html

    最新回复(0)