Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

listFiles() returns null on Android 6.0 emulator

I want to read jpeg files from sdcard on Android 6.0 emulator, but file list returns null. The sample code can work on my phone:

            String sdcard = Environment.getExternalStorageDirectory().toString();
            File sdcard_dir = new File(sdcard);
            if (sdcard_dir.isDirectory()) {
                File[] fileNames = sdcard_dir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.toString().endsWith(".jpg") ? true : false;
                    }
                });
            }

fileNames = null!

I can use adb shell to list image files on emulator:

enter image description here

The permission has been added to AndroidManifest.xml:

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

Anything else I can do?

I have to use the emulator because my device cannot be upgraded to Android 6.0 so far, and I want to test some new APIs.

like image 375
yushulx Avatar asked Oct 23 '15 06:10

yushulx


3 Answers

I have observed exactly the same problem, even after adding the runtime permissions code required with Android 6.0.

In my activity I have the following code:

    int permissionCheck1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
    int permissionCheck2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                             Manifest.permission.READ_EXTERNAL_STORAGE},
                REQUEST_READWRITE_STORAGE);
    }

and I receive the expected callback when the user confirms the request for the read/write storage permissions.

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_READWRITE_STORAGE) {
        if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
            finishCreationStep();
        }
    }
}

I have verified in the debugger that both the read and write permissions have been granted. Yet the subsequently executed call to read storage fails:

File[] possible_files = mrpDir.listFiles();

The call to listFiles() returns null. If I terminate the application, and go to Settings > Apps for my app, I see that the storage permission has been granted. If I also terminate the app, and then re-start it, the permissions are there, as expected, and the listFiles() calls works just fine. So, in other words, the change to permissions doesn't take effect until the app is terminated and re-started. Is there some way to get the app to recognize the changed permissions without having to make the user terminate and re-start it manually?

As with the originator of this thread, I am running with an API 23 emulator, since I don't currently have access to an Android 6 device. So I suppose it's possible that there is a problem with the emulator. But that seems unlikely.

like image 141
loxodrome Avatar answered Nov 19 '22 07:11

loxodrome


Android 6.0 introduced Runtime permissions. In addition to declaring the permission on your manifest, you need to request the permission from the user at runtime.

More info and tutorials here: http://developer.android.com/training/permissions/requesting.html

like image 10
1615903 Avatar answered Nov 19 '22 07:11

1615903


Your first call

if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                         Manifest.permission.READ_EXTERNAL_STORAGE},
            REQUEST_READWRITE_STORAGE);
}

is to check if you have the permission. IF you don't have, the permission, callback is called. This is first time.

Subsequently, callback is not called since you already have the permission. So, your code should look like

if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                         Manifest.permission.READ_EXTERNAL_STORAGE},
            REQUEST_READWRITE_STORAGE);
}
else
    finishCreationStep();
like image 1
Ananth Avatar answered Nov 19 '22 06:11

Ananth