manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- 静态声明+动态申请存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- andorid 30和30之后 静态声明+动态申请存储权限 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- andorid 30之前 静态声明的蓝牙权限 -->
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission
android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- 使用蓝牙还需要 静态声明+动态申请位置(前台位置)权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 后台位置权限(暂未确定使用的场景) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- andorid 30之后 静态声明+动态申请的蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
PermissionUtil
package com.yunqi.thamtu.utils
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Environment
import android.provider.Settings
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.lib.common.constant.Constants
import com.lib.common.util.SharedPre
/**
* @Author: Jin
* @Description: 权限管理类
* @CreateDate: 2023/2/28 14:09
*/
class PermissionUtil {
companion object {
/**
* Android 6(23)及以上系统,需要动态申请 存储权限集合
*/
private val PERMISSION_STORAGE_ARRAY = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
/**
* Android 11(30)及以上系统,需要动态申请 存储权限
*/
private val PERMISSION_MANAGE_STORAGE = arrayOf(Manifest.permission.MANAGE_EXTERNAL_STORAGE)
/**
* Android 6及以上系统,需要动态申请 位置权限集合
*/
private val PERMISSION_LOCATION_ARRAY = arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
/**
* Android 12及以上系统,需要动态申请 新增的蓝牙权限集合
*/
private val PERMISSION_BLUETOOTH_ARRAY = arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT)
/**
* 全部权限集合
*/
val PERMISSION_ARRAY = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.BLUETOOTH_CONNECT)
const val REQUEST_CODE = 101
/**
* 检测存储权限是否授权
*/
@JvmStatic
fun checksStoragePermission(context: Context): Boolean {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
// Android 11(30)及以上系统,无需动态申请该权限
return true
}
return checksPermission(context, PERMISSION_STORAGE_ARRAY)
}
/**
* 检测蓝牙权限是否授权
*/
@JvmStatic
fun checksBluetoothPermission(context: Context): Boolean {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S) {
// Android 12(31)及以下系统,无需动态申请权限
return true
}
return checksPermission(context, PERMISSION_BLUETOOTH_ARRAY)
}
/**
* 检测位置权限是否授权
*/
@JvmStatic
fun checksLocationPermission(context: Context): Boolean {
return checksPermission(context, PERMISSION_LOCATION_ARRAY)
}
/**
* 检测android 11 存储权限是否授权
*/
@JvmStatic
fun checksManageStoragePermission(): Boolean {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R) {
// Android 11(30)及以下系统,无需动态申请权限
return true
}
return Environment.isExternalStorageManager()
}
private fun checksPermission(context: Context, array: Array<String>): Boolean {
var granted = true
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
// Android 6(23)及以下系统,无需动态申请权限
return granted
}
for (permission in array) {
if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
granted = false
}
}
return granted
}
/**
* 申请存储权限
*/
@JvmStatic
fun requestStoragePermission(context: Activity) {
requestPermissions(context, PERMISSION_STORAGE_ARRAY)
}
/**
* 申请android 11 存储权限
*/
@JvmStatic
fun requestManageStoragePermission(context: Activity) {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent?.data = Uri.parse("package:" + context.packageName)
context.startActivity(intent)
}
/**
* 申请蓝牙权限
*/
@JvmStatic
fun requestBluetoothPermission(context: Activity) {
requestPermissions(context, PERMISSION_BLUETOOTH_ARRAY)
}
private fun requestPermissions(context: Activity, array: Array<String>) {
ActivityCompat.requestPermissions(context, array, REQUEST_CODE)
}
@JvmStatic
fun containsBluetooth(permission: String): Boolean {
return listOf(*PERMISSION_BLUETOOTH_ARRAY).contains(permission)
}
/**
* 拒绝存储权限
* @return true已拒绝 false 未拒绝
*/
@JvmStatic
fun deniedStoragePermission(): Boolean {
return SharedPre.getInstance().getBoolean(Constants.PERMISSION_STORAGE_DENIED)
}
@JvmStatic
fun deniedBluetoothPermission(): Boolean {
return SharedPre.getInstance().getBoolean(Constants.PERMISSION_BLUETOOTH_DENIED)
}
}
}
MainActivity
/**
* 申请系统权限流程:
* 1.用户点击,
* 2.检测权限,拒绝
* 3.弹窗提示用户申请权限
* 4.用户点击ok,判断 用户拒绝=0,动态申请系统权限
* 5.用户拒绝权限,申请系统权限失败,记录用户拒绝+1
* end
* 6.用户再次点击,
* 7.检测权限,拒绝
* 8.弹窗提示用户申请权限
* 9.用户点击ok,判断 用户拒绝>0,跳转系统设置页,让用户手动开启权限
* end
* 后续用户点击 重复6~9
*/
private void initBluetoothPermission(){
if (!PermissionUtil.checksBluetoothPermission(this)) {
DialogManager.getInstance().showDialog(getString(R.string.bluetooth_tip1), this, () -> {
if (PermissionUtil.deniedBluetoothPermission()) {
// 用户已拒绝权限,跳转系统设置页
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right,R.anim.slide_out_left);
} else {
// 用户未拒绝权限,弹框动态申请权限
PermissionUtil.requestBluetoothPermission(this);
}
});
return;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (PermissionUtil.REQUEST_CODE == requestCode) {
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
LogUtil.i(TAG, "permission: " + permission + ",grantResult:" + grantResult);
if (PermissionUtil.containsBluetooth(permission)) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
SharedPre.getInstance().putBoolean(Constants.PERMISSION_BLUETOOTH_DENIED, true);
} else {
// 同意权限,扫码蓝牙
scanDevice();
}
}
}
}
}
//*********************************************************************
// 判断是否需要动态申请android 11 以上存储权限
if (!PermissionUtil.checksManageStoragePermission()) {
DialogManager.getInstance().showDialog(getString(R.string.storage_tip1), this, () ->
PermissionUtil.requestManageStoragePermission(this));
return;
}
// 判断是否需要动态申请存储权限
if (!PermissionUtil.checksStoragePermission(this)) {
DialogManager.getInstance().showDialog(getString(R.string.storage_tip1), this, () -> {
if (PermissionUtil.deniedStoragePermission()) {
// 用户已拒绝权限,跳转系统设置页
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.setData(Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
overridePendingTransition(R.anim.slide_in_right,R.anim.slide_out_left);
} else {
// 用户未拒绝权限,弹框动态申请权限
PermissionUtil.requestStoragePermission(this);
}
});
return;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (PermissionUtil.REQUEST_CODE == requestCode) {
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
LogUtil.i(TAG, "permission: " + permission + ",grantResult:" + grantResult);
if (grantResult == PackageManager.PERMISSION_DENIED) {
SharedPre.getInstance().putBoolean(com.lib.common.constant.Constants.PERMISSION_STORAGE_DENIED, true);
}
}
}
}