WindowManager 在 Android OS 6 个特定设备上崩溃
WindowManager crash on Android OS 6 specific devices
我正在使用一项服务来创建 facebook Messenger 风格的聊天头。我的代码适用于 android OS 到 6(棉花糖)的设备。但是在 M 设备上,代码因 windowManager.addView()
上的运行时异常而崩溃
代码如下:
windowManager = (WindowManager) ctx.getSystemService(WINDOW_SERVICE);
callHead = new ImageView(this);
callHead.setImageResource(R.drawable.ic_flow_flat);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
PixelFormat.TRANSLUCENT);
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
params.height = 120; // given it a fixed height in case of large image
params.width = 120;
windowManager.addView(callHead, params);
我遇到的崩溃是
Caused by: android.view.WindowManager$InvalidDisplayException: Unable to add window android.view.ViewRootImpl$W@b40f577 -- the specified window type is not valid
看了 http://qiita.com/chibatching/items/add5e50921c2da5ee1c7 并亲自试用后
检查您的代码是否在 Marshmallow 及更高版本上运行。如果是,请检查应用程序是否有权绘制叠加层。如果不引导用户进行设置。在 onActivityResult 中,如果用户已授予权限,您可以调用 displayOverdraw。如果用户之前已授予权限,则无需再次显示设置屏幕。
public void checkdrawPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_ASK_PERMISSIONS);
} else {
// display over lay from service
}
}else
{
// display over lay from service
}
}
onActivityResult 回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_ASK_PERMISSIONS) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// You have permission
// display over lay from service
}
}
}
}
服务中的绘制叠加层
public void displayOverdraw() {
ImageView callHead = new ImageView(this);
callHead.setImageResource(R.mipmap.ic_launcher);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(callHead, params);
}
注意:为了测试,我在 activity 中尝试了这个。在服务中你不能调用 startActivityForResult
我正在使用一项服务来创建 facebook Messenger 风格的聊天头。我的代码适用于 android OS 到 6(棉花糖)的设备。但是在 M 设备上,代码因 windowManager.addView()
上的运行时异常而崩溃代码如下:
windowManager = (WindowManager) ctx.getSystemService(WINDOW_SERVICE);
callHead = new ImageView(this);
callHead.setImageResource(R.drawable.ic_flow_flat);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
PixelFormat.TRANSLUCENT);
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 100;
params.height = 120; // given it a fixed height in case of large image
params.width = 120;
windowManager.addView(callHead, params);
我遇到的崩溃是
Caused by: android.view.WindowManager$InvalidDisplayException: Unable to add window android.view.ViewRootImpl$W@b40f577 -- the specified window type is not valid
看了 http://qiita.com/chibatching/items/add5e50921c2da5ee1c7 并亲自试用后
检查您的代码是否在 Marshmallow 及更高版本上运行。如果是,请检查应用程序是否有权绘制叠加层。如果不引导用户进行设置。在 onActivityResult 中,如果用户已授予权限,您可以调用 displayOverdraw。如果用户之前已授予权限,则无需再次显示设置屏幕。
public void checkdrawPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_ASK_PERMISSIONS);
} else {
// display over lay from service
}
}else
{
// display over lay from service
}
}
onActivityResult 回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_ASK_PERMISSIONS) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// You have permission
// display over lay from service
}
}
}
}
服务中的绘制叠加层
public void displayOverdraw() {
ImageView callHead = new ImageView(this);
callHead.setImageResource(R.mipmap.ic_launcher);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(callHead, params);
}
注意:为了测试,我在 activity 中尝试了这个。在服务中你不能调用 startActivityForResult