Oreo (WRITE EXTERNAL STORAGE) Permission

后端 未结 7 1623
攒了一身酷
攒了一身酷 2020-12-29 23:47

According to \"developer.android.com\"

If the app targets Android 8.0 (API level 26), the system grants only 
READ_EXTERNAL_STORAGE at that time; however, i         


        
相关标签:
7条回答
  • 2020-12-29 23:59

    You are correct in adding the permissions to the manifest:

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

    For versions of Lollipop and higher, you need to also request the permissions at runtime. To solve this problem, I created a new method requestAppPermission that I call when the main activity is created. This method runs only for Lollipop and higher, and returns early otherwise:

    private void requestAppPermissions() {
        if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return;
        }
    
        if (hasReadPermissions() && hasWritePermissions()) {
            return;
        }
    
        ActivityCompat.requestPermissions(this,
                new String[] {
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                }, REQUEST_WRITE_STORAGE_REQUEST_CODE); // your request code
    }
    
    private boolean hasReadPermissions() {
        return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
    }
    
    private boolean hasWritePermissions() {
        return (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
    }
    

    I call this method in the activity's onCreate:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Other things
        requestAppPermissions();
    }
    

    On first load, this will prompt the user to accept permissions.

    Then, before you run any code that needs to read and write to storage, you can check these permissions, either by storing the values or running those checks again using methods hasReadPermissions() and hasWritePermissions() defined above.

    0 讨论(0)
  • 2020-12-30 00:03

    Use this

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:remove="android:maxSdkVersion"/>

    instead of

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

    Some of your third party libraries are override maxSdkVersion like com.vungle:publisher-sdk-android, to finding them just check the Merged Manifest below of your manifest screen. see this

    For SDK 29 and Later

    If you are still having issue to accessing external storage, consider using android:requestLegacyExternalStorage="true" in your <application> tag of your manifest.

    0 讨论(0)
  • 2020-12-30 00:07

    UPDATE: See this answer for a better solution


    EDIT: This is not a solution, just a quick workaround.

    If you get permission denied error even when the permissions are granted and you already implemented permission checks,

    make sure you're not targetting api level 29:

    Change targetSdkVersion and compilesdkversion from 29 to 28 or any other lower level.

    0 讨论(0)
  • 2020-12-30 00:09

    For Oreo,

    you need to explicitly do a READ_EXTERNAL_STORAGE request (by code) even if you have already requested and is granted the WRITE_EXTERNAL_STORAGE permission, and vis versa.

    prior to this, READ_EXTERNAL_STORAGE is automatically granted when WRITE_EXTERNAL_STORAGE is granted.

    so what you need to do, is to

    1) ask for WRITE permission in your codes.

    2) when user grants the WRITE permission, ask again for READ permission - this will be automatically granted (you will get an exception if you do not ask for a READ explicitly)

    The changes for Oreo doesn't make much sense to me (no idea why do we need to ask for a permission that is automatically granted), but that is what it is.

    https://developer.android.com/about/versions/oreo/android-8.0-changes.html#rmp

    0 讨论(0)
  • 2020-12-30 00:19

    You have to grant permissions at runtime on Marshmallow or higher. Sample snippet :

    private static final int REQUEST_WRITE_STORAGE = 112;

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                boolean hasPermission = (ContextCompat.checkSelfPermission(getBaseContext(),
                        Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
                if (!hasPermission) {
                    ActivityCompat.requestPermissions(SplashScreen.this,
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                    Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.RECORD_AUDIO, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.INTERNET
                            },
                            REQUEST_WRITE_STORAGE);
                }else{ startMainActivity(); }
            }
    

    Hope it helps.

    0 讨论(0)
  • 2020-12-30 00:23

    Actually, It was an external problem. One of App Libs I'm using request the WRITE_EXTERNAL_PERMISSION with android:maxSdkVersion. So when merging with my Manifest it will remove the permission for the whole application.

    The Solution is to add:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/> 
    
    0 讨论(0)
提交回复
热议问题