尽管获得许可,但写入外部存储器的权限仍被拒绝

Joh*_*ore 7 android android-permissions

我有一个Android 7.0测试设备和我的APK目标="targetSdkVersion 22",有:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

有:

final File f = new 
File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "DressUpBaby" + photonumber + ".png");
f.createNewFile();
Run Code Online (Sandbox Code Playgroud)

在这一点上,我得到警告:

W/System.err: java.io.IOException: Permission denied
Run Code Online (Sandbox Code Playgroud)

如何保存文件?当我在Eclipse上创建它时,这是有效的,但是现在我已经更新并转移到Android Studio,它似乎已经破坏了一些东西.

Joh*_*Doe 19

更新:请参阅Volker Voecking 的答案以获得更好的解决方案


编辑:对于那些没有时间寻找解决方案的人来说,这只是一种解决方法。*

如果即使授予权限并且您已经实施了权限检查,您仍然收到权限被拒绝的错误,

确保您不是针对 api 级别 29:

变化targetSdkVersioncompilesdkversion2928或任何其它较低的水平。


Vol*_*ing 12

如果您的目标是SDK 29并且在成功请求 WRITE_EXTERNAL_STORAGE 权限后仍然收到“权限被拒绝”错误,您应该添加

android:requestLegacyExternalStorage="true"

到 AndroidManifest.xml 中的应用程序定义。

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
    <application android:requestLegacyExternalStorage="true" ... >
      ...
    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

https://developer.android.com/training/data-storage/compatibility


fde*_*nte 9

如果您在API级别23或更高级别上运行应用程序,则必须在运行时请求权限.

请求许可:

String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(permissions, WRITE_REQUEST_CODE);
Run Code Online (Sandbox Code Playgroud)

然后处理结果:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
       case WRITE_REQUEST_CODE:
         if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
           //Granted.


         }
       else{
           //Denied.
         }
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问运行时请求权限 - Android Doc


小智 6

Android N引入了一种新的权限模型,该模型仅在应用程序真正需要它时才要求权限,而不是像以前那样在安装过程中要求权限。

使用以下代码请求权限

注意-还要在清单文件中添加所需的权限

如果您不是从Main Activity询问权限,请将该引用传递给上下文/活动

以下示例显示了询问写入外部存储的权限的示例,可以同时要求多个权限(不建议Google使用)。

public class MainActivity extends AppCompatActivity {
/**
 * Variables for requiesting permissions, API 25+
 */
private int requestCode;
private int grantResults[];


/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED ){
        //if you dont have required permissions ask for it (only required for API 23+)
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);


        onRequestPermissionsResult(requestCode,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},grantResults);
    }

    @Override // android recommended class to handle permissions
    public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {

            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                Log.d("permission","granted");
            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.uujm
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();

                //app cannot function without this permission for now so close it...
                onDestroy();
            }
            return;
        }

        // other 'case' line to check fosr other
        // permissions this app might request
    }
}
Run Code Online (Sandbox Code Playgroud)