java - android app下载apk文件并打开(安装)
问题描述
我想知道您是否可以提供帮助,我正在尝试在版本检查后下载一个 apk 文件作为更新。它正在下载 apk,但它不会打开 apk 文件它在尝试打开 apk 时打印错误
错误 :
E/UpdateAPP: Update error! file:///storage/emulated/0/download/update.apk exposed beyond app through Intent.getData()
代码 :
public class UpdateApp extends AsyncTask<String,Void,Void> {
private Context context;
public void setContext(Context contextf){
context = contextf;
}
@Override
protected Void doInBackground(String... arg0) {
try {
URL url = new URL(arg0[0]);
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH);
file.mkdirs();
File outputFile = new File(file, "update.apk");
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "/update.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
context.startActivity(intent);
} catch (Exception e) {
Log.e("UpdateAPP", "Update error! " + e.getMessage());
}
return null;
}}
我的 targetSdkVersion :
targetSdkVersion 27
谢谢您的帮助
解决方案
从 API 26 开始,“REQUEST_INSTALL_PACKAGES”权限是实现安装 apk 文件的必要权限。
- 在 res/xml 文件夹中创建“file_paths.xml”以使用 FileProvider api
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="" path="/" />
</paths>
- 在 AndroidManifest.xml 中声明 FileProvider 和权限
笔记。我使用的是 Androidx 版本的 FileProvider,如果你不使用 androidx,请确保 android.support.v4.content.FileProvider
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="{PACKAGE_NAME}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
- 通过 FileProvider api 获取“Uri”并请求安装权限
private fun openFile(file: File) {
val uri = if (Build.VERSION.SDK_INT >= 24) {
val authority = packageName + ".fileprovider"
FileProvider.getUriForFile(this, authority, file)
} else {
Uri.fromFile(file)
}
val myMime = MimeTypeMap.getSingleton()
val mimeType = myMime.getMimeTypeFromExtension(file.extension)
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri, mimeType)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
if (Build.VERSION.SDK_INT >= 26 && !packageManager.canRequestPackageInstalls()) {
startActivity(
Intent(
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:$packageName")
)
)
} else {
intent.action = Intent.ACTION_VIEW
startActivity(intent)
}
}
编辑 -> 删除在我的项目中使用的特定方法。
推荐阅读
- css - 在 Vaadin 14 中将“对话框”小部件的宽度设置为页面的百分比
- html - 如何使用 CSS 将一个元素淡入另一个元素?
- angular - 如何使用 Angular 创建多个页面?
- flutter - 无法显示图标和文字
- java - 在 JUnit 中自动注册扩展
- python - github和Python 3.8有问题吗?为什么我不能运行这段代码?
- mysql - Django:类型错误在“?” __str__ 返回非字符串(NoneType 类型)
- javascript - 降低嵌套for循环的时间复杂度
- html - 如何制作空白:预包装;证明文本?
- sockets - 创建数据集
来自从套接字创建的数据集(Spark Java)