我正在修复一个没有由我开发的安卓应用程序,几天前,客户要求我将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();
执行最后一行时,应用程序崩溃,并在Logcat中显示此错误:
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@b784d3a -- permission denied for window type 2003
当应用程序运行在有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
在“宣言”中,我得到了许可:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
我还从设备设置中启用了应用程序的所有权限。我该如何解决这个问题?
发布于 2018-10-21 16:34:02
正如您所看到的,Android及以上严格限制了允许使用的覆盖类型。奥利奥引入了新的TYPE_APPLICATION_OVERLAY
常量供应用程序使用,同时反对和拒绝旧常量。
然而,TYPE_APPLICATION_OVERLAY
并不存在于努格特及其下面,因此尝试在那里使用它将导致SecurityException。
替换
mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
使用
mProgressDialog.getWindow().setType(
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
else
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
至于为什么它仍然在奥利奥和更高的TYPE_APPLICATION_OVERLAY
上崩溃,SYSTEM_ALERT_WINDOW
权限不是一个正常的运行时权限,也没有显示在应用程序信息中的“权限”部分。面向用户的名称是“在其他应用程序之上”(通常),它位于普通应用程序信息页面或Settings>>Apps>>Special Access下。
您不能像使用运行时权限那样以编程方式授予它,在运行时您有一个简单的对话框来授予它。相反,您需要检查权限是否已授予,如果未授予,则启动设置页面以允许用户授予该权限:如何以编程方式在android中授予“其他应用程序的画图”权限?
然而,我真的不明白为什么一个简单的进度对话框需要一个全面的覆盖。事实上,ProgressDialog已经被完全反对了。您应该考虑迁移到一个简单的ProgressBar,或者,如果您想保留ProgressDialog,可以删除setType()
行。
https://stackoverflow.com/questions/52917177
复制相似问题