(android 基础知识) DownLoadManager

小虾米 阅读:583 2021-04-01 10:12:16 评论:0
                 从Android 2.3开始新增了一个下载管理类,在SDK的文档中我们查找android.app.DownloadManager可以看到。下载管理类可以长期处理多个HTTP下载任务,客户端只需要给出请求的Uri和存放目标文件的位置即可,下载管理使用了一个AIDL服务器所以可以放心的在后台执行,同时实例化的方法需要使用getSystemService(Context.DOWNLOAD_SERVICE) ,Android123再次提醒使用API Level为9的用户可以轻松的通过新增的这个API实现Android平台上的文件下载操作。

 DownloadManager类提供了以下几种方法来处理,

  long  enqueue(DownloadManager.Request request)   //存入队列一个新的下载项

 ParcelFileDescriptor  openDownloadedFile(long id)  //打开一个下载后的文件用于读取,参数中的long型id是一个provider中的一条记录。

Cursor  query(DownloadManager.Query query)  //查询一个下载,返回一个Cursor

int  remove(long... ids)  //取消下载同时移除这些条从下载管理中。

  我们可以看到提供的方法都比较简单,给我们操作的最终封装成为一个provider数据库的方式进行添加、查询和移除,但是对于查询和添加任务的细节,我们要看看DownloadManager.Request类和DownloadManager.Query 类了。

  一、DownloadManager.Request类的成员和定义

DownloadManager.Request  addRequestHeader(String header, String value)  // 添加一个Http请求报头,对于这两个参数,Android开发网给大家举个小例子,比如说User-Agent值可以为Android123或Windows XP等等了,主要是给服务器提供标识。
DownloadManager.Request  setAllowedNetworkTypes(int flags)  //设置允许使用的网络类型,这一步Android 2.3做的很好,目前有两种定义分别为NETWORK_MOBILE和NETWORK_WIFI我们可以选择使用移动网络或Wifi方式来下载。
DownloadManager.Request  setAllowedOverRoaming(boolean allowed)  //对于下载,考虑到流量费用,这里是否允许使用漫游。
DownloadManager.Request  setDescription(CharSequence description)  //设置一个描述信息,主要是最终显示的notification提示,可以随便写个自己区别
DownloadManager.Request  setDestinationInExternalFilesDir(Context context, String dirType, String subPath)  //设置目标存储在外部目录,一般位置可以用 getExternalFilesDir()方法获取。
DownloadManager.Request  setDestinationInExternalPublicDir(String dirType, String subPath)  //设置外部存储的公共目录,一般通过getExternalStoragePublicDirectory()方法获取。
DownloadManager.Request  setDestinationUri(Uri uri)  //设置需要下载目标的Uri,可以是http、ftp等等了。
DownloadManager.Request  setMimeType(String mimeType)  //设置mime类型,这里看服务器配置,一般国家化的都为utf-8编码。
DownloadManager.Request  setShowRunningNotification(boolean show)  //是否显示下载进度的提示
DownloadManager.Request  setTitle(CharSequence title)  //设置notification的标题
DownloadManager.Request  setVisibleInDownloadsUi(boolean isVisible)  //设置下载管理类在处理过程中的界面是否显示

  当然了Google还提供了一个简单的方法来实例化本类,这个构造方法为DownloadManager.Request(Uri uri) ,我们直接填写一个Uri即可,上面的设置使用默认情况。

 二、DownloadManager.Query类

  对于当前下载内容的状态,我们可以使用DownloadManager.Query类来获取,本类比较简单,仅仅提供了两个方法。

  DownloadManager.Query  setFilterById(long... ids)  //根据id来过滤查找。
  DownloadManager.Query  setFilterByStatus(int flags) //根据任务的状态来查找。

  详细的状态在android.app.DownloadManager类中有定义,目前Android 2.3中的定义为:

int STATUS_FAILED 失败
int STATUS_PAUSED 暂停
int STATUS_PENDING 等待将开始
int STATUS_RUNNING 正在处理中
int STATUS_SUCCESSFUL 已经下载成功

 最后Android开发网提醒大家要说的是因为DownloadManager类提供的query方法返回一个Cursor对象,这些状态保存在这个游标的COLUMN_STATUS 字段中。

  1. 下载的状态完成均是以广播的形式通知大家,目前API Level为9定义了下面三种Intent的action

  ACTION_DOWNLOAD_COMPLETE下载完成的动作。
  ACTION_NOTIFICATION_CLICKED 当用户单击notification中下载管理的某项时触发。
  ACTION_VIEW_DOWNLOADS 查看下载项

  2. 对于一个尚未完成的项,在Cursor中我们查找COLUMN_REASON字段,可能有以下定义:

int ERROR_CANNOT_RESUME 不能够继续,由于一些其他原因。
int ERROR_DEVICE_NOT_FOUND 外部存储设备没有找到,比如SD卡没有插入。
int ERROR_FILE_ALREADY_EXISTS 要下载的文件已经存在了,Android123提示下载管理类是不会覆盖已经存在的文件,所以如果需要重新下载,请先删除以前的文件。

int ERROR_FILE_ERROR 可能由于SD卡原因导致了文件错误。
int ERROR_HTTP_DATA_ERROR 在Http传输过程中出现了问题。
int ERROR_INSUFFICIENT_SPACE 由于SD卡空间不足造成的 

int ERROR_TOO_MANY_REDIRECTS 这个Http有太多的重定向,导致无法正常下载
int ERROR_UNHANDLED_HTTP_CODE 无法获取http出错的原因,比如说远程服务器没有响应。
int ERROR_UNKNOWN 未知的错误类型.

 3. 有关暂停的一些状态,同样COLUMN_REASON字段的值可能是以下定义

int PAUSED_QUEUED_FOR_WIFI 由于移动网络数据问题,等待WiFi连接能用后再重新进入下载队列。
int PAUSED_UNKNOWN 未知原因导致了任务下载的暂停.
int PAUSED_WAITING_FOR_NETWORK 可能由于没有网络连接而无法下载,等待有可用的网络连接恢复。.
int PAUSED_WAITING_TO_RETRY 由于重重原因导致下载暂停,等待重试。

  有关Android 2.3中新增的下载管理DownloadManager的介绍基本上已经完全讲完,如果你对Cursor、Provider这些基础概念了解的话,可以看到这个下载管理类可以帮我们减少很多不必要的代码编写。

 

实例代码:

package com.rf.downloadmanager; 
 
import android.net.Uri; 
import android.os.Bundle; 
import android.app.Activity; 
import android.app.DownloadManager; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.Toast; 
 
public class MainActivity extends Activity { 
	// 组件 
	private Button start; 
	// 下载管理器 
	DownloadManager manager; 
	// 界面上行文 
	private Context context; 
	//广播 
	DownloadCompleteReceiver receiver; 
 
	@Override 
	protected void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState); 
		setContentView(R.layout.activity_main); 
		// 下载管理器DownloadManager实例化 
		manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); 
		// 界面上下文实例化 
		context = this; 
		//广播实例化 
		receiver = new DownloadCompleteReceiver();    
 
		// 启动相关的监听事件 
		start = (Button) findViewById(R.id.start); 
		start.setOnClickListener(new OnClickListener() { 
			@Override 
			public void onClick(View v) { 
				// 创建下载请求---DownloadManager.Request 
				DownloadManager.Request down = new DownloadManager.Request(Uri 
						.parse("http://www.qzone.cc/haokan/keai/217033.html")); 
				// 设置允许使用的网络类型,这里是移动网络和wifi都可以 
				down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE 
						| DownloadManager.Request.NETWORK_WIFI); 
				// 禁止发出通知,既后台下载 
				down.setShowRunningNotification(false); 
				// 不显示下载界面 
				down.setVisibleInDownloadsUi(false); 
				// 设置下载后文件存放的位置 
				down.setDestinationInExternalFilesDir(context, null, 
						"217033.html"); 
				// 将下载请求放入队列 
				manager.enqueue(down); 
 
			} 
 
		}); 
	} 
 
	// 自定义广播实例 
	// 接受下载完成后的intent 
	class DownloadCompleteReceiver extends BroadcastReceiver { 
		@Override 
		public void onReceive(Context context, Intent intent) { 
			if (intent.getAction().equals( 
					DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { 
				long downId = intent.getLongExtra( 
						DownloadManager.EXTRA_DOWNLOAD_ID, -1); 
				Log.v("MainActivity", " 下载完毕! id编号 : " + downId); 
				Toast.makeText(context, intent.getAction() + "id : " + downId, 
						Toast.LENGTH_SHORT).show(); 
			} 
		} 
 
	} 
 
   //注销广播 
	@Override 
	protected void onDestroy() { 
		// TODO Auto-generated method stub 
		 if(receiver != null)unregisterReceiver(receiver); 
		super.onDestroy(); 
	} 
	//注册广播 
	@Override 
	protected void onResume() { 
		// TODO Auto-generated method stub 
		  registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));    
 
		super.onResume(); 
	} 
	 
 
}


androidmainfest文件

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.rf.downloadmanager" 
    android:versionCode="1" 
    android:versionName="1.0" > 
 
    <uses-sdk 
        android:minSdkVersion="10" 
        android:targetSdkVersion="10" /> 
 
    <application 
        android:allowBackup="true" 
        android:icon="@drawable/ic_launcher" 
        android:label="@string/app_name" 
        android:theme="@style/AppTheme" > 
        <activity 
            android:name="com.rf.downloadmanager.MainActivity" 
            android:label="@string/app_name" > 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 
    </application> 
    <!--权限问题  --> 
    <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" />  
 
</manifest>


 

标签:Android
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号