我尝试设置一种方法,在Activity初始化后注册权限结果处理程序,方法是创建一个Map<Integer, Runnable>
来保存处理程序,当我请求权限时,我使用随机生成的代码并将runnable保存到代码/处理程序的Map中。
这是我目前为止在活动课上学到的
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;
}
下面是一个如何使用它的示例,其中owner
是一个my Activity示例:
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);
}
}
现在在实际设备上运行(Android 12,API 31),工作原理完全符合我的预期(显示请求,并且在授予权限时执行处理程序),但是在模拟器上(Android 13,API 33),请求权限时没有任何显示,并且它保持"未授予",权限甚至不会显示在"应用程序信息"中,即使它包含在清单中。
真实器械:
模拟器:
我的清单:
<?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>
我的身材。
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'
}
没有解决我的问题的可能重复项:
1条答案
按热度按时间e4yzc0pl1#
自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