上篇文章:http://blog.csdn.net/u013408979/article/details/52289534
只简单的解决能在android6.0运行,但没有根本的解决问题。
下面介绍解决方法:
参考
http://xdeveloper.cn/gai-jin-ban-android6-0quan-xian-gua-pei-bi-ni-xiang-de-huan-yao-jian-dan/
权限的适配主要就是两步,一是请求权限,二是系统应答,主要在这两个地方进行封装。主要使用第三方库PermissionsDispatcher
(1)项目build.gradle 中添加
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
(2)app的 build.gradle 中添加
apply plugin:’android-apt’
apt ‘com.github.hotchemi:permissionsdispatcher-processor:2.1.3’
1.定义PermissionHandler用于权限回调,权限通过、权限拒绝、权限不再询问三种情况
public abstract class PermissionHandle{
//权限通过
public abstract void onGranted();
//权限拒绝
public abstract void onDenied();
//权限不在询问
public boolean onNeverAsk(){
return false;
}
}
2、请求权限
private PermissionHandle mHandle;
/**
* 请求权限
* @param permissions 权限列表
* @param handle 回调
*/
protected void requestPermission(String[] permissions,PermissionHandle handle){
if (PermissionUtil.hasSelfPermissions(this,permissions)){
handle.onGranted();
}else{
mHandle=handle;
ActivityCompat.requestPermissions(this,permissions,001);
}
}
注:PermissionUtil是PermissionsDispatcher中使用的工具类
public final class PermissionUtil {
private static SimpleArrayMap<String,Integer> MIN_SDK_PERMISSIONS;
static {
MIN_SDK_PERMISSIONS=new SimpleArrayMap<>(8);
MIN_SDK_PERMISSIONS.put("com.android.voicemail.permission.ADD_VOICEMAIL",14);
MIN_SDK_PERMISSIONS.put("android.permission.BODY_SENSORS",20);
MIN_SDK_PERMISSIONS.put("android.permission.READ_CALL_LOG",16);
MIN_SDK_PERMISSIONS.put("android.permission.READ_EXTERNAL_STORAGE",16);
MIN_SDK_PERMISSIONS.put("android.permission.USE_SIP",9);
MIN_SDK_PERMISSIONS.put("android.permission.WRITE_CALL_LOG",16);
MIN_SDK_PERMISSIONS.put("android.permission.SYSTEM_ALERT_WINDOW", 23);
MIN_SDK_PERMISSIONS.put("android.permission.WRITE_SETTINGS", 23);
}
private static volatile int targetSdkVersion=-1;
public PermissionUtil() {
}
//检查所有的权限是否被授权
public static boolean verifyPermissions(int... grantResults){
if (grantResults.length==0){
return false;
}
for (int result : grantResults) {
if (result!= PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
//如果活动或片段可以访问所有给定的权限,则返回true
public static boolean hasSelfPermissions(Context context,String... permissions){
for (String permission : permissions) {
if (permissionExists(permission)&&hasSelfPermissions(context,permission)){
return false;
}
}
return true;
}
//如果在这个SDK版本存在的权限,则返回true
private static boolean permissionExists(String permission) {
Integer minVersion = MIN_SDK_PERMISSIONS.get(permission);
return minVersion == null || Build.VERSION.SDK_INT >= minVersion;
}
//确定上下文访问给定的权限。
private static boolean hasSelfPermission(Context context, String permission) {
try {
return PermissionChecker.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
} catch (RuntimeException t) {
return false;
}
}
//检查需要给予的权限,显示理由
public static boolean shouldShowRequestPermissionRationale(Activity activity, String... permissions) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
return true;
}
}
return false;
}
//获取sdk 版本
@TargetApi(Build.VERSION_CODES.DONUT)
public static int getTargetSdkVersion(Context context) {
try {
if (targetSdkVersion != -1) {
return targetSdkVersion;
}
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
targetSdkVersion = packageInfo.applicationInfo.targetSdkVersion;
} catch (PackageManager.NameNotFoundException ignored) {
}
return targetSdkVersion;
}
}
3.权限结果处理
/**
* 权限请求结果
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (mHandle==null){
return;
}
if (PermissionUtil.shouldShowRequestPermissionRationale(this,permissions)){
if (!mHandle.onNeverAsk()){
Toast.makeText(this, "权限已被拒绝,请在设置-应用-权限中打开", Toast.LENGTH_SHORT).show();
}
}else{
mHandle.onDenied();
}
}
4、调用
public class PermissionActivity extends XPermissionActivity implements View.OnClickListener {
private Context mContext;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
mContext=PermissionActivity.this;
findViewById(R.id.btn_camera).setOnClickListener(this);
findViewById(R.id.btn_call).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_camera:
requestPermission(new String[]{Manifest.permission.CAMERA}, new PermissionHandle() {
@Override
public void onGranted() {
Intent intent = new Intent(); //调用照相机
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
}
@Override
public void onDenied() {
Toast.makeText(PermissionActivity.this, "拒绝", Toast.LENGTH_SHORT).show();
}
});
break;
case R.id.btn_call:
requestPermission(new String[]{Manifest.permission.CALL_PHONE}, new PermissionHandle() {
@Override
public void onGranted() {
/*Intent i=new Intent(Intent.ACTION_CALL,Uri.parse("tel:10086"));
startActivity(i);*/
Uri uri = Uri.parse("tel:10086");
Intent intent = new Intent(Intent.ACTION_DIAL, uri);
startActivity(intent);
}
@Override
public void onDenied() {
Toast.makeText(PermissionActivity.this, "拒绝", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onNeverAsk() {
new AlertDialog.Builder(mContext)
.setTitle("权限申请")
.setMessage("在设置-应用-权限中开始电话权限,以保证功能的正常使用")
.setPositiveButton("去开启",new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
Intent i=new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri=Uri.fromParts("package",getPackageName(),null);
i.setData(uri);
startActivity(i);
dialog.dismiss();
}
})
.setNegativeButton("取消",null)
.setCancelable(false)
.show();
return true;
}
});
break;
}
}
}