1.概述
大家有没有遇到过这种情况,开发app的时候发现自己手机选择照片是正常的,测试的时候他那边的一台手机怎么搞都不行,然后查看版本之后才发现是6.0的手机。
在Google发出Android 6.0版本以后,对权限这边做了很大的变动,其中之一就是权限处理。那么在6.0及以上版本我们的危险权限都需要在运行的时候去申请,之前都是在清单文件中配置即可,现在就不行了需要用代码动态申请。不然程序在执行时没有相应的权限就会无响应甚至导致APP崩溃。
2.权限分类及区别
Google对于Android 6.0 系统权限分为两类:
1.Normal Permission(普通权限):这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如访问网络,访问WIFI,访问蓝牙等权限;
看一些普通权限:
android.permission.ACCESS LOCATIONEXTRA_COMMANDS
android.permission.ACCESS NETWORKSTATE
android.permission.ACCESS NOTIFICATIONPOLICY
android.permission.ACCESS WIFISTATE
android.permission.ACCESS WIMAXSTATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE NETWORKSTATE
android.permission.CHANGE WIFIMULTICAST_STATE
android.permission.CHANGE WIFISTATE
android.permission.CHANGE WIMAXSTATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND STATUSBAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET PACKAGESIZE
android.permission.INTERNET
android.permission.KILL BACKGROUNDPROCESSES
android.permission.MODIFY AUDIOSETTINGS
android.permission.NFC
android.permission.READ SYNCSETTINGS
android.permission.READ SYNCSTATS
android.permission.RECEIVE BOOTCOMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST INSTALLPACKAGES
android.permission.SET TIMEZONE
android.permission.SET_WALLPAPER
android.permission.SET WALLPAPERHINTS
android.permission.SUBSCRIBED FEEDSREAD
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE SYNCSETTINGS
2.Dangerous Permission(危险权限):这类权限一般是涉及到用户的安全和隐私问题,需要用户进行授权,比如读取SD卡,访问相册,拨打电话等权限。
看几组危险权限:
SMS(短信)
SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE(存储卡)
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
CONTACTS(联系人)
READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
PHONE(手机)
READ_PHONE_STATE
READ_CALL_LOG
WRITE_CALL_LOG
CALL_PHONE
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
CALENDAR(日历)
READ_CALENDAR
WRITE_CALENDAR
CAMERA(相机)
CAMERA
LOCATION(位置)
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
SENSORS(传感器)
BODY_SENSORS
MICROPHONE(麦克风)
RECORD_AUDIO
普通权限和危险权限的区别:
- 普通权限:单条权限,可以直接在Manifests文件中进行注册从而获取权限,在程序初次安装启动时直接获取用户权限
- 危险权限:成组授予,当授予一组中任何一个权限时,该组内其他的权限也会自动被授予。不仅需要在Manifests文件中进行注册还要在代码中进行动态申请。
3.代码变化过程
3.1.6.0之前是这样写(已电话拨打为例):
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + mPhone);
intent.setData(data);
startActivity(intent);
3.2.6.0以后就不行啦,我们需要去检测该权限有没有被用户授予过,如果没有则需要申请打电话权限,如果有授予过可以直接拨打电话。
ContextCompat.checkSelfPermission:检测权限
ActivityCompat.requestPermissions:申请权限
/**
* 1.ContextCompat.checkSelfPermission 检查权限
* 2.方法返回值有两种:
* PackageManager.PERMISSION_GRANTED 有该权限
* PackageManager.PERMISSION_DENIED 没有该权限
*/
if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED){
/**
* ActivityCompat.requestPermissions 申请权限
* 参数1:Context ,
* 参数2:用户需要申请的权限字符串数组,
* 参数3:是请求码 主要用来处理用户选择后的返回结果 onRequestPermissionsResult返回会掉方法
*/
ActivityCompat.requestPermissions(this,new String[]{"Manifest.permission.CALL_PHONE"},CALL_PHONE_REQUEST_CODE);
}else {
// 有该权限,直接打电话
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + mPhone);
intent.setData(data);
startActivity(intent);
}
3.3. 回调处理:如果用户同意或是拒绝那么会回调onRequestPermissionsResult(),注意:不是onActivityResult()
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == CALL_PHONE_REQUEST_CODE){
if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授予了权限
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + mPhone);
intent.setData(data);
startActivity(intent);
} else {
//用户拒绝了权限
Toast.makeText(this,"权限被您拒绝了",Toast.LENGTH_SHORT).show();
}
}
}
4.简单事例:
public class TextActivity extends AppCompatActivity {
// 打电话权限申请的请求码
private static final int CALL_PHONE_REQUEST_CODE = 0x0011;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text);
}
/**
* 检察权限
*/
public void phoneClick(View view) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "申请权限", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE);
} else {
callPhone();
}
}
/**
* 拨打电话
**/
private void callPhone() {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:130****7927");
intent.setData(data);
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == CALL_PHONE_REQUEST_CODE){
if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 授予权限
callPhone();
} else {
// 拒绝权限
Toast.makeText(this,"权限被您拒绝了",Toast.LENGTH_SHORT).show();
}
}
}
}
网友评论