关于android 6.0 运行时权限 ,目前有五种处理方法
危险权限和权限组
权限组 | 危险权限 |
---|---|
CALENDAR | READ_CALENDAR |
WRITE_CALENDAR | |
CONTACTS | READ_CONTACTS |
WRITE_CONTACTS | |
GET_ACCOUNTS | |
LOCATION | ACCESS_FINE_LOCATION |
ACCESS_COARSE_LOCATION | |
MICROPHONE | RECORD_AUDIO |
PHONE | READ_PHONE_STATE |
CALL_PHONE | |
READ_CALL_LOG | |
WRITE_CALL_LOG | |
ADD_VOICEMAIL | |
USE_SIP | |
PROCESS_OUTGOING_CALLS | |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS |
RECEIVE_SMS | |
USE_SIP | |
READ_SMS | |
RECEIVE_WAP_PUSH | |
RECEIVE_MMS | |
STORAGE | READ_EXTERNAL_STORAGE |
WRITE_EXTERNAL_STORAGE |
gitHub 已上传三种实现方案的Demo
https://github.com/pengchengfuGit/PermissionsDemo
1… 采用不理睬的方式将项目的targetSdkVersion 设置为22及以下,
如果设备运行的是 Android 5.1(API 级别 22)或更低版本,
并且应用的 targetSdkVersion 是 22 或更低版本,则系统会在安装时要求用户授予权限。
再次强调,系统只告诉用户应用需要的权限组,而不告知具体权限。
2… 采用系统原生API处理,google原生方案。(采用原生方案,后面会更新。。。。)
3… easypermissions 基于注解,采用反射,影响性能
package com.example.administrator.permissionstest;
import android.Manifest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import pub.devrel.easypermissions.EasyPermissions;
public class EasyActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
private static final int RC_CALL_PHONE = 0;
private String TAG= "EasyActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common);
TextView permissions = (TextView) findViewById(R.id.permissions);
permissions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String[] perms = {Manifest.permission.CALL_PHONE};
EasyPermissions.requestPermissions(EasyActivity.this, "直接拨打电话的权限",
RC_CALL_PHONE, perms);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//Forward results to EasyPermissions
Toast.makeText(getApplicationContext(), "onRequestPermissionsResult requestCode" + requestCode, Toast.LENGTH_LONG).show();
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, List perms) {
if (perms != null && perms.size() > 0)
for (String item : perms) {
Log.d(TAG,"onPermissionsGranted "+item);
}
}
@Override
public void onPermissionsDenied(int requestCode, List perms) {
if (perms != null && perms.size() > 0)
for (String item : perms) {
Log.d(TAG,"onPermissionsDenied "+item);
}
}
}
4… permissionsdispatcher 基于注解,编译生成类,无反射,不影响性能
package com.example.administrator.permissionstest;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.OnShowRationale;
import permissions.dispatcher.PermissionRequest;
import permissions.dispatcher.RuntimePermissions;
@RuntimePermissions
public class DispatcherActivity extends AppCompatActivity {
private String TAG = "DispatcherActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common);
TextView permissions = (TextView) findViewById(R.id.permissions);
permissions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "showCameraWithCheck ");
DispatcherActivityPermissionsDispatcher.showCameraWithCheck(DispatcherActivity.this);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// NOTE: delegate the permission handling to generated method
DispatcherActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
@NeedsPermission(Manifest.permission.CAMERA)
void showCamera() {
Log.d(TAG, "showCamera ");
Intent intent = new Intent(); //调用照相机
intent.setAction("android.media.action.STILL_IMAGE_CAMERA");
startActivity(intent);
}
@OnShowRationale(Manifest.permission.CAMERA)
void showRationaleForCamera(final PermissionRequest request) {
Log.d(TAG, "showRationaleForCamera ");
new AlertDialog.Builder(this)
.setMessage("使用此功能需要打开照相机的权限")
.setPositiveButton("允许", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
request.proceed();
}
})
.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
request.cancel();
}
})
.show();
}
@OnPermissionDenied(Manifest.permission.CAMERA)
void showDeniedForCamera() {
Log.d(TAG, "showDeniedForCamera ");
Toast.makeText(this, "你拒绝了权限,该功能不可用", Toast.LENGTH_SHORT).show();
}
@OnNeverAskAgain(Manifest.permission.CAMERA)
void showNeverAskForCamera() {
Log.d(TAG, "showNeverAskForCamera ");
Toast.makeText(this, "用户设置不再询问权限申请", Toast.LENGTH_SHORT).show();
// Toast.makeText(this, " R.string.permission_camera_neverask", Toast.LENGTH_SHORT).show();
}
}
5… rxpermissions 基于Rxjava, Rxjava1.0版本跟2.0版本都有(本文采用Rxjava2.0)
package com.example.administrator.permissionstest;
import android.Manifest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.tbruyelle.rxpermissions2.Permission;
import com.tbruyelle.rxpermissions2.RxPermissions;
import io.reactivex.functions.Consumer;
import pub.devrel.easypermissions.EasyPermissions;
public class RxActivity extends AppCompatActivity{
private String TAG= "RxActivity";//READ_EXTERNAL_STORAGE
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_common);
TextView permissions = (TextView) findViewById(R.id.permissions);
permissions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// RxPermissions rxPermission = new RxPermissions(RxActivity.this);
requestPermission();
}
});
}
public void requestPermission(){
RxPermissions rxPermissions = new RxPermissions(this);
rxPermissions.requestEach(Manifest.permission.READ_EXTERNAL_STORAGE).subscribe(new Consumer() {
@Override
public void accept(Permission permission) throws Exception {
if (permission.granted) {
// 用户已经同意该权限
Toast.makeText(getApplicationContext(),"用户已经同意该权限",Toast.LENGTH_SHORT).show();
Log.d(TAG, permission.name + " is granted.");
} else if (permission.shouldShowRequestPermissionRationale) {
// 用户拒绝了该权限,没有选中『不再询问』(Never ask again),那么下次再次启动时,还会提示请求权限的对话框
Toast.makeText(getApplicationContext(),"用户拒绝了该权限",Toast.LENGTH_SHORT).show();
Log.d(TAG, permission.name + " is denied. More info should be provided.");
} else {
// 用户拒绝了该权限,并且选中『不再询问』
Toast.makeText(getApplicationContext(),"用户拒绝了该权限,并且选中『不再询问』",Toast.LENGTH_SHORT).show();
Log.d(TAG, permission.name + " is denied.");
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//Forward results to EasyPermissions
Toast.makeText(getApplicationContext(), "onRequestPermissionsResult requestCode" + requestCode, Toast.LENGTH_LONG).show();
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
}
PS:本人写的一个小Demo 里面包含了easypermissions,permissionsdispatcher ,rxpermissions
三种插件的用法
permissions Demo
Google官方github Demo