Android 自带的DownloadManager 在Service 中下载 apk 安装

     在Android 中如果请求网络,数据量小的时候,可以使用Volley 库,但是如果是下载数据非常大时,变的不可行了。这时我们可以使用Andoid 自带的 DownloadManager ,只要是api 9以上都可以用。网上也有很多例子,但是大部分都是放在Activity 中,这样带来很多的不便。当我们下载大文件时必须在这个界面。所以,我就根据网上的例子,自己改造了一下,把下载放在Service 中,用来下载apk 安装。


   1、首先,拿到启动Service 时传过来的 下载Url ,  DownloadManager 下载后会发出一个广播,所以我们同时注册下载完成的广播;

       

Intent intent = new Intent(MainActivity.this, DownloadRecommdAppService.class);
				intent.putExtra(DownloadRecommdAppService.DOWNLOAD_URL, url);
				startService(intent);

   2、因为 Service 也是运行在主线程中的,所以,我们把下载这些耗时的工作另开线程进行。

   3、在广播中,通过判断下载的状态,如果下载成功,就启动安装apk, 同时停止 Service.


  

public class DownloadRecommdAppService extends Service{

	public static final String DOWNLOAD_URL = "download_url";
	public static final String DOWNLOAD_FOLDER_NAME = "download";
	public  static final String DOWNLOAD_FILE_NAME = "yxhuang.apk";
	
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent != null) {
			String downloadUrl = intent.getExtras().getString(DOWNLOAD_URL);
			if (downloadUrl != null) {
				// 注册下载完成广播
				DownloadCompleteReceiver completeReceiver = new DownloadCompleteReceiver();
				registerReceiver(completeReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
				// 下载
				new Thread(new DownloadRunable(downloadUrl)).start();
			}
		}
		return super.onStartCommand(intent, flags, startId);
	}

	// 下载
	class DownloadRunable implements Runnable{
		private String mDownloadUrl;
		
		public DownloadRunable(String url) {
			mDownloadUrl = url;
		}
		
		@Override
		public void run() {
			startDownload();
		}
		
		// 开始下载
		private void startDownload(){
			
			File folder = Environment.getExternalStoragePublicDirectory(DOWNLOAD_FOLDER_NAME);
			if (!folder.exists() || !folder.isDirectory()) {
				folder.mkdirs();
			}
			
			DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
			DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mDownloadUrl));
			request.setMimeType("application/vnd.android.package-archive");
			// 存储的目录
			request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, DOWNLOAD_FILE_NAME);
			// 设定只有在 WIFI 情况下才能下载
			request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
			request.setTitle("下载应用");
			request.setVisibleInDownloadsUi(true);
			manager.enqueue(request);
		}
	}
	
	
	// 下载完成
	 class DownloadCompleteReceiver extends BroadcastReceiver {

			@Override
			public void onReceive(Context context, Intent intent) {
				 long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
				if (intent.getAction() == DownloadManager.ACTION_DOWNLOAD_COMPLETE) {
					checkStatus(context, completeDownloadId);
				}
			}
			
			private void checkStatus(Context context,Long completeDownloadId){
			    DownloadManager mManager  = (DownloadManager) context.getSystemService(Service.DOWNLOAD_SERVICE);
				DownloadManager.Query query = new DownloadManager.Query();
				query.setFilterById(completeDownloadId);
				Cursor cursor = mManager.query(query);
				if (cursor.moveToFirst()) {
					int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
					
					switch (status) {
					case DownloadManager.STATUS_RUNNING:
						break;
						
					case DownloadManager.STATUS_SUCCESSFUL:
						Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();
						 String apkFilePath = new StringBuilder(Environment.getExternalStorageDirectory().getAbsolutePath())
		                 .append(File.separator).append(DownloadRecommdAppService.DOWNLOAD_FOLDER_NAME).append(File.separator)
		                 .append(DownloadRecommdAppService.DOWNLOAD_FILE_NAME).toString();
						
						 installApk(context, apkFilePath);
						 
						 // 停止下载Service
						 DownloadRecommdAppService.this.stopSelf();
						break;
						
					default:
						break;
					}
				}
				cursor.close();
			}
			
			// 安装APk
			private  void installApk(Context context, String file) {
				File apkFile = new File(file);
				Intent intent = new Intent(Intent.ACTION_VIEW);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
				context.startActivity(intent);
			}
		}
}


 关于 DownloadManager 详细的介绍,移步至 http://www.trinea.cn/android/android-downloadmanager/

       






你可能感兴趣的:(android,service,download,安装APK,Manger)