1.概述
从Android6.0开始,安卓的权限不在跟之前一样只要安装就有权限。在6.0之前如果权限在AndroidManifest.xml声明,只要安装就取得了这些权限,也就是说当你点击确定安装时就已经授权。在6.0以后权限不仅需要在AndroidManifest.xml中声明, 还需要在使用时动态申请,用户确认授权后才可以进行操作。
权限又分为普通权限和危险权限,如连接网络不会对用户隐私造成泄露的基本权限为正常权限, 如读取用户通讯录则是危险权限。只有危险权限才需要动态申请,普通权限可以跟之前一样只在AndroidManifes.xml中声明即可。
1.1危险权限
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
group下面的同属于一个权限组。Android系统对所有的危险权限进行了分组,称为权限组 。属于同一组的危险权限将自动合并授予,用户授予应用某个权限组的权限,则应用将获得该权限组下的所有权限(前提是相关权限在 AndroidManifest.xml 中有声明)
1.2普通权限
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
普通权限只要在AndroidManifest中声明就行
2.申请权限
public class Permission extends Activity {
private final static int PREMISSION_REQUESTCONTACTS_CODE = 100; /**读取通讯录权限申请码**/
private Button btu;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
init();
}
private void init() {
btu = findViewById(R.id.button);
btu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkPermission();
}
});
}
/**
* 读取通讯录
*/
private void readContacts() {
//读取通讯录...
}
/**
* 6.0以上版本权限检查
*/
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { /**6.0以上才需要检查**/
/**
* 检查读取通讯录权限
*/
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
/**
* 如果没有授权就进行权限申请
* @param String[] permissions -可以把一组权限放一起申请
* @param int requestCode -本次申请的一个识别码,自定义,如果该类中有多次调用 *这个函数申请, 则调用时的requestCode不能相同。 否则无法识别是哪次申请
*/
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PREMISSION_REQUESTCONTACTS_CODE);
} else {
/**已经有权限就可以读取了**/
readContacts();
}
} else {
/**6.0以下版本不需要检查,可以直接读取**/
readContacts();
}
}
/****
* 申请权限的回掉方法
* @param requestCode 请求权限时传入的请求码,用于区别是哪一次请求的
* @param permissions String[] permissions 所请求的所有权限的数组
* @param grantResults 权限授予结果,和 permissions 数组参数中的权限一一对应,元素值为
* 两种情况, 授予: PackageManager.PERMISSION_GRANTED
* 拒绝: PackageManager.PERMISSION_DENIED
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
/***访问通讯录权限***/
case PREMISSION_REQUESTCONTACTS_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //同意权限
//同意了
readContacts();
} else { //拒绝权限
Toast.makeText(this, "没有读取通讯录的权限", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
上面是一个读取用户通讯录的例子,其中有两个重要的方法
申请
public final void requestPermissions(String[] permissions, int requestCode)
回调
void onRequestPermissionsResult(int requestCode,String[] permissions, int[] grantResults)