理解android6权限方法
我正在尝试从Gallery中获取图像并将其设置为imageview,但在Android 6中存在一些权限问题。下面是请求许可的方法。我应该请求读取外部存储还是写入外部存储 以下是我迄今为止所做的工作:理解android6权限方法,android,android-6.0-marshmallow,runtime-permissions,Android,Android 6.0 Marshmallow,Runtime Permissions,我正在尝试从Gallery中获取图像并将其设置为imageview,但在Android 6中存在一些权限问题。下面是请求许可的方法。我应该请求读取外部存储还是写入外部存储 以下是我迄今为止所做的工作: private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1; public void getPermissionToReadExternalStorage() { if (ContextCompat.c
private static final int READ_CONTACTS_PERMISSIONS_REQUEST = 1;
public void getPermissionToReadExternalStorage() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (shouldShowRequestPermissionRationale(
Manifest.permission.READ_EXTERNAL_STORAGE)) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_CONTACTS_PERMISSIONS_REQUEST);
}}}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults){
// Make sure it's our original READ_CONTACTS request
if (requestCode == READ_CONTACTS_PERMISSIONS_REQUEST) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getActivity(), "Read Contacts permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), "Read Contacts permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
现在,单击“我的侦听器”从库中拾取数据:
pro.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
if (android.os.Build.VERSION.SDK_INT >= 23) {
getPermissionToReadExternalStorage();
if (getPermissionToReadExternalStorage () this???? <==)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
} else {
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0);
}}
});
return v;
}
pro.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Intent Intent=新Intent(Intent.ACTION\u PICK,android.provider.MediaStore.Images.Media.EXTERNAL\u CONTENT\u URI);
intent.setType(“image/*”);
如果(android.os.Build.VERSION.SDK_INT>=23){
GetPermissionToReaderExternalStorage();
如果(GetPermissionToReaderExternalStoreage(),则此???编辑
我已经重写了代码,并在另一个答案中发布
旧答案:
是的,你每次都必须检查并请求许可
通常我会这样编写代码:
private int requestPermissionCode;
private Runnable requestPermissionRunnable;
private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) {
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissionCode = requestCode;
requestPermissionRunnable = codeToRun;
requestPermissions(new String[]{requestPermission},
requestCode);
}
} else {
codeToRun.run();
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
if (requestCode == requestPermissionCode) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestPermissionRunnable != null)
requestPermissionRunnable.run();
} else {
Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() {
@Override
public void run() {
// your code here
}
});
然后像这样运行它:
private int requestPermissionCode;
private Runnable requestPermissionRunnable;
private void runPermissionCode(String requestPermission, int requestCode, Runnable codeToRun) {
if (android.os.Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissionCode = requestCode;
requestPermissionRunnable = codeToRun;
requestPermissions(new String[]{requestPermission},
requestCode);
}
} else {
codeToRun.run();
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
if (requestCode == requestPermissionCode) {
if (grantResults.length == 1 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestPermissionRunnable != null)
requestPermissionRunnable.run();
} else {
Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
runPermissionCode(Manifest.permission.READ_EXTERNAL_STORAGE, READ_CONTACTS_PERMISSIONS_REQUEST, new Runnable() {
@Override
public void run() {
// your code here
}
});
我确信这不是一个最好的方法,但至少它提供了一个请求权限的可能性,并使操作更容易。因此我完全重写了请求权限的代码。
现在,它支持请求多个权限并以正确的结果运行代码。
它也适用于PremarshAllow设备,因此在这种情况下,您不必检查和复制代码
首先,使用此代码创建一个Activity类(您可以扩展任何需要的活动,例如AppCompatActivity):
您的活动和片段应该扩展这些类,而不是标准类
现在,您可以通过调用以下方法请求权限:
requestPermissions(int requestCode, String[] requestPermissions, PermissionListener permissionListener)
如果应用程序需要权限才能工作,则应调用此方法并指定消息,说明为什么需要权限
requestPermissions(int requestCode, String[] requestPermissions, String message, PermissionListener permissionListener)
不要错误调用默认方法,即
// DON'T USE THIS ONE!
requestPermissions(String[] requestPermissions, int requestCode)
// DON'T USE THIS ONE!
以下是请求联系人的示例:
private void requestAndLoadContacts() {
String[] permissions = new String[]{Manifest.permission.READ_CONTACTS};
requestPermissions(REQUEST_PERMISSIONS_CONTACTS, permissions, "Read contacts permission is required for the app to work!", new PermissionListener() {
@Override
public boolean onResult(int requestCode, String[] requestPermissions, int[] grantResults) {
// Check if the requestCode is ours
if (requestCode == REQUEST_PERMISSIONS_CONTACTS) {
// Check if the permission is correct and is granted
if (requestPermissions[0].equals(Manifest.permission.READ_CONTACTS) && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
// Calling a method to actually load the contacts
loadContacts();
} else {
// Permission not granted
Toast.makeText(MainActivity.this, "Access denied!", Toast.LENGTH_SHORT).show();
}
return true;
}
return false;
}
});
}
注:
在实现PermissionListener时,当请求代码正确时,不要忘记返回true,否则PermissionListener将不会从ArrayList中删除,并且很可能会出现小内存泄漏。初始化您的权限
private static final int INITIAL_REQUEST = 1337;
private static final int GET_ACCOUNTS = INITIAL_REQUEST+2;
private static final int LOCATION_REQUEST =INITIAL_REQUEST+3;
private static final String[] INITIAL_PERMS = {
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION
};
检查设备并请求权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!canAccessAccounts()|| !canAccessLocation() ||!canAccessInternet()) {
requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
}
}
是否授予检查权限
private boolean canAccessAccounts() {
return (hasPermission(Manifest.permission.GET_ACCOUNTS));
}
private boolean canAccessLocation() {
return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean canAccessInternet() {
return (hasPermission(Manifest.permission.INTERNET));
}
private boolean hasPermission(String perm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}
return (true);
}
void UpdatePermissions(){
canAccessInternet();
canAccessLocation();
canAccessInternet();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
UpdatePermissions();
switch(requestCode) {
case GET_ACCOUNTS:
if (canAccessAccounts()) {
}
else {
}
break;
case LOCATION_REQUEST:
if (canAccessLocation()) {
}
else {
}
break;
case INITIAL_REQUEST:
if(canAccessInternet()){
}else {
}
break;
}
}
在RequestPermissionsResult上更新权限并检查权限的方法
private boolean canAccessAccounts() {
return (hasPermission(Manifest.permission.GET_ACCOUNTS));
}
private boolean canAccessLocation() {
return (hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}
private boolean canAccessInternet() {
return (hasPermission(Manifest.permission.INTERNET));
}
private boolean hasPermission(String perm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return (PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}
return (true);
}
void UpdatePermissions(){
canAccessInternet();
canAccessLocation();
canAccessInternet();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
UpdatePermissions();
switch(requestCode) {
case GET_ACCOUNTS:
if (canAccessAccounts()) {
}
else {
}
break;
case LOCATION_REQUEST:
if (canAccessLocation()) {
}
else {
}
break;
case INITIAL_REQUEST:
if(canAccessInternet()){
}else {
}
break;
}
}
但是你如何使用它?或者当用户要点击某个东西时你如何使用它?这样你就可以完成你的任务了。在我的情况下,你会如何使用它?或者任何其他情况下,只需向我展示带有侦听器的代码之类的东西。谢谢,伙计。我明白了。好主意!有可能改进使用处理旧android版本的ContextCompat吗?比谢谢!但是“permissionListeners.remove(permissionListener);”不会抛出ConcurrentModificationException吗?@Gilian会的。从那以后,我对这段代码做了很多改进。很快就会更新答案。@geNia很好的解决方案,我喜欢使用shouldShowRequestPermissionRegulation()方法来使用消息,再次感谢!