Search code examples
androidandroid-file

Environment.getExternalStorageDir().list() returns null


I have the following code in my MainActivity.

Log.d("FILES", Environment.getExternalStorageDirectory().getAbsolutePath());
Log.d("FILES", Environment.getRootDirectory().getAbsolutePath());
Log.d("FILES", Arrays.toString(Environment.getRootDirectory().list()));
Log.d("FILES", Arrays.toString(Environment.getExternalStorageDirectory().list()));
Log.d("FILES", Environment.getExternalStorageState());
Log.d("FILES", String.valueOf(Environment.getExternalStorageDirectory().listFiles() != null));

The aboce code shows an output like this in logcat:

12-28 08:38:51.344 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: /storage/emulated/0
12-28 08:38:51.344 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: /system
12-28 08:38:51.344 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: [lost+found, app, bin, build.prop, data, etc, fonts, framework, lib, media, plugin, preloadres, priv-app, recovery-from-boot.p, res, tts, usr, vendor, xbin]
12-28 08:38:51.347 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: null
12-28 08:38:51.353 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: mounted
12-28 08:38:51.356 23429-23429/com.tahsinalsayeed.codeviewer D/FILES: false

I can't make heads or tails why I can't list files under getExternalStorageDir. According to the accepted answer to this question this should work. I have the following permissions in my manifest.

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

I have tested in on both physical device and emulator with API 23.


Solution

  • In Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.

    Note: Mention permission in manifest will not work in API 23, you need to ask permission during run time.

    Please follow this official link here

    askForPermission(Manifest.permission.READ_EXTERNAL_STORAGE,100);
    

    Method to ask permission from user

    private void askForPermission(String permission, Integer requestCode) {
        if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {
    
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
    
                //This is called if user has denied the permission before
                //In this case I am just asking the permission again
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
    
            } else {
    
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
            }
        } else {
            Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show();
        }
    }
    

    To handle the results of a permission request, the onRequestPermissionsResult method is called. It’s code is below:

    Note: When a result is returned, it checks whether the permission was granted or not. If it is, the requestCode is passed.

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
    
            //permission granted
        } else {
            //Permission Denied
        }
    }