Android 11 包可见性问题
Android 11 Package Visibilty issue
我有一个从服务器下载 apk 的应用程序,但我无法像其他 android 版本一样启动它,即使我在 android 清单
中有查询标记
这是意图代码:-
private void callInstallProcess() {
try
{
Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(pathname);
Uri fileUri = Uri.fromFile(file);
// if (Build.VERSION.SDK_INT >= 24) {
// fileUri = FileProvider.getUriForFile(this, getPackageName(),
// file);
// }
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace();
}
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(fileUri , "application/vnd.android.package-archive");
startActivityForResult(intent, PERMISSIONS_REQUEST);
}
catch (Exception e)
{
e.printStackTrace();
}
}
这是我的清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="x.x.x">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="application/vnd.android.package-archive" />
</intent>
</queries>
<application
android:allowBackup="false"
android:icon="@mipmap/appicon"
android:label="@string/app_name"
android:roundIcon="@mipmap/appicon"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Gradle 文件:-
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "30.0.0-rc4"
defaultConfig {
applicationId "x.x.x"
minSdkVersion 22
targetSdkVersion 'R'
versionCode 3
versionName "1.11"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
我已允许我的应用程序在 android R preview 4 模拟器上安装未知应用程序。
日志:-
W/System.err: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Android/data/x.x.x/files/ApkDownload/x.x.x.apk typ=application/vnd.android.package-archive flg=0x3 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2067)
W/System.err: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
at android.app.Activity.startActivityForResult(Activity.java:5323)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
at android.app.Activity.startActivityForResult(Activity.java:5281)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
at x.x.x.MainActivity.callInstallProcess(MainActivity.java:126)
at x.x.x.MainActivity.askPerm(MainActivity.java:98)
W/System.err: at x.x.x.MainActivity.access[=14=]0(MainActivity.java:42)
at x.x.x.MainActivity.onClick(MainActivity.java:79)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7478)
at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
D/EGL_emulation: eglMakeCurrent: 0xe8ae0220: ver 2 0 (tinfo 0xe8e31210)
我正在使用 android studio 4 并且 gradleversion 是 4.0.0
这只是一个错误还是我做错了什么,因为 chrome 设法安装了 apk。
Is it just a bug or am I doing something wrong
你做错了什么。
Uri.fromFile()
实际上从 Android 7.0 开始就被禁止了。通常,您尝试使用 Intent
来使用它会因 FileUriExposedException
而崩溃。您没有解决问题,而是决定尝试通过 disableDeathOnFileUriExposure
hack 绕过检查。但是,没有其他人必须尊重您的 file:///
Uri
,因为这已经被禁止多年了。显然,Android R 的安装程序不再支持 file:///
.
因此,您至少需要在 Android 7.0+ 上切换到使用 FileProvider
。 Uri.fromFile()
适用于 Android 6.0 及更早版本,特别是对于您要尝试执行的操作(安装 APK),您别无选择,只能对那些较旧的设备使用 Uri.fromFile()
。
另请注意,Android 10+ 已弃用使用 ACTION_VIEW
安装 APK。暂时它仍然有效,但 Google 希望您改用 PackageInstaller
API。
我有一个从服务器下载 apk 的应用程序,但我无法像其他 android 版本一样启动它,即使我在 android 清单
中有查询标记这是意图代码:-
private void callInstallProcess() {
try
{
Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(pathname);
Uri fileUri = Uri.fromFile(file);
// if (Build.VERSION.SDK_INT >= 24) {
// fileUri = FileProvider.getUriForFile(this, getPackageName(),
// file);
// }
if(Build.VERSION.SDK_INT>=24){
try{
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
}catch(Exception e){
e.printStackTrace();
}
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(fileUri , "application/vnd.android.package-archive");
startActivityForResult(intent, PERMISSIONS_REQUEST);
}
catch (Exception e)
{
e.printStackTrace();
}
}
这是我的清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="x.x.x">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:mimeType="application/vnd.android.package-archive" />
</intent>
</queries>
<application
android:allowBackup="false"
android:icon="@mipmap/appicon"
android:label="@string/app_name"
android:roundIcon="@mipmap/appicon"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Gradle 文件:-
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "30.0.0-rc4"
defaultConfig {
applicationId "x.x.x"
minSdkVersion 22
targetSdkVersion 'R'
versionCode 3
versionName "1.11"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
我已允许我的应用程序在 android R preview 4 模拟器上安装未知应用程序。
日志:-
W/System.err: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///storage/emulated/0/Android/data/x.x.x/files/ApkDownload/x.x.x.apk typ=application/vnd.android.package-archive flg=0x3 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2067)
W/System.err: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1727)
at android.app.Activity.startActivityForResult(Activity.java:5323)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
at android.app.Activity.startActivityForResult(Activity.java:5281)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
at x.x.x.MainActivity.callInstallProcess(MainActivity.java:126)
at x.x.x.MainActivity.askPerm(MainActivity.java:98)
W/System.err: at x.x.x.MainActivity.access[=14=]0(MainActivity.java:42)
at x.x.x.MainActivity.onClick(MainActivity.java:79)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7478)
at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)
D/EGL_emulation: eglMakeCurrent: 0xe8ae0220: ver 2 0 (tinfo 0xe8e31210)
我正在使用 android studio 4 并且 gradleversion 是 4.0.0 这只是一个错误还是我做错了什么,因为 chrome 设法安装了 apk。
Is it just a bug or am I doing something wrong
你做错了什么。
Uri.fromFile()
实际上从 Android 7.0 开始就被禁止了。通常,您尝试使用 Intent
来使用它会因 FileUriExposedException
而崩溃。您没有解决问题,而是决定尝试通过 disableDeathOnFileUriExposure
hack 绕过检查。但是,没有其他人必须尊重您的 file:///
Uri
,因为这已经被禁止多年了。显然,Android R 的安装程序不再支持 file:///
.
因此,您至少需要在 Android 7.0+ 上切换到使用 FileProvider
。 Uri.fromFile()
适用于 Android 6.0 及更早版本,特别是对于您要尝试执行的操作(安装 APK),您别无选择,只能对那些较旧的设备使用 Uri.fromFile()
。
另请注意,Android 10+ 已弃用使用 ACTION_VIEW
安装 APK。暂时它仍然有效,但 Google 希望您改用 PackageInstaller
API。