ant*_*i95 2 android android-windowmanager android-layoutparams
我正在修复一个不是我开发的 android 应用程序,几天前客户端要求我将 targetSdkVersion 设置为 26(之前是 14),之后我注意到应用程序在某些情况下崩溃,例如崩溃时显示 ProgressDialog。这是存在此问题的代码部分:
mProgressDialog.setTitle(getString(R.string.downloading_data));
mProgressDialog.setMessage(mAlertMsg);
Drawable icon = getActivity().getDrawable(android.R.drawable.ic_dialog_info);
icon.setColorFilter(Color.parseColor("#00cbac"), PorterDuff.Mode.SRC_ATOP);
mProgressDialog.setIcon(icon);
mProgressDialog.setIndeterminate(true);
mProgressDialog.setCancelable(false);
mProgressDialog.setButton(getString(R.string.cancel), loadingButtonListener);
mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mProgressDialog.show();
Run Code Online (Sandbox Code Playgroud)
执行最后一行时,应用程序崩溃并在 Logcat 中出现此错误:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@b784d3a -- permission denied for window type 2003
Run Code Online (Sandbox Code Playgroud)
当应用程序运行在具有Android 8和9的设备上时会出现此问题。我寻找了类似问题的解决方案,发现使用WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY代替会更好TYPE_SYSTEM_ALERT,然后我修改了我写的代码的倒数第二行在这篇文章中,但它没有改变任何东西,应用程序崩溃了,并且在日志中出现了这个错误:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@b784d3a -- permission denied for window type 2038
Run Code Online (Sandbox Code Playgroud)
在清单中,我有权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Run Code Online (Sandbox Code Playgroud)
我还从设备设置中启用了该应用程序的所有权限。我怎么解决这个问题?
正如您所见,Android Oreo 及更高版本严格限制了您可以使用的覆盖类型。Oreo 引入了供应TYPE_APPLICATION_OVERLAY用程序使用的新常量,同时弃用和禁止使用旧常量。
但是,TYPE_APPLICATION_OVERLAY在 Nougat 及以下版本中不存在,因此尝试使用它会导致 SecurityException。
代替
mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Run Code Online (Sandbox Code Playgroud)
和
mProgressDialog.getWindow().setType(
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
else
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
Run Code Online (Sandbox Code Playgroud)
至于为什么它仍然在 Oreo 及更高版本上崩溃TYPE_APPLICATION_OVERLAY,该SYSTEM_ALERT_WINDOW权限不是正常的运行时权限,并且不会显示在应用信息的“权限”部分下。它面向用户的名称是“绘制其他应用程序”(通常),它位于常规应用程序信息页面或设置>>应用程序>>特殊访问下。
您不能像使用运行时权限那样以编程方式授予它,您可以通过一个简单的对话框来授予它。相反,您需要检查是否授予权限,如果未授予,请启动“设置”页面以允许用户授予权限:如何以编程方式授予 android 中的“绘制其他应用程序”权限?
但是,我真的不明白为什么一个简单的进度对话框需要是一个完整的叠加层。事实上,ProgressDialog已被完全弃用。您应该考虑迁移到一个简单的 ProgressBar,或者,如果您想保留 ProgressDialog,则删除该setType()行。
| 归档时间: |
|
| 查看次数: |
6994 次 |
| 最近记录: |