PermissionAndroid.request() 总是返回 never_ask_again 且没有任何提示。反应本机

问题描述 投票:0回答:3

我已经尝试了大多数问题的结果,但没有一个对我有用。 我尝试使用 PermissionAndroid.request 方法访问 WRITE_EXTERNAL_STORAGE 权限,但它总是返回 never_ask_again 作为结果。

我的请求文件:

try {
        const granted = await PermissionsAndroid.request(
          PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
          {
            title: 'External Storage Write Permission',
            message: 'App needs write permission',
          },
        );

        console.log(granted);
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
          // Start downloading
          downloadFile();
          console.log('Storage Permission Granted.');
        } else {
          // If permission denied then show alert
          Alert.alert('Error', 'Storage Permission Not Granted');
        }
      } catch (err) {
        // To handle permission related exception
        console.log('++++' + err);
      }
    }

这是我的 AndroidManifest.xml 文件

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <application android:name=".MainApplication" android:usesCleartextTraffic="true" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme">
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
      </intent-filter>
    </activity>
  </application>
</manifest>

请帮助我解决问题。 预先感谢。

编辑: targetSDKVersion:33 尝试在 Android 13 中测试应用程序

android react-native android-external-storage react-native-permissions
3个回答
1
投票

当您在 API 级别 33 (Android 13) 中检查代码时,您必须跳过检查并请求 API 级别 33 中的 WRITE_EXTERNAL_STORAGE 许可,因为新的 Android 版本引入了存储访问限制并提供了访问数据的安全方式。如果不需要向用户显示数据,建议始终仅将数据写入应用程序目录(缓存目录)。有关存储更改的更多信息,请参阅此文档

链接:-

https://developer.android.com/about/versions/11/privacy/storage

https://developer.android.com/training/data-storage/shared/media

https://stackoverflow.com/a/74296799/5696047


1
投票

我对

POST_NOTIFICATIONS
权限也有同样的问题,所以我环顾四周,发现这个 github 问题发布在 React-Native 的存储库 上,讨论了
POST_NOTIFICATIONS
WRITE_EXTERNAL_STORAGE
权限发生的问题。

POST_通知

显然,如果 API 级别低于 33 (Android 13),则不需要请求权限,因为 Android 无法识别这些版本的权限。

这解释了为什么在较旧的版本中,

PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS) 
方法返回
never_ask_again
而没有任何提示
而不是granted。换句话说,Android 不知道旧 API 的权限,因为它根本不存在。

因此,正确的处理方式是在请求权限之前显式检查Android版本:

let notificationsPermissionCheck: PermissionStatus = "granted";
// The permission exists only for Android API versions bigger than 33 (Android 13),
// we can assume it's always granted beforehand
if (Platform.Version >= 33) {
  notificationsPermissionCheck = await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
  );
}

console.log("notificationsPermissionCheck:", notificationsPermissionCheck);

写入外部存储

关于

WRITE_EXTERNAL_STORAGE
权限,在同一个github问题中,说明在Android 13中不需要
WRITE_EXTERNAL_STORAGE
权限,并给出了这个例子:

async function hasAndroidPermission() {
  if (Number(Platform.Version) >= 33) {
    return true;
  }

  const permission = PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE;

  const hasPermission = await PermissionsAndroid.check(permission);
  if (hasPermission) {
    return true;
  }

  const status = await PermissionsAndroid.request(permission);
  return status === 'granted';
}

0
投票

这可能是 Android 上权限流程的预期结果。

从 Android 11 开始,如果用户在设备上安装应用的生命周期内多次点击拒绝特定权限,则当您的应用再次请求该权限时,用户将不会看到系统权限对话框。用户的行为暗示“不要再问”。

取自https://developer.android.com/about/versions/11/privacy/permissions#dialog-visibility

react-native-permission 有一个很好的权限流程流程图:https://github.com/zoontek/react-native-permissions#android-flow

© www.soinside.com 2019 - 2024. All rights reserved.