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
原创粉丝点击