直接上代码,一个函数完成
在需要的地方调用即可,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中拆分文件名
初学者,水平不高,勿喷,有问题和平讨论,欢迎指正
谢绝转载