Android 6.0 以后最大的改变就是对于权限的管理这一块了,以前某个App 想使用什么权限 只要在 manifest 文件里面添加申请就可以了。
Android 6.0 以后不但要在manifest 里面添加运行的时候还会弹出一个对话框让用户选择是否赋予该权限。
新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。
Normal Permissions:
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
…….
Dangerous Permissions:
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
……
可以通过adb shell pm list permissions -d -g进行查看。
申请步骤:
1. 在AndroidManifest文件中添加需要的权限
2. 使用前检查
3. 申请权限
4. 处理申请回调
(一) 在AndroidManifest文件中添加需要的权限
这个和在6.0 以前是一样的。
(二)检查权限
6.0 以后 在 Activity 里面 有
checkSelfPermission(String permission)这个方法。
(其实是在ContextWrapper ,Activity 实现了 ContextWrapper )
也可以使用 ContextCompat.checkSelfPermission()这个方法。
ContextCompat 是在 support.v4 里面的。为了兼容6.0以前 版本,尽量使用 ContextCompat 检查权限。
(三)申请权限
6.0 以后 在Activity 也有
requestPermissions(String[] permissions, int requestCode);
(也是 ContextWrapper 里面的)
也可以通过
ActivityCompat.requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final int requestCode)
申请。
ActivityCompat 在 v4 里面,建议申请权限 都统一使用 v4 里面的组件申请管理。以免出现异常。
(四) 权限回调处理
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
申请权限时候 会弹出一个对话框,用户可以选择 同意或者不同意。
用户操作之后会回调到这个方法。
if (grantResults.length > 0&& grantResults[0] ==PackageManager.PERMISSION_GRANTED)
public static final int PERMISSION_DENIED = -1; //拒绝
public static final int PERMISSION_GRANTED = 0;//同意
我们可以根据不同的逻辑进行不同的处理。
(五) 简单封装
/**
* @Author linyong
* @Date 2016/10/5
* @Time 22:22
*/
public class BaseActivity extends Activity {
/**
* @param permissions
* @return
*/
protected boolean hasPermissions(String... permissions) {
boolean flag = true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return flag;
}
/**
*
* @param requestCode
* @param permissions
*/
protected void doRequestPermissions(int requestCode, String... permissions) {
ActivityCompat.requestPermissions( this,permissions, requestCode);
}
}
Fragment 也可以进行类似的封装。
(六) 高级封装
使用 PermissionGen(https://github.com/lovedise/PermissionGen),一个韩国人写的,通过反射简单的封装了权限的处理。
具体用法可以 看他的 sample。使用起来比较简单。
public class MainActivity extends AppCompatActivity {
@Bind(R.id.btn_contact)
Button btnContact;
@Bind(R.id.btn_camera)
Button btnCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
@OnClick({R.id.btn_contact, R.id.btn_camera})
public void open(View view) {
switch (view.getId()) {
case R.id.btn_contact:
PermissionGen.with(MainActivity.this)
.addRequestCode(100)
.permissions(
Manifest.permission.READ_CONTACTS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.WRITE_CONTACTS)
.request();
break;
case R.id.btn_camera:
PermissionGen.needPermission(this, 200, Manifest.permission.CAMERA);
break;
}
}
@PermissionSuccess(requestCode = 100)
public void test() {
startActivity(new Intent(this, ContactActivity.class));
}
@PermissionFail(requestCode = 100)
private void test2() {
Dlog.debug("contact fail");
}
@PermissionSuccess(requestCode = 200)
public void openCamera() {
Dlog.debug("open camera success");
}
@PermissionFail(requestCode = 200)
public void failOpenCamera() {
Toast.makeText(this, "Camera permission is not granted", Toast.LENGTH_SHORT).show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
}
更多精彩内容:
http://jblog.top/