为了账号安全,请及时绑定邮箱和手机立即绑定

Android:无法添加窗口。此窗口类型的权限被拒绝

Android:无法添加窗口。此窗口类型的权限被拒绝

慕仙森 2019-08-31 16:32:38
我工作的一个应用程序,我需要显示一些信息的窗口ON未解锁手机的锁屏(键盘保护)。我想我可以用WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG做到这一点但每次我的应用程序崩溃时出现以下错误:android.view.WindowManager $ BadTokenException:无法添加窗口android.view.ViewRootImpl$W@40ec8528 - 此窗口类型的权限被拒绝这些帖子(这里,这里和这里)都给出了相同的答案。在清单文件中添加以下权限。android.permission.SYSTEM_ALERT_WINDOW我已经实现的解决方案,但我仍然得到相同的错误。我知道我做错了什么?以下是我的清单文件中的权限:<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.droidpilot.keyguardwindow" ><uses-sdk    android:minSdkVersion="16"    android:targetSdkVersion="21" /><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.VIBRATE" />这是我用来将Window添加到锁定屏幕的代码WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);    LayoutInflater mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);    mView = mInflater.inflate(R.layout.lock_screen_notif, null);    WindowManager.LayoutParams params = new WindowManager.LayoutParams(            WindowManager.LayoutParams.WRAP_CONTENT,            WindowManager.LayoutParams.WRAP_CONTENT,            WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,            PixelFormat.TRANSLUCENT    );    wm.addView(mView, params);有人知道吗?PS我正在测试运行Android 4.4.2的HTC Desire 620 DS
查看完整描述

3 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

对于应该是完全明显的原因,普通的应用程序不允许在锁定屏幕上创建任意窗口。如果我在锁屏上创建一个可以完美模仿真实锁屏的窗口,你怎么能这么做呢?


您的错误的技术原因是使用TYPE_KEYGUARD_DIALOG标志 - 它需要android.permission.INTERNAL_SYSTEM_WINDOW哪个是签名级权限。这意味着只有使用与权限创建者相同的证书签名的Apps 才能使用它。


android.permission.INTERNAL_SYSTEM_WINDOWAndroid系统本身的创建者,所以除非你的应用程序是操作系统的一部分,否则你没有机会。


有明确定义且记录良好的方式来通知用户来自锁屏的信息。您可以创建在锁屏上显示的自定义通知,用户可以与它们进行交互。


查看完整回答
反对 回复 2019-08-31
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

如果你使用apiLevel >= 19,不要使用


WindowManager.LayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT 

得到以下错误:


android.view.WindowManager $ BadTokenException:无法添加窗口android.view.ViewRootImpl$W@40ec8528 - 此窗口类型的权限被拒绝


请改用:


LayoutParams.TYPE_TOAST or TYPE_APPLICATION_PANEL


查看完整回答
反对 回复 2019-08-31
?
MYYA

TA贡献1868条经验 获得超4个赞

我想你应该区分目标(奥利奥之前和之后)


int LAYOUT_FLAG;

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

} else {

    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;

}


params = new WindowManager.LayoutParams(

    WindowManager.LayoutParams.WRAP_CONTENT,

    WindowManager.LayoutParams.WRAP_CONTENT,

    LAYOUT_FLAG,

    WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,

    PixelFormat.TRANSLUCENT);


查看完整回答
反对 回复 2019-08-31
  • 3 回答
  • 1 关注
  • 1805 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信