androidreact-nativeandroid-external-storagereact-native-permissions

PermissionAndroid.request() always returns never_ask_again without any prompt. React Native


I already tried results from most of the questions but none worked for me. I try accessing the WRITE_EXTERNAL_STORAGE permission using the PermissionAndroid.request method but it always returns never_ask_again as the result.

My requestFile:

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);
      }
    }

This is my AndroidManifest.xml file

<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>

Please help me with fixing the issue. Thanks in Advance.

Edit: targetSDKVersion : 33 trying to test the app in Android 13


Solution

  • I had the same issue for the POST_NOTIFICATIONS permission, so I looked around and found this github issue posted on react-native's repo that talks about this issue occurring for both the POST_NOTIFICATIONS and WRITE_EXTERNAL_STORAGE permissions.

    POST_NOTIFICATIONS

    Apparently, you don't ask for the permission if the API level is below 33 (Android 13), as Android doesn't recognize the permission for these versions.

    That explains why in version older the PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS) method returns never_ask_again without any prompt instead of granted. In other words, Android doesn't know the permission on older APIs as it simply doesn't exist.

    Therefore, the correct way to handle it is to explicitly check for the Android version before requesting the permission:

    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

    As for the WRITE_EXTERNAL_STORAGE permission, in the same github issue, it is stated that in Android 13 no WRITE_EXTERNAL_STORAGE permission is needed, and this example is given:

    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';
    }