Android10 调用系统DownloadManager下载更新App

该博客介绍了如何在Android应用中使用系统下载器下载文件,并结合FileProvider检查文件是否存在,成功下载后自动启动安装流程。详细步骤包括创建BroadcastReceiver监听下载完成,设置权限和路径配置,以及处理文件的读取和安装。适用于Android开发者学习如何处理文件下载与安装操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码,一个函数完成

在需要的地方调用即可,URL需要是静态链接,形如:https://xxxxxx.com/package.apk

/**
 * 调用系统下载器下载文件
 *
 * @param context ()
 * @return boolean 是否成功调用系统下载
 */
private boolean acquireDownload(Context context, String url) {
    Log.i(getClass().toString()+"//acquireDownload()","Download requested");
    String fileName = url.substring(url.lastIndexOf('/') + 1);
    File localFile=new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),fileName);
    if(localFile.exists()){
        Uri uri=FileProvider.getUriForFile(context,packageName,localFile);
        Log.d(getClass().toString()+"//acquireDownload()","File exists");
        Log.d(getClass().toString()+"//acquireDownload()",uri.toString());
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        context.startActivity(intent);
        return true;
    }else{
        Log.d(getClass().toString()+"//acquireDownload()","Download file");
        DownloadManager.Request request=new DownloadManager.Request(Uri.parse(url));
        request.setTitle(context.getResources().getString(R.string.app_name));
        request.setDescription(context.getResources().getString(R.string.notification_downloading_latest_version));
        request.setVisibleInDownloadsUi(true);
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        File cloudFile=new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),fileName);
        request.setDestinationUri(Uri.fromFile(cloudFile));
        DownloadManager downloadManager=(DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        if(downloadManager!=null) {
            Long requestID=downloadManager.enqueue(request);
            context.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    DownloadManager.Query query = new DownloadManager.Query();
                    query.setFilterById(requestID);
                    Cursor cursor=downloadManager.query(query);
                    if(cursor.moveToFirst()){
                        int columnIndex=cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
                        if(DownloadManager.STATUS_SUCCESSFUL==cursor.getInt(columnIndex)){
                            String downloadFileName=cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                            if(downloadFileName!=null) {
                                downloadFileName = downloadFileName.substring(downloadFileName.lastIndexOf('/') + 1);
                                File downloadFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), downloadFileName);
                                Uri uri = FileProvider.getUriForFile(context, packageName, downloadFile);
                                Log.i(getClass().toString() + "//acquireDownload()", uri.toString());
                                Intent installIntent = new Intent(Intent.ACTION_VIEW);
                                installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
                                context.startActivity(installIntent);
                            }
                        }
                    }
                }
            }, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
            return true;
        }
    }
    return false;
}

额外工作:FileProvider

1.在Android Manifest中配置

provider

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="packageName"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path" />
</provider>

 permission

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

2.在xml目录中新建file_path.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="download"
            path="" />
    </paths>
</resources>

就这样,只需要在需要的地方调用acquireDownload(context,url)即可

也可以利用返回值弹出下载失败的Toast或者Dialog

这个函数花了一些时间才写好,主要实现的功能:

1.调用系统下载

2.检查要下载的文件是否存在

3.拉起安装

4.避免全局变量,可以放在任何位置(最好还是放一个地方,在需要的地方new一个)

我这个app用的对象存储作为下载的服务端(永久50g,主要是能白嫖,带宽还大)

所以能直接从URL中拆分文件名

初学者,水平不高,勿喷,有问题和平讨论,欢迎指正

谢绝转载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值