READ_EXTERNAL_STORAGE权限请求不会显示在模拟器上

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

READ_EXTERNAL_STORAGE Permission request not showing on emulator

问题

I'm trying to set up a way to register permission result handlers after the activity is initialized, by creating a Map<Integer, Runnable> to hold the handlers, when I request permission I use a randomly generated code and save a runnable to the Map of codes/handlers.

Here's what I have so far in my activity class

private final HashMap<Integer, Runnable> onPermission = new HashMap<>();

// I call this from other classes to ask for a permission and register a handler
public void requestPermission(Runnable onGranted, String... permissions) {
    int code = Permissions.permissionRequestCode();
    onPermission.put(code, onGranted);
    requestPermissions(permissions, code);
}

// Overriding this method to check if the Map has a handler for the granted request
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Runnable handler = onPermission.get(requestCode);
    if (handler != null && isGranted(grantResults)) {
        handler.run();
        onPermission.remove(requestCode);
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

// Utility method to check if all the requested permissions are granted
private boolean isGranted(int[] results) {
    for (int i : results) {
        if (i != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

And here is an example of how this can be used, where owner is my Activity instance:

private void readImages() {
    if (ContextCompat.checkSelfPermission(owner, Manifest.permission.READ_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED) {
        loadImages();
    } else {
        owner.requestPermission(this::loadImages, Manifest.permission.READ_EXTERNAL_STORAGE);
    }
}

Now running this on an actual device (Android 12, API 31), works exactly like I would expect (the request shows, and the handler is executed when the permission is granted), however on the emulator (Android 13, API 33), nothing shows when the permission is requested, and it remains "not granted", the permission doesn't even show in the "App info" even though it's included in the manifest.

Real device:
READ_EXTERNAL_STORAGE权限请求不会显示在模拟器上

Emulator:
READ_EXTERNAL_STORAGE权限请求不会显示在模拟器上

My manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Mesa"
        android:roundIcon="@mipmap/ic_launcher"
        android:supportsRtl="true"
        android:theme="@style/Theme.Mesa.NoActionBar"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".app.Mesa"
            android:configChanges="uiMode|screenSize|colorMode"
            android:exported="true"
            android:theme="@style/Theme.Mesa.NoActionBar"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

My build.gradle:

android {
    compileSdk 33

    defaultConfig {
        applicationId "org.luke.mesa"
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        proguardFiles 'proguard-rules.pro'
    }

    buildTypes {
        release {
            minifyEnabled true
        }

        debug {
            minifyEnabled false
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
        allprojects {
            tasks.withType(JavaCompile){
                options.compilerArgs << "-Xlint:deprecation"
            }
        }
    }
    buildFeatures {
        viewBinding true
        dataBinding true
    }
    packagingOptions {
        resources {
            merges += ['META-INF/DEPENDENCIES']
        }
    }
    namespace 'org.luke.mesa'
    dependenciesInfo {
        includeInApk true
        includeInBundle true
    }
    buildToolsVersion '33.0.0'
}

Possible duplicates which didn't solve my problem:

英文:

I'm trying to set up a way to register permission result handlers after the activity is initialized, by creating a Map&lt;Integer, Runnable&gt; to hold the handlers, when I request permission I use a randomly generated code and save a runnable to the Map of codes/handlers.

Here's what I have so far in my activity class

private final HashMap&lt;Integer, Runnable&gt; onPermission = new HashMap&lt;&gt;();

//i call this from other classes to ask for a permission and register a handler
public void requestPermission(Runnable onGranted, String...permissions) {
    int code = Permissions.permissionRequestCode();
    onPermission.put(code, onGranted);
    requestPermissions(permissions, code);
}

//overriding this method to check if the Map has a handler for the granted request
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    Runnable handler = onPermission.get(requestCode);
    if (handler != null &amp;&amp; isGranted(grantResults)) {
        handler.run();
        onPermission.remove(requestCode);
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

//utility method to check if all the requested permissions are granted
private boolean isGranted(int[] results) {
    for (int i : results) {
        if (i != PackageManager.PERMISSION_GRANTED) {
            return false;
        }
    }
    return true;
}

And here is an example of how this can be used, where owner is an my Activity instance :

private void readImages() {
    if (ContextCompat.checkSelfPermission(owner, Manifest.permission.READ_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED) {
        loadImages();
    } else {
        owner.requestPermission(this::loadImages, Manifest.permission.READ_EXTERNAL_STORAGE);
    }
}

Now running this on an actual device (Android 12, API 31), works exactly like I would expect (the request shows, and the handler is executed when the permission is granted), however on the emulator (Android 13, API 33), nothing shows when the permission is requested, and it remains "not granted", the permission doesn't even show in the "App info" even though it's included in the manifest.

Real device :

READ_EXTERNAL_STORAGE权限请求不会显示在模拟器上

Emulator :

READ_EXTERNAL_STORAGE权限请求不会显示在模拟器上

My manifest :

&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;&gt;

    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot;/&gt;

    &lt;application
        android:allowBackup=&quot;true&quot;
        android:icon=&quot;@mipmap/ic_launcher&quot;
        android:label=&quot;Mesa&quot;
        android:roundIcon=&quot;@mipmap/ic_launcher&quot;
        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/Theme.Mesa.NoActionBar&quot;
        android:usesCleartextTraffic=&quot;true&quot;&gt;
        &lt;activity
            android:name=&quot;.app.Mesa&quot;
            android:configChanges=&quot;uiMode|screenSize|colorMode&quot;
            android:exported=&quot;true&quot;
            android:theme=&quot;@style/Theme.Mesa.NoActionBar&quot;
            android:windowSoftInputMode=&quot;adjustResize&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;

My build.gradle :

android {
    compileSdk 33

    defaultConfig {
        applicationId &quot;org.luke.mesa&quot;
        minSdk 24
        targetSdk 33
        versionCode 1
        versionName &quot;1.0&quot;

        testInstrumentationRunner &quot;androidx.test.runner.AndroidJUnitRunner&quot;
        proguardFiles &#39;proguard-rules.pro&#39;
    }

    buildTypes {
        release {
            minifyEnabled true
        }

        debug {
            minifyEnabled false
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
        allprojects {
            tasks.withType(JavaCompile){
                options.compilerArgs &lt;&lt;&quot;-Xlint:deprecation&quot;
            }
        }
    }
    buildFeatures {
        viewBinding true
        dataBinding true
    }
    packagingOptions {
        resources {
            merges += [&#39;META-INF/DEPENDENCIES&#39;]
        }
    }
    namespace &#39;org.luke.mesa&#39;
    dependenciesInfo {
        includeInApk true
        includeInBundle true
    }
    buildToolsVersion &#39;33.0.0&#39;
}

possible duplicates which didn't solve my problem :

答案1

得分: 3

Android 13及更高版本,请求READ_EXTERNAL_STORAGE权限的应用必须改为请求以下一个或多个更细粒度的权限:

  • READ_MEDIA_IMAGES(读取媒体图像)
  • READ_MEDIA_VIDEO(读取媒体视频)
  • READ_MEDIA_AUDIO(读取媒体音频)

参考链接:https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions

英文:

As of Android 13 and above, apps that request READ_EXTERNAL_STORAGE must instead request one or more of the following more granular permissions:

  • READ_MEDIA_IMAGES
  • READ_MEDIA_VIDEO
  • READ_MEDIA_AUDIO

Reference: https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions

huangapple
  • 本文由 发表于 2023年3月3日 22:11:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628155.html
匿名

发表评论

匿名网友

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

确定