Android 6.0動(dòng)態(tài)權(quán)限
android 6.0權(quán)限需要?jiǎng)討B(tài)申請(qǐng),分為兩種驾诈,普通權(quán)限和高危權(quán)限,主要目的是保護(hù)用戶隱私殉了。
新的權(quán)限機(jī)制更好的保護(hù)了用戶的隱私,Google將權(quán)限分為兩類喉刘,一類是Normal Permissions庐氮,這類權(quán)限一般不涉及用戶隱私吕粗,是不需要用戶進(jìn)行授權(quán)的,比如手機(jī)震動(dòng)旭愧、訪問網(wǎng)絡(luò)等颅筋;另一類是Dangerous Permission,一般是涉及到用戶隱私的输枯,需要用戶進(jìn)行授權(quán)议泵,比如讀取sdcard、訪問通訊錄等桃熄。
Normal Permissions(普通權(quán)限)
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_SHORTCUTINTERNETKILL_BACKGROUND_PROCESSESMODIFY_AUDIO_SETTINGSNFCREAD_SYNC_SETTINGSREAD_SYNC_STATSRECEIVE_BOOT_COMPLETEDREORDER_TASKSREQUEST_INSTALL_PACKAGESSET_ALARMSET_TIME_ZONESET_WALLPAPERSET_WALLPAPER_HINTSTRANSMIT_IRUNINSTALL_SHORTCUTUSE_FINGERPRINTVIBRATEWAKE_LOCKWRITE_SYNC_SETTINGS
Dangerous Permission(高危權(quán)限)
該權(quán)限分為一組一組先口,申請(qǐng)一組里其中一個(gè),相當(dāng)于擁有了一組里所有權(quán)限瞳收,但還是建議把需要的權(quán)限都申請(qǐng)一下碉京,避免因權(quán)限分組的變化,而引起不要的代碼修改
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
相應(yīng)的ApI
1.螟深、在AndroidManifest文件中添加需要的權(quán)限谐宙。
這個(gè)步驟和我們之前的開發(fā)并沒有什么變化,試圖去申請(qǐng)一個(gè)沒有聲明的權(quán)限會(huì)導(dǎo)致程序崩潰界弧。(動(dòng)態(tài)申請(qǐng)的權(quán)限也需要申明)
2.凡蜻、檢查權(quán)限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) !=
PackageManager.PERMISSION_GRANTED) {
//沒有權(quán)限
} else {
//有權(quán)限
}
這里涉及到一個(gè)API,ContextCompat.checkSelfPermission
垢箕,主要用于檢測(cè)某個(gè)權(quán)限是否已經(jīng)被授予划栓,方法返回值為PackageManager.PERMISSION_DENIED
或者PackageManager.PERMISSION_GRANTED
。當(dāng)返回DENIED就需要進(jìn)行申請(qǐng)授權(quán)了条获。
3忠荞、權(quán)限申請(qǐng)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
三個(gè)參數(shù),第一個(gè)上下文帅掘,第二個(gè)委煤,需要申請(qǐng)的權(quán)限,String數(shù)組锄开,可以進(jìn)行多權(quán)限同時(shí)申請(qǐng)素标,第三個(gè)參數(shù)為requestCode称诗,主要用于回調(diào)的時(shí)候檢測(cè)
4.萍悴、處理權(quán)限申請(qǐng)回調(diào)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callPhone();
} else {
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show(); }
return;
}
}
ok,對(duì)于權(quán)限的申請(qǐng)結(jié)果,首先驗(yàn)證requestCode定位到你的申請(qǐng)癣诱,然后驗(yàn)證grantResults對(duì)應(yīng)于申請(qǐng)的結(jié)果计维,這里的數(shù)組對(duì)應(yīng)于申請(qǐng)時(shí)的第二個(gè)權(quán)限字符串?dāng)?shù)組。如果你同時(shí)申請(qǐng)兩個(gè)權(quán)限撕予,那么grantResults的length就為2鲫惶,分別記錄你兩個(gè)權(quán)限的申請(qǐng)結(jié)果。如果申請(qǐng)成功实抡,就可以做你的事情了
5.欠母、再次申請(qǐng)
// 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.
}
注意事項(xiàng)
- 注意申請(qǐng)結(jié)果回調(diào)的數(shù)組進(jìn)行非空判斷
- 注意動(dòng)態(tài)申請(qǐng)的權(quán)限,也要申明吆寨,且申明不要使用
uses-permission-sdk-23這種方式申明的在底版本不可用 - 藍(lán)牙權(quán)限無需動(dòng)態(tài)赏淌,但需要位置權(quán)限,且位置權(quán)限需要?jiǎng)討B(tài)
實(shí)例一
java代碼
public class MainActivity extends AppCompatActivity {
private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testCall();
}
public void testCall() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)!=
PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_PHONE_STATE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
} else {
callPhone();
}
}
public void callPhone() {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + "10086");
intent.setData(data);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) !=
PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return; }
startActivity(intent);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
grantResults){super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
callPhone();
} else {
Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
return;
}
}
}
xml文件
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission-sdk-23 android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission-sdk-23 android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
實(shí)例二
Java代碼
public void get() {
int phone = ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_PHONE_STATE);
int fineLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
int coarseLocation = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION); int readStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); int writeStorage = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if ((phone != PackageManager.PERMISSION_GRANTED) ||(fineLocation !=
PackageManager.PERMISSION_GRANTED) ||(coarseLocation !=
PackageManager.PERMISSION_GRANTED) ||(readStorage !=
PackageManager.PERMISSION_GRANTED) ||(writeStorage !=
PackageManager.PERMISSION_GRANTED)){
Log.i("testCall", "testCall: into");
ActivityCompat.requestPermissions(this, new String[
{Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
init();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) {case MY_PERMISSIONS_REQUEST_LOCATION:Log.i("TAG-->", "onRequestPermissionsResult: " + grantResults.length); if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {init(); } else {// Permission Denied Toast.makeText(SplashActivity.this, "沒有權(quán)限啄清,本應(yīng)用無法使用", Toast.LENGTH_SHORT).show();
finishAll();
}
break;
}
}
xml文件
<!--Normal Permission-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<!--Dengon Permission-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>