如何在Android M上请求访问相册的权限?

21

我有一个应用程序,可以从相册选择图像,并使用ImageView在测试中显示它。我的问题是它在Android M上无法工作。我可以选择图片,但无法在测试中显示它们。他们说我需要请求访问Android M上的图像权限,但我不知道如何做。请帮忙。

2个回答

44

从Android 6.0(API级别23)开始,用户在应用程序运行时授予权限,而不是在安装应用程序时。

类型1-当您的应用程序请求权限时,系统会向用户显示一个对话框。当用户响应时,系统会调用您的应用程序的onRequestPermissionsResult()方法,并将用户响应传递给它。您的应用程序必须覆盖该方法以找出是否已授予权限。回调传递了您传递给requestPermissions()的相同请求代码。

private static final int PICK_FROM_GALLERY = 1;

ChoosePhoto.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick (View v){
    try {
        if (ActivityCompat.checkSelfPermission(EditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(EditProfileActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PICK_FROM_GALLERY);
        } else {
            Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
});


@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults)
    {
       switch (requestCode) {
            case PICK_FROM_GALLERY:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                  startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
                } else {
                    //do something like displaying a message that he didn`t allow the app to access gallery and you wont be able to let him select from gallery
                }
                break;
        }
    }

类型2- 如果您想在一个地方连续授予权限,则可以按照下面的链接进行操作:

Android 6.0多个权限

并在清单中添加所需的权限。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

注意- 如果Manifest.permission.READ_EXTERNAL_STORAGE导致错误,请将其替换为android.Manifest.permission.READ_EXTERNAL_STORAGE。

==> 如果您想了解更多关于运行时权限的内容,请访问以下链接

https://developer.android.com/training/permissions/requesting.html

-----------------------------更新 1--------------------------------

使用EasyPermissions进行运行时权限控制

EasyPermissions是一个包装库,可以简化针对Android M或更高版本的基本系统权限逻辑。

安装 在应用级别的gradle中添加依赖项

 dependencies {
// For developers using AndroidX in their applications
implementation 'pub.devrel:easypermissions:3.0.0'

// For developers using the Android Support Library
implementation 'pub.devrel:easypermissions:2.0.1'
}

您的Activity(或Fragment)覆盖了onRequestPermissionsResult方法:

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

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

请求权限

private static final int LOCATION_REQUEST = 222;

调用此方法

@AfterPermissionGranted(LOCATION_REQUEST)
private void checkLocationRequest() {
   String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION};
    if (EasyPermissions.hasPermissions(this, perms)) {
        // Already have permission, do the thing
        // ...
    } else {
        // Do not have permissions, request them now
        EasyPermissions.requestPermissions(this,"Please grant permission",
                LOCATION_REQUEST, perms);
    }
}

如果需要更精细的控制,您可以让您的Activity / Fragment实现PermissionCallbacks接口。

implements EasyPermissions.PermissionCallbacks

 @Override
public void onPermissionsGranted(int requestCode, List<String> list) {
    // Some permissions have been granted
    // ...
}

@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
    // Some permissions have been denied
    // ...
}

链接 -> https://github.com/googlesamples/easypermissions

-----------------------------KOTLIN的更新2--------------------------------

使用florent37运行时权限

安装 在应用级别的gradle中添加依赖项

依赖项

implementation 'com.github.florent37:runtime-permission-kotlin:1.1.2'

在代码中

        askPermission(
        Manifest.permission.CAMERA,
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    ) {
       // camera or gallery or TODO
    }.onDeclined { e ->
        if (e.hasDenied()) {
            AlertDialog.Builder(this)
                .setMessage(getString(R.string.grant_permission))
                .setPositiveButton(getString(R.string.yes)) { dialog, which ->
                    e.askAgain()
                } //ask again
                .setNegativeButton(getString(R.string.no)) { dialog, which ->
                    dialog.dismiss()
                }
                .show()
        }

        if (e.hasForeverDenied()) {
            e.goToSettings()
        }
    }

链接-> https://github.com/florent37/RuntimePermission

这是一个关于运行时权限的GitHub项目链接。

4
如果您拥有WRITE_EXTERNAL_STORAGE权限,就不需要READ_EXTERNAL_STORAGE权限。WRITE包含READ。 - The incredible Jan
@DileepPatel 对不起,我有点新手。您会把那段Java代码放在哪里?同时感谢您的回答。 - Laney Williams
2
根据警告块:https://developer.android.com/guide/topics/permissions/overview#perm-groups,如果这两个权限在未来的Android版本中分别属于不同分组,则可能会导致IOException。 - hidd

0
public void pickFile() {
        int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
                CAMERA);
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    getActivity(),
                    new String[]{CAMERA},
                    PERMISSION_CODE
            );
            return;
        }
        openCamera();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_CODE) {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCamera();
            }
        }
    }

    private void openCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, CAMERA_CODE);
    }


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接