Android 如何处理在某些预棉花糖设备上未自动授予的系统警报窗口权限
我一直收到一些小米设备(例如,运行API级别21的Mi 2)没有显示覆盖层的报告。我的应用程序以API 23为目标 关于这件事,有很多人。MIUI设备似乎在安装时不启用此权限(与其他棉花糖之前的设备不同) 不幸的是,Android 如何处理在某些预棉花糖设备上未自动授予的系统警报窗口权限,android,android-overlay,Android,Android Overlay,我一直收到一些小米设备(例如,运行API级别21的Mi 2)没有显示覆盖层的报告。我的应用程序以API 23为目标 关于这件事,有很多人。MIUI设备似乎在安装时不启用此权限(与其他棉花糖之前的设备不同) 不幸的是,Settings.canDrawOverlays()仅适用于Android 23+ 检查此权限是否尚未在棉花糖前启用的正确方法是什么 是否打算将用户带到相关的MUIU设置页面?也许:newintent(“android.settings.action.MANAGE\u OVERLAY
Settings.canDrawOverlays()
仅适用于Android 23+
newintent(“android.settings.action.MANAGE\u OVERLAY\u PERMISSION”,packageName)
但我没有办法测试这个public static void requestSystemAlertPermission(Activity context, Fragment fragment, int requestCode) {
if (VERSION.SDK_INT < VERSION_CODES.M)
return;
final String packageName = context == null ? fragment.getActivity().getPackageName() : context.getPackageName();
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + packageName));
if (fragment != null)
fragment.startActivityForResult(intent, requestCode);
else
context.startActivityForResult(intent, requestCode);
}
公共静态void requestSystemAlertPermission(活动上下文、片段片段、int requestCode){
if(VERSION.SDK\u INT
然后,在onActivityResult中,您可以检查是否授予了权限,例如:
@TargetApi(VERSION_CODES.M)
public static boolean isSystemAlertPermissionGranted(Context context) {
final boolean result = VERSION.SDK_INT < VERSION_CODES.M || Settings.canDrawOverlays(context);
return result;
}
@TargetApi(VERSION\u CODES.M)
已授予公共静态布尔值IsSystemAlertPermission(上下文){
最终布尔结果=VERSION.SDK_INT
编辑:目前,如果您将应用程序发布到Play Store,您的应用程序将自动获得此权限。你可以读到它。当我问起这个问题时,我认为它是Android本身的一部分,因为我认为我们需要的是为targetSdkVersion设定一个足够高的目标值。谷歌写给我()的是,他们希望避免流行应用程序出现问题
我建议正确处理此权限,即使您将自动获得此权限。关于在小米、魅族中搜索此问题,我找到了此。它工作得很好
public static boolean isMiuiFloatWindowOpAllowed(@NonNull Context context) {
final int version = Build.VERSION.SDK_INT;
if (version >= 19) {
return checkOp(context, OP_SYSTEM_ALERT_WINDOW); //See AppOpsManager.OP_SYSTEM_ALERT_WINDOW=24 /*@hide/
} else {
return (context.getApplicationInfo().flags & 1<<27) == 1;
}
}
public static boolean checkOp(Context context, int op, String packageName, int uid) {
final int version = Build.VERSION.SDK_INT;
if (version >= 19) {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
try {
return (AppOpsManager.MODE_ALLOWED == (Integer) ReflectUtils.invokeMethod(manager, "checkOp", op, uid, packageName));
} catch (Exception e) {
e.printStackTrace();
}
} else {
Flog.e("Below API 19 cannot invoke!");
}
return false;
}
公共静态布尔值IsmiIfLoatWindowOpallowed(@NonNull上下文){
最终int版本=Build.version.SDK\u int;
如果(版本>=19){
return checkOp(context,OP_SYSTEM_ALERT_WINDOW);//参见apppsmanager.OP_SYSTEM_ALERT_WINDOW=24/*@hide/
}否则{
return(context.getApplicationInfo().flags&1检查您是否具有drawOverlays权限使用此选项更安全:
@SuppressLint("NewApi")
public static boolean canDrawOverlayViews(Context con){
if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP){return true;}
try {
return Settings.canDrawOverlays(con);
}
catch(NoSuchMethodError e){
return canDrawOverlaysUsingReflection(con);
}
}
public static boolean canDrawOverlaysUsingReflection(Context context) {
try {
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
Class clazz = AppOpsManager.class;
Method dispatchMethod = clazz.getMethod("checkOp", new Class[] { int.class, int.class, String.class });
//AppOpsManager.OP_SYSTEM_ALERT_WINDOW = 24
int mode = (Integer) dispatchMethod.invoke(manager, new Object[] { 24, Binder.getCallingUid(), context.getApplicationContext().getPackageName() });
return AppOpsManager.MODE_ALLOWED == mode;
} catch (Exception e) { return false; }
}
以下是一步一步的处理方法:
首先在清单文件中授予以下权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
只需从LauncherActivity或任何需要的地方调用CheckDrawOverlypermission()
执行项目时,您将看到一个窗口,要求启用权限。在允许权限后,您将可以对此执行任何操作。您可以像这样检查权限:
boolean granted = activity.checkSelfPermission("android.permission.SYSTEM_ALERT_WINDOW") == PackageManager.PERMISSION_GRANTED;
你找到解决方案了吗?我面临着类似的问题。一些设备(小米、魅族)不允许“使用其他应用程序”默认情况下。我想我们永远不会知道你的答案是针对一般情况的,而这不是这个问题的内容。一些小米和魅族设备不是这样工作的。@MarkCarter好吧,这就是它应该如何工作的。你应该和他们谈一谈,问他们如何允许它工作。对。问题是关于如何为这些设备应用解决方法这种情况在许多设备上都会发生——无论人们如何成功地说服小米和魅族修复问题,其中许多设备可能永远不会收到更新。@MarkCarter好的。对不起,你是对的。我不知道它在那里是如何工作的。你可以使用try catch来尝试在这些情况下将内容放在顶部。还有此外,对于意图本身,您可以查看日志以了解需要哪些意图。如果活动是公开的,您也可以自己找到它(可能尝试“设置”应用程序).安卓6.0.1安全性异常漏洞有任何更新吗?targetSdk 25仍然会出现这种情况。您不理解这个问题,所以您的答案没有帮助。@Manifest,如何检测运行miui(如小米、魅族??getBaseTypeClass)的设备是否未编译,我做错了什么?
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission-sdk-23 android:name="android.permission.SYSTEM_ALERT_WINDOW" />
public final static int REQUEST_CODE = 65635;
public void checkDrawOverlayPermission() {
/** check if we already have permission to draw over other apps */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
/** if not construct intent to request permission */
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
/** request permission via start activity for result */
startActivityForResult(intent, REQUEST_CODE);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/** check if received result code
is equal our requested code for draw permission */
if (requestCode == REQUEST_CODE) {
// ** if so check once again if we have permission */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// continue here - permission was granted
goYourActivity();
}
}
}
}
boolean granted = activity.checkSelfPermission("android.permission.SYSTEM_ALERT_WINDOW") == PackageManager.PERMISSION_GRANTED;