详细介绍可以看看大神的文章http://blog.csdn.net/lmj623565791/article/details/50709663 ,本文只是记录一些使用逻辑,以后再用直接复制了(本人比较懒)
一.权限动态申请总体逻辑如下:(复制大神的)
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
private TextView mTvDeviceId;
/**
* 前面是点击了一个button,开始申请权限
*/
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {//没有权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {//说明被拒绝过,需要解释原因
ExplainFragment.getInstance().show(getFragmentManager(), "");
} else {//没有权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, MY_REQUEST_CODE);
}
} else {//有权限,读取id
mTvDeviceId.setText(getIMEI());
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == MY_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mTvDeviceId.setText(getIMEI());
} else {
Toast.makeText(this, "不好意思,您没有权限查看...", Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
//解释为什么要打开权限
public static class ExplainFragment extends DialogFragment {
public static ExplainFragment getInstance() {
return new ExplainFragment();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage("请允许该app获取您的设备标识权限,这样能更好的为您服务")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_PHONE_STATE}, MY_REQUEST_CODE);
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(), "不好意思,您没有权限查看...", Toast.LENGTH_SHORT).show();
}
})
.create();
}
}
public String getIMEI() {
return ((TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
}
三.fragment 中如何申请权限呢?其实略有不同,思路一样
/**
* 前面一样也是只有一个button点击开始请求权限
*/
private void requestPermission() {
if(ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){//没有权限
if(FragmentCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_PHONE_STATE)){//被拒绝过
ExplainFragment.getInstance().show(getFragmentManager(),"");
}else{//第一次请求
FragmentCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE},MY_REQUEST_CODE);
}
}else{//有权限
mTvDeviceId.setText(getIMEI());
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode==MY_REQUEST_CODE){
if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
mTvDeviceId.setText(getIMEI());
}else{
Toast.makeText(getActivity(),"对不起,您没有权限读取",Toast.LENGTH_SHORT).show();
}
}
}
public static class ExplainFragment extends DialogFragment {
public static ExplainFragment getInstance() {
return new ExplainFragment();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setMessage("请允许该app获取您的设备标识权限,这样能更好的为您服务")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
FragmentCompat.requestPermissions(permissionFragment, new String[]{Manifest.permission.READ_PHONE_STATE}, MY_REQUEST_CODE);
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getActivity(), "不好意思,您没有权限查看...", Toast.LENGTH_SHORT).show();
}
})
.create();
}
}
public String getIMEI() {
return ((TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
}
这里需要注意的是fragment不要倒v4包里的,还有就是builde文件要加入依赖:
compile "com.android.support:support-v13:24.1.1"
四,是不是很简单,然并卵,我觉得每次都要写这么一堆东西是不是很不爽?如果要是所有页面都要有申请权限的那还不累死,所以需要封装了,如下:
package com.example.permissiondemo;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;
/**
* Created by jeffzhang on 2016/11/24.
*/
public class RequestPermissionActivity extends FragmentActivity {
/**
* 请求权限code
*/
private static final int MY_REQUEST_CODE = 1;
/**
* 获取所有权限的集合
*/
private static final String REQUEST_PERMISSIONS_LIST = "requestpermission";
/**
* 向用户解释需要权限
*/
private static final String EXPLAIN_OPEN_PERMISSION = "explain";
private String[] mRequestPermissionList;
private String mExplainOpenPermissionMsg;
/**
* @param activity 启动此activity的activity
* @param requestPermissions 需要申请的权限数据
* @param explainMsg 再次申请权限的解释用语
* @return
*/
public static Intent getIntent(Activity activity, String[] requestPermissions, String explainMsg) {
Intent intent = new Intent(activity, RequestPermissionActivity.class);
intent.putExtra(REQUEST_PERMISSIONS_LIST, requestPermissions);
intent.putExtra(EXPLAIN_OPEN_PERMISSION, explainMsg);
return intent;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
mRequestPermissionList = intent.getStringArrayExtra(REQUEST_PERMISSIONS_LIST);
mExplainOpenPermissionMsg = intent.getStringExtra(EXPLAIN_OPEN_PERMISSION);
requestPermission();
}
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {//没有权限
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE)) {//说明被拒绝过,需要解释原因
if (null != mExplainOpenPermissionMsg) {
ExplainFragment.getInstance(mExplainOpenPermissionMsg).show(getFragmentManager(), "");
} else {
setResult(RESULT_CANCELED);
finish();
}
} else {//没有被拒绝过
ActivityCompat.requestPermissions(this, mRequestPermissionList, MY_REQUEST_CODE);
}
} else {//有权限
setResult(RESULT_OK);
finish();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == MY_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setResult(RESULT_OK);
finish();
} else {
setResult(RESULT_CANCELED);
finish();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public static class ExplainFragment extends DialogFragment {
private static final String EXPLAIN_MSG = "explainmsg";
public static ExplainFragment getInstance(String explainMsg) {
ExplainFragment explainFragment = new ExplainFragment();
Bundle bundle = new Bundle();
bundle.putString(EXPLAIN_MSG, explainMsg);
explainFragment.setArguments(bundle);
return explainFragment;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog alertDialog = new AlertDialog.Builder(getActivity())
.setMessage(getArguments().getString(EXPLAIN_MSG))
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_PHONE_STATE}, MY_REQUEST_CODE);
}
})
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getActivity().setResult(RESULT_CANCELED);
getActivity().finish();
}
})
.create();
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.setCancelable(false);
alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
return true;
} else {
return false;
}
}
});
return alertDialog;
}
}
}
注意点就是这个activity的theme要单独设置一下,要设置成透明的,因为我们这个activity没有任何布局,所以透明的
那么怎使用呢?很简单:
startActivityForResult(RequestPermissionActivity.getIntent(this,new String[]{Manifest.permission.READ_PHONE_STATE},"请允许该app获取您的设备标识权限,这样能更好的为您服务"),1);
然后
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==1&&resultCode==RESULT_OK){//获取权限了
mTvDeviceId.setText(getIMEI());
}else{//没有获取成功
Toast.makeText(this,"不好意思您没有权限",Toast.LENGTH_SHORT).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
大功告成,就这么简单。。。
最后源码已经上传到资源中,可以去下载