Android - ask write to SD card permission dialog

流过昼夜 提交于 2020-07-18 16:21:59

问题


I am having trouble gaining write access to device SD card root directory. I can write to device internal storage and app package folder in an SD card without problems. I found that gaining access to an SD card is possible using Storage Access Framework, so I looked at other apps to see how they gain access to an SD card, and found Total Commander with its neat permission dialog.

How to show such a dialog because I cannot find any examples? My goal is to store large files on the SD card that stay after uninstalling the app.

Similar questions:

Android (Write on external SD-Card): java.io.IOException: Permission denied

Android M write to SD Card - Permission Denied

Android SD Card Write Permission using SAF (Storage Access Framework)


回答1:


Unfortunately, using createAccessIntent is now deprecated in Android Q, and the documentation states that if you use it in Android Q, it will immediately return RESULT_CANCELED.

They recommend you use an intent with ACTION_OPEN_DOCUMENT_TREE.You can specify the directory it opens initially (which is only supported on Android O and above), making it easier for the user, but this still is not a very user friendly approach.

I'm wondering if there are any other user friendly solutions that anyone knows of? I don't understand why Android removed createAccessIntent, as it seems to be the most user friendly way.




回答2:


I found open source file manager. Looked at the code and finally found the solution.

Only works on Android N (7.0.0) (api 24) and above.

First get root path of SD card and show user permission dialog.

public void takeCardUriPermission(String sdCardRootPath) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            File sdCard = new File(sdCardRootPath);
            StorageManager storageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
            StorageVolume storageVolume = storageManager.getStorageVolume(sdCard);
            Intent intent = storageVolume.createAccessIntent(null);
            try {
                startActivityForResult(intent, 4010);
            } catch (ActivityNotFoundException e) {
            }
        }
    }

When user accepts the request, onActivityResult() gets triggered and we can save uri from intent data

protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 4010) {

            Uri uri = data.getData();

            grantUriPermission(getPackageName(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
                    Intent.FLAG_GRANT_READ_URI_PERMISSION);

            final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
                    Intent.FLAG_GRANT_READ_URI_PERMISSION);

            getContentResolver().takePersistableUriPermission(uri, takeFlags);
        }
    }

Now we can retrieve uri of SD card root and use it with Storage Access Framework

public Uri getUri() {
        List<UriPermission> persistedUriPermissions = getContentResolver().getPersistedUriPermissions();
        if (persistedUriPermissions.size() > 0) {
            UriPermission uriPermission = persistedUriPermissions.get(0);
            return uriPermission.getUri();
        }
        return null;
    }


来源:https://stackoverflow.com/questions/54945401/android-ask-write-to-sd-card-permission-dialog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!