权限拒绝:写入设置需要android.permission.WRITE_SETTINGS。

3

对于极少数用户,我的应用程序出现以下崩溃问题:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cloud3squared.meteogram.pro/com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity}:
        java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
    at android.app.ActivityThread.access$900(ActivityThread.java:177)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:5942)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: java.lang.SecurityException: Permission denial: writing to settings requires android.permission.WRITE_SETTINGS
    at android.os.Parcel.readException(Parcel.java:1540)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
    at android.content.ContentProviderProxy.call(ContentProviderNative.java:643)
    at android.provider.Settings$NameValueCache.putStringForUser(Settings.java:1204)
    at android.provider.Settings$System.putStringForUser(Settings.java:1505)
    at android.provider.Settings$System.putIntForUser(Settings.java:1616)
    at android.provider.Settings$System.putInt(Settings.java:1607)
    at android.app.WallpaperManager$Globals.getDefaultWallpaperLocked(WallpaperManager.java:483)
    at android.app.WallpaperManager$Globals.peekWallpaperBitmap(WallpaperManager.java:303)
    at android.app.WallpaperManager.getDrawable(WallpaperManager.java:550)
    at com.cloud3squared.meteogram.ax.c(Unknown Source)
    at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.a(Unknown Source)
    at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.c(Unknown Source)
    at com.cloud3squared.meteogram.MeteogramWidgetConfigureActivity.onCreate(Unknown Source)
    at android.app.Activity.performCreate(Activity.java:6288)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
    ... 10 more

尽管崩溃报告中提供了解决此问题的方法(只需将android.permission.WRITE_SETTINGS添加到清单中),但我感到困扰,因为我的应用程序不会有意地写入设置,并且绝大多数用户没有任何权限问题。这尤其令人不安,因为文档指出:

有一些权限不像普通和危险的权限那样行事。SYSTEM_ALERT_WINDOW和WRITE_SETTINGS特别敏感,因此大多数应用程序不应使用它们。如果应用程序需要其中一个权限,则必须在清单中声明该权限,并发送一个请求用户授权的意图。系统通过显示详细的管理屏幕来响应意图。

我希望尽一切可能避免在我的应用程序中使用此权限,因为显然这是“危险的”,并且在运行时请求此权限足以吓跑非极端用户。 我真的不需要写入设置... 我只写SharedPreferences,仅此而已。
那么,有没有任何方法可以避免在不需要权限的情况下解决此问题?
编辑根据下面的评论添加代码(从我的Activity调用此函数):
static String getAverageWallpaperColour(Context context) {
    final WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
    final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
    Bitmap bmp = ((BitmapDrawable)wallpaperDrawable).getBitmap();
    int color = getAverageColour(bmp); // details of function not relevant... just reads the bmp to work out an average colour
    return colorToHexString(color); // details of function not relevant... just converts into color to String in particular format
}

我的猜测是您正在触及一个通常需要该权限的类内部的某些内容。您应该发布您的.MeteogramWidgetConfigureActivity或相关代码部分... - Opiatefuchs
是的,这一定是无意的/间接的。只有在某些设备上似乎才会抛出异常,这很奇怪...如果我触及需要权限的东西,那么每个用户在每个设备上都肯定需要它吧?我将深入代码,看看是否可以找到可能是原因的相关内容。 - drmrbrewer
你的应用程序中是否使用了壁纸相关的功能?在你的清单文件中是否声明了SET_WALLPAPER权限? - Opiatefuchs
我所做的关于壁纸的事情只是通过类似于https://dev59.com/lmkw5IYBdhLWcg3wXpec#9939358的代码来获取它。崩溃发生在我的AppWidget的Config Activity上,但奇怪的是Activity第一次打开时(当小部件首次配置和放置时)不会崩溃,只有当Activity第二次从正在运行的小部件中打开时才会崩溃。 - drmrbrewer
这篇帖子可能会有所启发...和我类似...http://developer.samsung.com/forum/thread/securityexception-calling-wallpapermanagergetdrawable/202/279150 --- 当壁纸设置为null时似乎存在问题。我将在我的问题中添加相关代码。 - drmrbrewer
显示剩余10条评论
1个回答

0

我现在确定问题出在我编辑中添加的代码片段上:

static String getAverageWallpaperColour(Context context) {
    final WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
    final Drawable wallpaperDrawable = wallpaperManager.getDrawable();
    Bitmap bmp = ((BitmapDrawable)wallpaperDrawable).getBitmap();
    int color = getAverageColour(bmp); // details of function not relevant... just reads the bmp to work out an average colour
    return colorToHexString(color); // details of function not relevant... just converts into color to String in particular format
}

基本上,一个应用程序崩溃的用户告诉我,他们在设备上使用的是动态壁纸,而不是传统的静态壁纸。

因此,由于某种我仍然不理解的原因,无论是尝试获取可绘制对象还是从可绘制对象获取位图,这都会导致Settings$System.putIntSettings$System.putIntForUser以及Settings$System.putStringForUser日志条目,进而导致SecurityException: Permission denial错误(尝试在没有权限的情况下写入设置)。

这篇文章也是类似的情况,报告说错误似乎与“系统壁纸为空”的情况有关。为什么当我尝试对null进行不可言喻的操作时,没有出现NullPointerException,而是在明显尝试篡改设置后出现了严重的权限错误,我不知道。


我在三星设备上遇到了相同的错误,如何修复? - Hamza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接