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

android M SYSTEM_ALERT_WINDOW权限问题

2016-10-18 17:22 609 查看
public class ForceOfflineReceiver extends BroadcastReceiver {

@Override
public void onReceive(final Context context,  Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle("Warning");
dialogBuilder.setMessage("You are forced to be offline.Please try to login again,");
dialogBuilder.setCancelable(true);
dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
forceAllActivity(context);
}
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//因为dialog需要依附于activity显示,但是我们现在是在receiver中所以不能正常显示,我们可以通过TYPE_SYSTEM_ALERT将其声明成系统提示框然后就可以正常显示了,但是需要在manifest里面进行权限声明
alertDialog.show();
}

private void forceAllActivity(final Context context){
ActivityCollector.finishAll();
Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//在非activity中启动一个activity需要添加一个flag让其运行在一个新的堆栈中
context.startActivity(intent);
}
}


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


在android M 以前,这样做是可以正常显示的,但是在android M 后运行就会报错,说我们没有权限,官方解释如下:

SYSTEM_ALERT_WINDOW

Added in API level 1
String SYSTEM_ALERT_WINDOW
Allows an app to create windows using the type TYPE_SYSTEM_ALERT, shown on top of all other apps. Very few apps should use this permission; these windows are intended for system-level interaction with the user.

Note: If the app targets API level 23 or higher, the app user must explicitly grant this permission to the app through a permission management screen. The app requests the user's approval by sending an intent with action ACTION_MANAGE_OVERLAY_PERMISSION. The app can check whether it has this authorization by calling Settings.canDrawOverlays().

Protection level: signature

Constant Value: "android.permission.SYSTEM_ALERT_WINDOW"


ACTION_MANAGE_OVERLAY_PERMISSION

Added in API level 23
String ACTION_MANAGE_OVERLAY_PERMISSION
Activity Action: Show screen for controlling which apps can draw on top of other apps.

In some cases, a matching Activity may not exist, so ensure you safeguard against this.

Input: Optionally, the Intent's data URI can specify the application package name to directly invoke the management GUI specific to the package name. For example "package:com.my.app".

Output: Nothing.

Constant Value: "android.settings.action.MANAGE_OVERLAY_PERMISSION"


即我们需要用户的再次确认才可以使用这个权限,再次确认的方式有两种

一、用户手动确认:Settings – Apps – setting – Draw over other apps – 选择需要权限的app – enable

二、代码中动态跳转到相应界面,让用户开启

public static int OVERLAY_PERMISSION_REQUEST_CODE = 8888;

public void requestDrawOverLays() {
if (!Settings.canDrawOverlays(LoginActivity.this)) {
//没有权限,给出提示,并跳转界面然用户enable
Toast.makeText(this, "can not DrawOverlays", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + LoginActivity.this.getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQUEST_CODE);
} else {
//有权限,正常逻辑走起
Toast.makeText(this, "Permission Allowed", Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE) {
if (!Settings.canDrawOverlays(this)) {
// 还是没权限,说明用户不想给你这个权限,可以弹框说明
Toast.makeText(this, "Permission Denieddd by user.Please Check it in Settings", Toast.LENGTH_SHORT).show();
} else {
//用户已经给了权限,正常逻辑走起
Toast.makeText(this, "Permission Allowed", Toast.LENGTH_SHORT).show();
}
}
}


参考链接如下:

https://developer.android.com/reference/android/Manifest.permission.html

https://developer.android.com/reference/android/provider/Settings.html#ACTION_MANAGE_OVERLAY_PERMISSION

http://www.jianshu.com/p/2746a627c6d2
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐