3

I have facing issue related to Android 11 in React Native. In my app, i am fetching WhatsApp status from /storage/emulated/0/WhatsApp/Media/.Statuses/ folder everything working find till Android 10, but in android 11 it shows nothing. Please guild me for this.

Here is my react native code to read WhatsApp status folder

  var RNFS = require('react-native-fs');
        RNFS.readDir(RNFS.ExternalStorageDirectoryPath + '/WhatsApp/Media/.Statuses/').then((result) => {
             printLogs("Result=>", result);
             result.map((item)=>{
                 printLogs("path===>",item.path)
             })
            setStatusList(result.sort((a, b) => a.mtime < b.mtime ? 1 : -1));
            setRefresh(false);

        }).catch((error) => {
            printLogs("error=>", error);
            setRefresh(false);
            setStatusList([]);

        })
Divyata Chauhan
  • 279
  • 4
  • 21

3 Answers3

3

On an Android 11 device your app has access to the folder you mention but it will not see files that belong to other apps. Only subfolders.

So the owner of the file is important on an Android 11 device.

For testing at home you can request all files access with MANAGE_EXTERNAL_STORAGE.

See: Accessing external storage in Android API 29

blackapps
  • 8,011
  • 2
  • 11
  • 25
3

Please make one condition

// Old Version path
String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";   

Android 11 path

targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";

and put one condition

        if (android.os.Build.VERSION.SDK_INT < 30) {
            // Less then 11
            String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses";
            File targetDirector = new File(targetPath);
            allfiles = targetDirector.listFiles();
        } else {
            // Android 11
            String targetPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses";
            File targetDirector = new File(targetPath);
            allfiles = targetDirector.listFiles();

        }
Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31
3

I fixed this problem , and guiding you how to get status from whats app in your app, as mostly peoples are getting issues in android 10 and 11 to get the status after whats app update on 09/06/2021

keep in mind before the update you were getting the status from the path was different and now its update to different path see the changing below ,

first keep the both path and when you will get the status just check which whats app version installed on the device if the old then it will get from old path if the whats app is updated on user device then it will get from the new path

 public static final File STATUS_DIRECTORY = new File(Environment.getExternalStorageDirectory() +
        File.separator + "WhatsApp/Media/.Statuses");

public static final File STATUS_DIRECTORY_NEW = new File(Environment.getExternalStorageDirectory() +
        File.separator + "Android/media/com.whatsapp/WhatsApp/Media/.Statuses");

now check the directory in user device .

 if (Common.STATUS_DIRECTORY.exists()) {

        execute(Common.STATUS_DIRECTORY);

    } else if (Common.STATUS_DIRECTORY_NEW.exists()) {

        execute(Common.STATUS_DIRECTORY_NEW);

    } 

in your mainfest file do these changing

 <uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
    android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    android:minSdkVersion="30"
    tools:ignore="ScopedStorage" />
<uses-permission
    android:name="android.permission.READ_EXTERNAL_STORAGE"
    android:maxSdkVersion="29" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:requestLegacyExternalStorage="true"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

set your device compile sdk version and target to api 29 then your app will run on both android ten and 11 api.

**one thing more you have to use the permission in this way **

public class PermissionActivity extends AppCompatActivity {

private static final int REQUEST_PERMISSIONS = 1234;
private static final String[] PERMISSIONS = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private static final String MANAGE_EXTERNAL_STORAGE_PERMISSION = "android:manage_external_storage";

private final Handler handler = new Handler(Looper.getMainLooper());

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    if (!arePermissionDenied()){
        next();
        return;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && arePermissionDenied()) {

        requestPermissions(PERMISSIONS, REQUEST_PERMISSIONS);
    }

}

@Override
protected void onResume() {
    super.onResume();
    if (!arePermissionDenied()) {
        next();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSIONS && grantResults.length > 0) {
        if (arePermissionDenied()) {
            // Clear Data of Application, So that it can request for permissions again
            ((ActivityManager) Objects.requireNonNull(this.getSystemService(ACTIVITY_SERVICE))).clearApplicationUserData();
            recreate();
        } else {
            next();
        }
    }
}

private void next() {

    handler.postDelayed(() -> {
        startActivity(new Intent(PermissionActivity.this, MainActivity.class));
        finish();
    }, 1000);

}

private boolean arePermissionDenied() {

    for (String permissions : PERMISSIONS) {
        if (ActivityCompat.checkSelfPermission(getApplicationContext(), permissions) != PackageManager.PERMISSION_GRANTED) {
            return true;
        }
    }
    return false;
}

now am referring you to the actual code link that i follow to do this if you need further assistance kindly reply me back in the comment .

when you will go to the below link you have to go to the utils common class and then there is and see the implementation for how its is copying the file try to adjust it in your app code

re3ference link

Najaf Ali
  • 1,433
  • 16
  • 26
  • 4
    if you use manage_external_storage permission, your update will get rejected in Google Play – Akash Chaudhary Jun 16 '21 at 11:49
  • android:requestLegacyExternalStorage="true" is not allowed for 11 Api , but you can put it for api 29 , to target the api 30 and it will work however android:name="android.permission.MANAGE_EXTERNAL_STORAGE" you can use for both android 29 and 30 – Najaf Ali Jun 22 '21 at 12:30
  • 4
    You can use this permission but you want be able to publish your app to play store. It is clearly stated in Google's policy unless you are a file manager app. – Akash Chaudhary Jun 22 '21 at 14:27
  • I have make the changes as above and application is live on the play store – Najaf Ali Jun 27 '21 at 09:42
  • @NajafAli Rejected application with this message Not adhering to All files access permission policy, how can I fix it ? – Saneesh Aug 10 '21 at 06:38