關於Android6.0許可權適配的問題
阿新 • • 發佈:2019-02-03
1.適配的背景
由於Android系統的碎片化嚴重,適配成了不可或缺的重要步驟;最近在專案中負責Android6.0的各種危險許可權的適配,今天藉此機會,向大家分享一下適配的原理。2.藍芽許可權的適配
有人會問為什麼把藍芽許可權單獨拿出來說,我只能回答,藍芽許可權有些特別,開啟藍芽搜尋的時候,模糊定位也就開啟了,而重要的是,模糊定位是一種危險的許可權,在Android6.0中最好做做必要的適配工作;下面我將採取Android官方的方式進行藍芽適配。
2.1 Android 6.0之前,使用藍芽功能只需要在Manifest檔案中新增如下許可權:
<uses-permission android2.2 Android6.0及以上版本,使用藍芽掃描,需要新增模糊定位的許可權::name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />並且該許可權在使用時,需要動態的去申請。
2.3適配程式碼:
public class MainActivity extends效果圖:AppCompatActivity { private static final int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bluetooth).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { checkBluetoothPermission(); } }); } /* 校驗藍芽許可權 */ private void checkBluetoothPermission() { if (Build.VERSION.SDK_INT >= 23) { //校驗是否已具有模糊定位許可權 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION); } else { //具有許可權 connectBluetooth(); } } else { //系統不高於6.0直接執行 connectBluetooth(); } } /** * 對返回的值進行處理,相當於StartActivityForResult * @param requestCode * @param permissions * @param grantResults */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); doNext(requestCode, grantResults); } private void doNext(int requestCode, int[] grantResults) { if (requestCode == MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { //同意權限,做跳轉邏輯 connectBluetooth(); } else { // 許可權拒絕,提示使用者開啟許可權 denyPermission(); } } } private void denyPermission() { Toast.makeText(MainActivity.this,"藍芽許可權已經拒絕!",Toast.LENGTH_SHORT).show(); } private void connectBluetooth() { Toast.makeText(MainActivity.this,"連線藍芽成功!",Toast.LENGTH_SHORT).show(); } }
3.其他許可權的適配
3.1 除了藍芽許可權,還有相機,讀寫,定位等危險許可權在Android6.0要進行適配。這裡我引用了一個第三方適配框架AndPermissioncompile 'com.yanzhenjie:permission:1.0.2'3.2 適配步驟: ①在Activity中進行適配
public class PermissionActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.permission_activity); findViewById(R.id.test_calendar).setOnClickListener(this); findViewById(R.id.test_contacts_sms).setOnClickListener(this); } /** * 寫日曆 */ private void requestCalendarPermission(){ AndPermission.with(this) .requestCode(100) .permission(Manifest.permission.WRITE_CALENDAR) .send(); } @PermissionYes(100) private void getCalendarYes(){ Toast.makeText(this,"獲取日曆成功",Toast.LENGTH_SHORT).show(); } @PermissionNo(100) private void getCalendarNo(){ Toast.makeText(this,"獲取日曆失敗",Toast.LENGTH_SHORT).show(); } /** * 聯絡人,簡訊 */ private void requestContactsAndSMS(){ AndPermission.with(this) .requestCode(101) .permission(Manifest.permission.WRITE_CONTACTS,Manifest.permission.READ_SMS) .send(); } @PermissionYes(101) private void getContactsAndSMSYes(){ Toast.makeText(this,"獲取聯絡人,簡訊成功",Toast.LENGTH_SHORT).show(); } @PermissionNo(101) private void getContactAndSMSNo(){ Toast.makeText(this,"獲取聯絡人,簡訊失敗",Toast.LENGTH_SHORT).show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // super.onRequestPermissionsResult(requestCode, permissions, grantResults); AndPermission.onRequestPermissionsResult(this,requestCode,permissions,grantResults); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.test_calendar: requestCalendarPermission(); break; case R.id.test_contacts_sms: requestContactsAndSMS(); break; } } }②在Fragment中進行適配
public class PermissionFragment extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_layout); getSupportFragmentManager().beginTransaction().add(R.id.fragmentLayout,new FragmentPermission(),"permissionFragment").commit(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }然後在Fragment進行適配
public class FragmentPermission extends Fragment implements View.OnClickListener { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.permission_fragment,container,false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { view.findViewById(R.id.test_phone_state).setOnClickListener(this); view.findViewById(R.id.test_sensor).setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.test_phone_state: requestPhoneState(); break; case R.id.test_sensor: requestSensor(); break; } } /** * 感測器 */ private void requestSensor() { AndPermission.with(this) .requestCode(104) .permission(Manifest.permission.BODY_SENSORS) .send(); } @PermissionYes(104) private void getSensorYes(){ Toast.makeText(getContext(),"獲取感測器成功",Toast.LENGTH_SHORT).show(); } @PermissionNo(104) private void getSensorNo(){ Toast.makeText(getContext(),"獲取感測器失敗",Toast.LENGTH_SHORT).show(); } /** * 手機狀態 */ private void requestPhoneState() { AndPermission.with(this) .requestCode(103) .permission(Manifest.permission.READ_PHONE_STATE) .send(); } @PermissionYes(103) private void getPhoneStateYes(){ Toast.makeText(getContext(),"獲取手機狀態成功",Toast.LENGTH_SHORT).show(); } @PermissionNo(103) private void getPhoneStateNo(){ Toast.makeText(getContext(),"獲取手機狀態失敗",Toast.LENGTH_SHORT).show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { //super.onRequestPermissionsResult(requestCode, permissions, grantResults); AndPermission.onRequestPermissionsResult(this,requestCode,permissions,grantResults); } }③通過Listener 回撥成功或失敗事件(推薦)
public class ListenerActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listener_layout); findViewById(R.id.btn_request_location).setOnClickListener(this); } /** * 申請SD卡許可權 */ private void requestLocationPermission() { AndPermission.with(this) .requestCode(100) .permission(Manifest.permission.ACCESS_FINE_LOCATION) .rationale(rationaleListener) .send(); } private RationaleListener rationaleListener = new RationaleListener() { @Override public void showRequestPermissionRationale(int requestCode,final Rationale rationale) { new AlertDialog.Builder(ListenerActivity.this) .setTitle("友好提醒") .setMessage("您已拒絕過定位許可權,沒有定位許可權無法為您推薦附近妹子,請把定位許可權賜給我吧!") .setPositiveButton("好,給你", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); rationale.resume(); } }) .setNegativeButton("我拒絕", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); rationale.cancel(); } }).show(); } }; @PermissionYes(100) private void getLocationYes() { Toast.makeText(this, "獲取定位許可權成功", Toast.LENGTH_SHORT).show(); } @PermissionNo(100) private void getLocationNo() { Toast.makeText(this, "獲取定位許可權失敗", Toast.LENGTH_SHORT).show(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // 這個Activity中沒有Fragment,這句話可以註釋。 // super.onRequestPermissionsResult(requestCode, permissions, grantResults); AndPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_request_location: { requestLocationPermission(); break; } } } }好了,適配就說這麼多了,有木有很簡單啊!我是張星,歡迎您的關注,後期更精彩!原始碼地址:http://download.csdn.net/detail/zhangxing52077/9706043