在我重新启动Android M的应用程序之前,编写外部存储器是不行的。

时间:2022-06-04 21:14:11

I am having an issue with the new permission system. I modified my code to ask permission for WRITE_EXTERNAL_STORAGE. But my app cannot write to (or read from) the sd card until I restart application (of course I allowed it in the dialog). After that it's working fine.

我对新的权限系统有异议。我修改了代码以请求WRITE_EXTERNAL_STORAGE的权限。但是我的应用程序在我重新启动应用程序之前不能写(或读)sd卡(当然我在对话框中允许它)。在那之后一切正常。

It's not a new app, I already declared WRITE_EXTERNAL_STORAGE in the manifest, and on earlier systems it's working fine.

它不是一个新的应用程序,我已经在manifest中声明了WRITE_EXTERNAL_STORAGE,在早期的系统中它运行良好。

I'm using checkSelfPermission and requestPermissions methods and when I make a read or write request to the sd card I've got an exception that I don't have permission.

我使用了checkSelfPermission和requestPermissions方法,当我向sd卡发出读写请求时,我有一个异常,我没有权限。

Anyone has any idea what did I miss? Or did I run into a bug?

有人知道我错过了什么吗?或者我遇到了一个错误?

SDK version is the latest (updated a few hours ago), and I'm testing it on the emulator.

SDK版本是最新的(几个小时前更新过),我正在模拟器上测试它。

1 个解决方案

#1


3  

You need Callback when User allow WRITE_EXTERNAL_STORAGE permission from RuntimePermission dialog.

当用户允许从RuntimePermission对话框中允许WRITE_EXTERNAL_STORAGE权限时,需要回调。

First you need to implement OnRequestPermissionsResultCallback Listener of ActivityCompat class in your Activity and override void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) Method to check whether User is allowing or denying the permission

首先,需要在活动中实现ActivityCompat类的OnRequestPermissionsResultCallback侦听器,并覆盖void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,以检查用户是否允许或拒绝该权限

You can do like this:

你可以这样做:

int REQUEST_STORAGE = 1;

private void checkExternalStoragePermissions() {
    if (hasStoragePermissionGranted()) {
        //You can do what whatever you want to do as permission is granted
    } else {
        requestExternalStoragePermission();
    }
}

public boolean hasStoragePermissionGranted(){
        return  ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}

public void requestExternalStoragePermission() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
    }
}

Here is onRequestPermissionsResult() method will be called when user allow or deny Permission from Runtime permission dialog.

当用户允许或拒绝运行时权限对话框中的权限时,将调用onRequestPermissionsResult()方法。

You can also handle situation when User has checked never show Runtime Permission dialog.

您还可以处理用户已检查“从未显示运行时权限”对话框时的情况。

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {

        if (requestCode == REQUEST_STORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               //User allow from permission dialog
               //You can do what whatever you want to do as permission is granted
            } else if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivtity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
               //User has deny from permission dialog
               Snackbar.make(mainLayout, getResources().getString("Please enable storage permission"),Snackbar.LENGTH_INDEFINITE)
                      .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
                            }
                       })
                       .show();
            } else {
                // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
                Snackbar.make(mainLayout, getResources().getString("Please enable permission from settings"),Snackbar.LENGTH_INDEFINITE)
                     .setAction("OK", new View.OnClickListener() {
                           @Override
                           public void onClick(View view) {
                                Intent intent = new Intent();                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
                                intent.setData(uri);
                                startActivity(intent);
                            }
                       })
                       .show();
            }
        }
}

Here i have used Snackbar to show relevant message to user about Permission and mainLayout is id of Activity's Main Layout.

这里我用Snackbar向用户显示了相关的权限信息,主布局是活动主布局的id。

Hope it helps you.

希望它能帮助你。

#1


3  

You need Callback when User allow WRITE_EXTERNAL_STORAGE permission from RuntimePermission dialog.

当用户允许从RuntimePermission对话框中允许WRITE_EXTERNAL_STORAGE权限时,需要回调。

First you need to implement OnRequestPermissionsResultCallback Listener of ActivityCompat class in your Activity and override void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) Method to check whether User is allowing or denying the permission

首先,需要在活动中实现ActivityCompat类的OnRequestPermissionsResultCallback侦听器,并覆盖void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,以检查用户是否允许或拒绝该权限

You can do like this:

你可以这样做:

int REQUEST_STORAGE = 1;

private void checkExternalStoragePermissions() {
    if (hasStoragePermissionGranted()) {
        //You can do what whatever you want to do as permission is granted
    } else {
        requestExternalStoragePermission();
    }
}

public boolean hasStoragePermissionGranted(){
        return  ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}

public void requestExternalStoragePermission() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
    }
}

Here is onRequestPermissionsResult() method will be called when user allow or deny Permission from Runtime permission dialog.

当用户允许或拒绝运行时权限对话框中的权限时,将调用onRequestPermissionsResult()方法。

You can also handle situation when User has checked never show Runtime Permission dialog.

您还可以处理用户已检查“从未显示运行时权限”对话框时的情况。

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {

        if (requestCode == REQUEST_STORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               //User allow from permission dialog
               //You can do what whatever you want to do as permission is granted
            } else if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivtity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
               //User has deny from permission dialog
               Snackbar.make(mainLayout, getResources().getString("Please enable storage permission"),Snackbar.LENGTH_INDEFINITE)
                      .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
                            }
                       })
                       .show();
            } else {
                // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
                Snackbar.make(mainLayout, getResources().getString("Please enable permission from settings"),Snackbar.LENGTH_INDEFINITE)
                     .setAction("OK", new View.OnClickListener() {
                           @Override
                           public void onClick(View view) {
                                Intent intent = new Intent();                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
                                intent.setData(uri);
                                startActivity(intent);
                            }
                       })
                       .show();
            }
        }
}

Here i have used Snackbar to show relevant message to user about Permission and mainLayout is id of Activity's Main Layout.

这里我用Snackbar向用户显示了相关的权限信息,主布局是活动主布局的id。

Hope it helps you.

希望它能帮助你。