您的位置:首页 > 移动开发 > Android开发

关于Android6.0权限适配的问题

2016-12-08 21:11 351 查看

1.适配的背景

         
由于Android系统的碎片化严重,适配成了不可或缺的重要步骤;最近在项目中负责Android6.0的各种危险权限的适配,今天借此机会,向大家分享一下适配的原理。

2.蓝牙权限的适配

    有人会问为什么把蓝牙权限单独拿出来说,我只能回答,蓝牙权限有些特别,开启蓝牙搜索的时候,模糊定位也就开启了,而重要的是,模糊定位是一种危险的权限,在Android6.0中最好做做必要的适配工作;下面我将采取Android官方的方式进行蓝牙适配。

2.1 Android 6.0之前,使用蓝牙功能只需要在Manifest文件中添加如下权限:


<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

2.2 Android6.0及以上版本,使用蓝牙扫描,需要添加模糊定位的权限:


<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要进行适配。这里我引用了一个第三方适配框架AndPermission

compile '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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息