api
checkPermission :检测权限是否授予isOpenGPS :是否打开gpsisNotifyEnabled :获取是否有通知权限isNotifyEnabled2 :获取是否有通知权限startSetting :跳转设置(应用信息),会开启一个新的进程(点回退会回到桌面),使用startActivityForResult不可靠,跳转就会触发onActivityResultstartSettingActivity:打开设置页面(应用信息),和App在同一个进程startNotifySetting :跳转到通知设置界面
utils
package com.kiwilss.lutils.utils.permissionimport android.annotation.SuppressLintimport android.app.Activityimport android.app.AppOpsManagerimport android.app.NotificationManagerimport android.content.Contextimport android.content.Intentimport android.content.pm.ApplicationInfoimport android.content.pm.PackageManagerimport android.location.LocationManagerimport android.net.Uriimport android.os.Buildimport android.provider.Settingsimport androidx.core.app.NotificationManagerCompatimport androidx.core.content.ContextCompatimport androidx.fragment.app.Fragmentimport java.lang.reflect.Fieldimport java.lang.reflect.Method/***@author kiwilss* @email kiwilss@163.com* @time 2022/7/1* @desc {权限相关工具类}*/object PermissionUtils {const val SETTING_REQUESTCODE = 6666private const val CHECK_OP_NO_THROW = "checkOpNoThrow"private const val OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION"/*** 检测是否有权限* @param context* @param permissions* @return*/fun checkPermission(context: Context?, vararg permissions: String?): Boolean {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {return true} else {if (context == null || permissions.isEmpty()) return falsefor (permisson in permissions) {permisson?.run {if (ContextCompat.checkSelfPermission(context,this) != PackageManager.PERMISSION_GRANTED) {return false}}}}return true}/*** 判断GPS是否开启,GPS或者AGPS开启一个就认为是开启的** @param context* @return true 表示开启*/fun isOpenGPS(context: Context?): Boolean {if (context == null) return falseval locationManager: LocationManager =context.getSystemService(Context.LOCATION_SERVICE) as LocationManager// 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)var gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)// 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)// boolean network = false;// if (locationManager != null) {// network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);// }return gps}/*** 跳转设置(应用信息),会开启一个新的进程(点回退会回到桌面),使用startActivityForResult不可靠,跳转就会触发onActivityResult** @param context*/fun startSetting(context: Context?) {context?.run {try {val intent = Intent()intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)intent.action = "android.settings.APPLICATION_DETAILS_SETTINGS"intent.data = Uri.fromParts("package", packageName, null)startActivity(intent)} catch (e: Exception) {e.printStackTrace()}}}/*** 打开设置页面(应用信息),和App在同一个进程** @param context*/fun startSettingActivity(context: Activity?, requestCode: Int = SETTING_REQUESTCODE) {if (context == null) returntry {val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" +context.packageName))intent.addCategory(Intent.CATEGORY_DEFAULT)context.startActivityForResult(intent,requestCode) //这里的requestCode和onActivityResult中requestCode要一致} catch (e: Exception) {e.printStackTrace()}}/*** 打开设置页面(应用信息),和App在同一个进程** @param context*/fun startSettingActivity(fragment: Fragment?, requestCode: Int = SETTING_REQUESTCODE) {if (fragment == null) returnval context = fragment.context ?: returntry {val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" +context.packageName))intent.addCategory(Intent.CATEGORY_DEFAULT)fragment.startActivityForResult(intent,requestCode) //这里的requestCode和onActivityResult中requestCode要一致} catch (e: Exception) {e.printStackTrace()}}/*** 跳转到通知设置界面*/@SuppressLint("ObsoleteSdkInt")fun startNotifySetting(context: Context?) {if (context == null) return// vivo 点击设置图标>加速白名单>我的app// 点击软件管理>软件管理权限>软件>我的app>信任该软件var appIntent = context.packageManager.getLaunchIntentForPackage("com.iqoo.secure")if (appIntent != null) {context.startActivity(appIntent)return}// oppo 点击设置图标>应用权限管理>按应用程序管理>我的app>我信任该应用// 点击权限隐私>自启动管理>我的appappIntent = context.packageManager.getLaunchIntentForPackage("com.oppo.safe")if (appIntent != null) {context.startActivity(appIntent)return}val intent = Intent()if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGSintent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS}intent.putExtra("app_package", context.packageName)intent.putExtra("app_uid", context.applicationInfo.uid)} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGSintent.data = Uri.fromParts("package", context.packageName, null)} else {intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)intent.action = Intent.ACTION_VIEWintent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails")intent.putExtra("com.android.settings.ApplicationPkgName", context.packageName)}context.startActivity(intent)}/*** 获取是否有通知权限** @param context* @return*/fun isNotifyEnabled(context: Context?): Boolean {if (context == null) return falsereturn NotificationManagerCompat.from(context).areNotificationsEnabled()}/*** 获取是否有通知权限** @param context* @return*/fun isNotifyEnabled2(context: Context): Boolean {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {isEnableV26(context)} else {isEnabledV19(context)}}/*** 8.0以下判断** @param context api19 4.4及以上判断* @return*/private fun isEnabledV19(context: Context): Boolean {val mAppOps: AppOpsManager =context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManagerval appInfo: ApplicationInfo = context.applicationInfoval pkg = context.applicationContext.packageNameval uid: Int = appInfo.uidvar appOpsClass: Class<*>? = nulltry {appOpsClass = Class.forName(AppOpsManager::class.java.name)val checkOpNoThrowMethod: Method = appOpsClass.getMethod(CHECK_OP_NO_THROW,Integer.TYPE, Integer.TYPE, String::class.java)val opPostNotificationValue: Field = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION)val value = opPostNotificationValue.get(Int::class.java) as Intreturn checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) as Int ===AppOpsManager.MODE_ALLOWED} catch (e: java.lang.Exception) {e.printStackTrace()}return false}/*** 8.0及以上通知权限判断** @param context* @return*/private fun isEnableV26(context: Context): Boolean {val appInfo: ApplicationInfo = context.applicationInfoval pkg = context.applicationContext.packageNameval uid: Int = appInfo.uidreturn try {val notificationManager: NotificationManager =context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManagerval sServiceField: Method =notificationManager.javaClass.getDeclaredMethod("getService")sServiceField.setAccessible(true)val sService: Any = sServiceField.invoke(notificationManager)val method: Method = sService.javaClass.getDeclaredMethod("areNotificationsEnabledForPackage",String::class.java,Integer.TYPE)method.setAccessible(true)method.invoke(sService, pkg, uid) as Boolean} catch (e: java.lang.Exception) {true}}}
ktx
package com.kiwilss.lutils.utils.permissionimport android.app.Activityimport android.content.Contextimport androidx.fragment.app.Fragment/***@author kiwilss* @email kiwilss@163.com* @time 2022/7/1* @desc {权限扩展工具类}*//*** 检测是否有权限** @param permission* @return*/fun Context?.checkPermission(vararg permission: String?) = PermissionUtils.checkPermission(this,*permission)/*** 是否打开gps** @return*/fun Context?.isOpenGPS() = PermissionUtils.isOpenGPS(this)/***跳转设置(应用信息),会开启一个新的进程(点回退会回到桌面),使用startActivityForResult不可靠,跳转就会触发onActivityResult*/fun Context?.startSetting() = PermissionUtils.startSetting(this)/*** 打开设置页面(应用信息),和App在同一个进程** @param requestCode*/fun Activity?.startSettingActivity(requestCode: Int = PermissionUtils.SETTING_REQUESTCODE) =PermissionUtils.startSettingActivity(this, requestCode)/*** 打开设置页面(应用信息),和App在同一个进程** @param requestCode*/fun Fragment?.startSettingActivity(requestCode: Int = PermissionUtils.SETTING_REQUESTCODE) =PermissionUtils.startSettingActivity(this, requestCode)/***打开通知设置界面*/fun Context?.startNotifySetting() = PermissionUtils.startNotifySetting(this)/***获取通知权限是否打开*/fun Context?.isNotifyEnabled() = PermissionUtils.isNotifyEnabled(this)
申请权限
申请单个权限
PermissionsHelper.init(this).requestEachPermissions(ACCESS_FINE_LOCATION, new IPermissionListenerWrap.IEachPermissionListener() {@Overridepublic void onAccepted(Permission permission) {if (permission.granted){//同意ALog.i(LUtils.tag(this),"grant");}else if (permission.shouldShowRequestPermissionRationale){//拒绝ALog.i(LUtils.tag(this),"reject");}else {//拒绝并不再显示ALog.i(LUtils.tag(this),"reject and not show");}}});
申请多个权限
PermissionsHelper.init(this).requestPermissions(new String[]{ACCESS_FINE_LOCATION, RECORD_AUDIO}, new IPermissionListenerWrap.IPermissionListener() {@Overridepublic void onAccepted(boolean isGranted, boolean allShould, List<String> rejects, List<String> shoulds) {if (isGranted){//全部同意ALog.i(LUtils.tag(this),"grant");}else if (allShould){//有权限不同意ALog.i(LUtils.tag(this),"reject:" + rejects);}else {//有权限不同意,并且设置了不再显示ALog.i(LUtils.tag(this),"reject and not show : " + shoulds);}}});
