【发布时间】:2020-10-19 17:41:25
【问题描述】:
我有这个应用程序,它将选择图像到画廊并使用 Imageview 将其显示给测试。我的问题是它不能在 Android M 上运行。我可以选择图像,但不会在我的测试中显示。他们说我需要请求权限才能访问 android M 上的图像,但不知道如何。请帮忙。
【问题讨论】:
我有这个应用程序,它将选择图像到画廊并使用 Imageview 将其显示给测试。我的问题是它不能在 Android M 上运行。我可以选择图像,但不会在我的测试中显示。他们说我需要请求权限才能访问 android M 上的图像,但不知道如何。请帮忙。
【问题讨论】:
从 Android 6.0(API 级别 23)开始,用户在应用运行时授予应用权限,而不是在安装应用时。
Type 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;
}
}
Type 2-如果你想在一个地方背靠背授予运行时权限,那么你可以点击下面的链接
Android 6.0 multiple permissions
并在清单中为您的要求添加权限
<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 或更高版本时简化基本系统权限逻辑。
安装 在 App 级别的 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 接口。
实现 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
--------------更新 2 对于 KOTLIN----------- ---------------------
使用 florent37 的运行时权限
安装在App级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()
}
}
【讨论】:
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" />
【讨论】: