Android - ask write to SD card permission dialog

前端 未结 2 1115
栀梦
栀梦 2021-01-06 02:51

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 fo

相关标签:
2条回答
  • 2021-01-06 03:24

    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;
        }
    
    0 讨论(0)
  • 2021-01-06 03:31

    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.

    0 讨论(0)
提交回复
热议问题