一、Android 6.0权限介绍
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。 Android 6.0系统6.0以前,所有的权限,访问网络的权限,读取SD卡的权限,访问通讯录,拨打电话的权限都在安装的时候系统授予了要安装的应用。在系统运行的时候不需要对权限做任何的处理。用户在安装的时候一般都不知道这些权限用在了什么地方,这样做很不安全。一个应用很容易在一个Service中读取用户所有的通讯录信息发送到服务器上。Android 6.0后的动态权限让我们的系统更加安全,牺牲了用户的方便性,得到的是安全。下图是Android 6.0系统对拨打电话和管理电话权限组的询问。
Android 6.0把权限分为两种:Normal Permissions(正常权限)和Dangerous Permissions(危险权限)。其中危险权限又进行了分类。把所有的危险权限分成了几个组。正常权限不会给用户的隐私带来不安全,不需要动态申请,在应用安装的时候就已经被授予了。危险权限需要动态处理,只有用户批准了这些权限,应用才能被授予这些权限。
所有的普通权限:
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_NETWORK_STATE
- ACCESS_NOTIFICATION_POLICY
- ACCESS_WIFI_STATE
- BLUETOOTH
- BLUETOOTH_ADMIN
- BROADCAST_STICKY
- CHANGE_NETWORK_STATE
- CHANGE_WIFI_MULTICAST_STATE
- CHANGE_WIFI_STATE
- DISABLE_KEYGUARD
- EXPAND_STATUS_BAR
- GET_PACKAGE_SIZE
- INSTALL_SHORTCUT
- INTERNET
- KILL_BACKGROUND_PROCESSES
- MODIFY_AUDIO_SETTINGS
- NFC
- READ_SYNC_SETTINGS
- READ_SYNC_STATS
- RECEIVE_BOOT_COMPLETED
- REORDER_TASKS
- REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
- REQUEST_INSTALL_PACKAGES
- SET_ALARM
- SET_TIME_ZONE
- SET_WALLPAPER
- SET_WALLPAPER_HINTS
- TRANSMIT_IR
- UNINSTALL_SHORTCUT
- USE_FINGERPRINT
- VIBRATE
- WAKE_LOCK
- WRITE_SYNC_SETTINGS
所有的危险权限:
二、Android 6.0+危险权限的动态处理
在开发应用的时候不管是正常权限还是危险权限都必须在应用的Manifest.xml文件中声明。如果设备运行的是Android 5.1或更低的系统,或者应用的目标SDK小于23,那么在Manifest.xml文件中列出的危险权限在安装的时候用户必须接受,要不应用没法安装。如果设备运行的是Android 6.0或更高的系统,或者应用的目标SDK大于等于23,那么在Manifest.xml文件中列出的危险权限,会在应用运行的时候被用户授予或拒绝。开发者需要在代码中对危险权限进行处理。
public class MainActivity extends AppCompatActivity {
final public static int REQUEST_CODE_ASK_CALL_PHONE = 123;
private String mMobile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
onCallWrapper("12345678912");
}
});
}
public void onCallWrapper(String mobile) {
this.mMobile = mobile;
int checkCallPhonePermisssion = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (checkCallPhonePermisssion != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHON