Android 11 软件包可见性问题

huangapple go评论88阅读模式
英文:

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){
            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预览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$000(MainActivity.java:42)
        at x.x.x.MainActivity$1.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和Gradle版本为4.0.0。这只是一个错误,还是我做错了什么,因为Chrome可以管理APK安装。

英文:

I have a app that downloads an apk from server, but I am unable to launch it like other android versions even though I have queries tag in android manifest

Here is the intent code:-

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 &gt;= 24) {
//                fileUri = FileProvider.getUriForFile(this, getPackageName(),
//                        file);
//            }
            if(Build.VERSION.SDK_INT&gt;=24){
                try{
                    Method m = StrictMode.class.getMethod(&quot;disableDeathOnFileUriExposure&quot;);
                    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 , &quot;application/vnd.android.package-archive&quot;);
            startActivityForResult(intent, PERMISSIONS_REQUEST);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

Here is my manifest file

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;x.x.x&quot;&gt;
&lt;uses-permission android:name=&quot;android.permission.REQUEST_INSTALL_PACKAGES&quot;/&gt;
    &lt;uses-permission android:name=&quot;android.permission.WAKE_LOCK&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.ACCESS_NETWORK_STATE&quot; /&gt;
&lt;queries&gt;
    &lt;intent&gt;
        &lt;action android:name=&quot;android.intent.action.VIEW&quot; /&gt;
        &lt;data android:mimeType=&quot;application/vnd.android.package-archive&quot; /&gt;
    &lt;/intent&gt;
&lt;/queries&gt;
    &lt;application
        android:allowBackup=&quot;false&quot;
        android:icon=&quot;@mipmap/appicon&quot;
        android:label=&quot;@string/app_name&quot;
        android:roundIcon=&quot;@mipmap/appicon&quot;
        android:networkSecurityConfig=&quot;@xml/network_security_config&quot;

        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/AppTheme&quot;&gt;

        &lt;activity android:name=&quot;.MainActivity&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;

&lt;/manifest&gt;

Gradle file:-

apply plugin: &#39;com.android.application&#39;

android {
    compileSdkVersion 29
    buildToolsVersion &quot;30.0.0-rc4&quot;

    defaultConfig {
        applicationId &quot;x.x.x&quot;
        minSdkVersion 22
        targetSdkVersion &#39;R&#39;
        versionCode 3
        versionName &quot;1.11&quot;

        testInstrumentationRunner &quot;androidx.test.runner.AndroidJUnitRunner&quot;
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile(&#39;proguard-android-optimize.txt&#39;), &#39;proguard-rules.pro&#39;
        }
    }

}

dependencies {
    implementation fileTree(dir: &#39;libs&#39;, include: [&#39;*.jar&#39;])

    implementation &#39;androidx.appcompat:appcompat:1.1.0&#39;
    implementation &#39;androidx.constraintlayout:constraintlayout:1.1.3&#39;
    testImplementation &#39;junit:junit:4.12&#39;
    androidTestImplementation &#39;androidx.test.ext:junit:1.1.1&#39;
    androidTestImplementation &#39;androidx.test.espresso:espresso-core:3.2.0&#39;
}

I have allowed to my app the permission to install unknown apps on android R preview 4 emulator.

Log:-

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$000(MainActivity.java:42)
        at x.x.x.MainActivity$1.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)

I am using android studio 4 and gradleversion is 4.0.0
Is it just a bug or am I doing something wrong as chrome manages to intent apk install.

答案1

得分: 1

> 这只是一个错误还是我做错了什么

你做错了某些事情。

Uri.fromFile() 自 Android 7.0 起已被禁止使用。通常情况下,如果你尝试在 Intent 中使用它,会导致应用崩溃并抛出 FileUriExposedException。但你并没有修复这个问题,而是选择尝试绕过检查,通过你的 disableDeathOnFileUriExposure hack。然而,没有其他人需要遵循你的 file:///Uri,因为这个用法已经被禁止多年。显然,Android R 的安装程序不再支持 file:///

所以,至少在 Android 7.0+ 上你需要切换到使用 FileProviderUri.fromFile() 在 Android 6.0 及更早版本是可以的,而且特别针对你尝试做的事情(安装 APK),在这些旧设备上你别无选择,只能使用 Uri.fromFile()

此外,值得注意的是,在 Android 10+ 上使用 ACTION_VIEW 来安装 APK 已经被弃用。虽然目前它还能临时工作,但 Google 希望你改用 PackageInstaller API。

英文:

> Is it just a bug or am I doing something wrong

You are doing something wrong.

Uri.fromFile() has been banned, in effect, since Android 7.0. Normally, your attempt to us it with an Intent would crash with a FileUriExposedException. Rather than fixing the problem, you decided to try to bypass the check, through your disableDeathOnFileUriExposure hack. However, nobody else has to honor your file:/// Uri, because, again, that has been banned for years. Apparently, Android R's installer no longer supports file:///.

So, at minimum, you need to switch to using FileProvider on Android 7.0+. Uri.fromFile() is fine for Android 6.0 and older, and specifically for what you are trying to do (install an APK), you have no choice but to use Uri.fromFile() for those older devices.

Also note that using ACTION_VIEW for installing an APK has been deprecated on Android 10+. Temporarily it still works, but Google would like you to switch to the PackageInstaller API instead.

huangapple
  • 本文由 发表于 2020年5月30日 21:43:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/62103310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定