洒家最近需要给应用更新,先下载应用文件,然后安装这个应用文件,没想到在安装应用上翻了车,弄了大半天,以下记录下坑,避免以后自己又踩一次
结论先行
android 9以前
private void installApk(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
try {
mContext.startActivity(intent);
}catch (ActivityNotFoundException e){
Toast.makeText(mContext,mContext.getString(R.string.no_app_to_open_the_file),Toast.LENGTH_SHORT).show();
}
}
Android 9以后
步骤1
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.cvte.myutils.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:ignore="WrongManifestParent">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"
/>
</provider>
步骤2
filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<root-path path="" name="file" />
</paths>
</resources>
步骤3
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
有其他需要自行添加
步骤4
File file = new File("/storage/3242-081F/aapk/Yl-test.apk");
if (!file.exists() || !file.canRead()){
setText("file error:"+file.getAbsolutePath()+" "+file.exists());
return;
}
setText(file.getAbsolutePath()+" exit");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri;
String type = "application/vnd.android.package-archive";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
String authority = "com.cvte.myutils.fileprovider";
uri = FileProvider.getUriForFile(MainActivity.this,authority,file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
uri = Uri.fromFile(file);
}
intent.setDataAndType(uri,type);
MainActivity.this.startActivity(intent);
以下是个人记录,大神勿看勿喷,有错误欢迎指正
1 android9.0以后不能直接使用uri.fromFile来获取,需要用以下方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
String authority = "com.cvte.myutils.fileprovider";
uri = FileProvider.getUriForFile(MainActivity.this,authority,file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
uri = Uri.fromFile(file);
}
2 Failed to find configured root
报错日志如下,就是获取的时候出问题了
Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/Yl-test.apk
01-22 04:16:50.871 4147 4147 E AndroidRuntime: at androidx.core.content.FileProvider$b.a(Unknown Source:177)
01-22 04:16:50.871 4147 4147 E AndroidRuntime: at androidx.core.content.FileProvider.a(Unknown Source:4)
01-22 04:16:50.871 4147 4147 E AndroidRuntime: at com.cvte.myutils.MainActivity.helloWorld(Unknown Source:64)
01-22 04:16:50.871 4147 4147 E AndroidRuntime: ... 13 more
解决方法如下
新建一个filepaths.xml放置在res/xml/下,并在provider用android:resource="@xml/filepaths"指定它
内容为
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<root-path path="" name="file" />
</paths>
</resources>
之所以用<resources>是因为不用的话AndroidStudio会提示无用文件
3 权限
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
4 搞不懂uri作用及对应文件的关系
content://com.cvte.myutils.fileprovider/file/storage/3242-081F/aapk/Yl-test.apk
约等于一个网址,在对应位置存储
storage可以连接到外部存储端