APK下载并跳转安装--DownloadManager、IntentService、BroadcastReceiver的结合使用
来源:互联网 发布:湖南 福建卓知 编辑:程序博客网 时间:2024/06/08 05:21
我们希望应用的下载更新可以不受UI周期的约束,这里下载就涉及到Google提供的大文件下载管理类DownloadManager和startService调用对应的下载服务,下载完成后通过BroadcastReceive通知开启应用安装。下面正式开启步骤解析
本博客Demo地址:http://download.csdn.net/detail/g_ying_jie/9895370
第一步,新建DownloadService继承IntentService处理后台下载耗时操作。对IntentService还不是很了解的可以戳这里
public class DownloadService extends IntentService { //构造方法必须重写 public DownloadService() { super("DownloadService"); } @Override protected void onHandleIntent(Intent intent) { //获取下载地址 String url = intent.getDataString(); //获取DownloadManager对象 DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); //指定APK缓存路径和应用名称,可在SD卡/Android/data/包名/file/Download文件夹中查看 request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, "we_chat.apk"); //设置网络下载环境为wifi request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); //设置显示通知栏,下载完成后通知栏自动消失 request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); //设置通知栏标题 request.setTitle("下载"); request.setDescription("应用正在下载"); request.setAllowedOverRoaming(false); //获得唯一下载id long requestId = downloadManager.enqueue(request); //将id放进Intent Intent broadIntent = new Intent(AppConfig.BROADCAST_ACTION); broadIntent.putExtra(AppConfig.BROADCAST_KEY, requestId); //查询下载信息 DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(requestId); try { boolean isGoing = true; while (isGoing) { Cursor cursor = downloadManager.query(query); if (cursor != null && cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); switch (status) { //如果下载状态为成功 case DownloadManager.STATUS_SUCCESSFUL: isGoing = false; //调用sendBroadcast将intent传递回去 sendBroadcast(broadIntent); break; } } if (cursor != null) { cursor.close(); } } } catch (Exception e) { e.printStackTrace(); } }}
注意在manifest的application中注册DownloadService
<!--android:exported 被设置为"false",保证服务只会在这个App内部运行--> <service android:name=".DownloadService" android:exported="false" />
第二步,在MainActivity中启动服务,并且传入待下载apk的URL
Intent serviceIntent = new Intent(MainActivity.this, DownloadService.class);//将下载地址url放入intent中serviceIntent.setData(Uri.parse(url));startService(serviceIntent);
第三步,注册静态广播UpdateBroadcastReceiver,接收下载成功广播,开启应用安装
public class UpdateBroadcastReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Intent install = new Intent(Intent.ACTION_VIEW); File apkFile = queryDownloadedApk(context, intent.getLongExtra(AppConfig.BROADCAST_KEY, -1)); install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(install); } //通过downLoadId查询下载的apk,解决6.0以后安装的问题 private File queryDownloadedApk(Context context, long id) { File targetApkFile = null; DownloadManager downloader = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); if (id != -1) { DownloadManager.Query query = new DownloadManager.Query(); query.setFilterById(id); query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL); Cursor cur = downloader.query(query); if (cur != null) { if (cur.moveToFirst()) { String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); if (!TextUtils.isEmpty(uriString)) { targetApkFile = new File(Uri.parse(uriString).getPath()); } } cur.close(); } } return targetApkFile; }}
注意在manifest中注册UpdateBroadcastReceive
<receiver android:name=".UpdateBroadcastReceiver"> <intent-filter> <action android:name="com.example.gu.download.DOWNLOAD_COMPLETE" /> </intent-filter></receiver>
这里有个细节需要注意下,filter过滤器action属性可以保证UpdateBroadcastReceiver接收到的是apk下载完成的广播,这需要在DownloadService中发送广播时设置同样的action,如下:
//将id放进IntentIntent broadIntent = new Intent(AppConfig.BROADCAST_ACTION);broadIntent.putExtra(AppConfig.BROADCAST_KEY, requestId);//调用sendBroadcast将intent传递回去sendBroadcast(broadIntent);
这里的AppConfig.BROADCAST_ACTION的值就是UpdateBroadcastReceiver设置的action属性
最后不要忘记了添加用到的权限
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
阅读全文
1 0
- APK下载并跳转安装--DownloadManager、IntentService、BroadcastReceiver的结合使用
- Android中使用DownloadManager下载并安装apk
- DownloadManager——Android 下载 apk 包并安装
- 通过DownloadManager来下载并静默安装APK
- Android 使用系统自带的DownloadManager下载apk
- DownloadManager使用详解以及APK下载更新
- android -- 小功能 DownloadManager——Android 下载 apk 包并安装
- android 自带downloadManager下载apk文件,并打开安装包
- android -- 小功能 DownloadManager——Android 下载 apk 包并安装
- Android DownloadManager下载并自动弹出安装
- Android DownloadManager 下载完成并安装
- 使用okhttp下载一个apk并安装
- Android 自带的DownloadManager 在Service 中下载 apk 安装
- Android 自带的DownloadManager 在Service 中下载 apk 安装
- apk更新、下载、安装(四)---DownloadManager ui方式
- 使用DownloadManager 自动更新apk
- Service、IntentService下载Apk
- Android DownloadManager下载并自动弹出安装(转载)
- C++全局构造与析构底层实现
- 最大子数组问题
- leetcode 367.Valid Perfect Square
- Hessian 序列化,反序列
- 通过银行卡号获取银行卡所属银行
- APK下载并跳转安装--DownloadManager、IntentService、BroadcastReceiver的结合使用
- 快速排序-javascript
- 类属性的小 case 们
- 和莫里的最后14堂星期二的课
- Oracle数据库三范式
- 运算符
- Linux-视频监控系统(1)-产品设计规划
- HTTP错误 403.14 服务器配置为不列出此目录内容
- 微信小程序尺寸单位