在Android中设置壁纸时出现java.lang.SecurityException: Permission Denial的解决方法

4

我有一个壁纸应用程序,允许用户直接从应用程序设置壁纸。在这里,我将图像的http url转换为位图,并调用Android的WallpaperManager类。

以下是将URL转换为位图并设置到WallpaperManager位图的代码:

private void setWallpaper() {
        WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
        try {
            Bitmap image = getBitMapFromHttpURL();
            if (image != null) {
                wallpaperManager.setBitmap(getBitMapFromHttpURL());
                image.recycle();
                image = null;
            } else {
                Toast.makeText(this, "Failed to set wallpaper",
                        Toast.LENGTH_LONG).show();
            }
        } catch (IOException e) {

        } catch (Exception es) {

        }
    }

在这一行代码wallpaperManager.setBitmap(getBitMapFromHttpURL());上失败,并抛出以下异常:

java.lang.SecurityException: Permission Denial: writing com.android.providers.settings.SettingsProvider uri content://settings/system from pid=21407, uid=10133 requires android.permission.WRITE_SETTINGS, or grantUriPermission()
       at android.os.Parcel.readException(Parcel.java:1465)
       at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
       at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
       at android.content.ContentProviderProxy.insert(ContentProviderNative.java:468)
       at android.content.ContentResolver.insert(ContentResolver.java:1190)
       at android.provider.Settings$NameValueTable.putString(Settings.java:843)
       at android.provider.Settings.putString(Settings.java:6792)
       at android.provider.Settings.putString(Settings.java:6717)
       at android.app.WallpaperManager.willSendBroadcat(WallpaperManager.java:1124)
       at android.app.WallpaperManager.setBitmap(WallpaperManager.java:788)
       at com.wallie.WallpaperFullScreenActivity.setWallpaper(WallpaperFullScreenActivity.java:453)
       at com.wallie.WallpaperFullScreenActivity.access$1(WallpaperFullScreenActivity.java:448)
       at com.wallie.WallpaperFullScreenActivity$WallpaperManagerTask.doInBackground(WallpaperFullScreenActivity.java:473)
       at com.wallie.WallpaperFullScreenActivity$WallpaperManagerTask.doInBackground(WallpaperFullScreenActivity.java:1)
       at android.os.AsyncTask$2.call(AsyncTask.java:295)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:238)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:841)

什么可能是原因?

你在 AndroidManifest.xml 中定义了这个权限:<uses-permission android:name="android.permission.SET_WALLPAPER"/> 吗? - Haresh Chhelana
已经定义。 - virendrao
请查看:http://stackoverflow.com/questions/26735180/crash-when-i-use-method-setwallpaper-android/26735713#26735713 - Haresh Chhelana
在我的情况下,如果我将WallpaperManager对象从类级别创建到方法级别,会有什么区别? - virendrao
你尝试过上述权限了吗? - Haresh Chhelana
显示剩余4条评论
4个回答

5

你收到的异常明确指出需要在清单文件中添加权限。

java.lang.SecurityException: 拒绝许可:从pid=21407,uid=10133写入com.android.providers.settings.SettingsProvider uri content://settings/system需要android.permission.WRITE_SETTINGS或grantUriPermission()

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

2
它只在某些设备上出现,那么这个权限的原因是什么? - virendrao
你能具体说明是在哪个设备上吗? - SweetWisher ツ
7040n是阿尔卡特4.4.2安卓版本。 - virendrao
Kitkat问题 - SweetWisher ツ

2
日志没有异常:
java.lang.SecurityException: Permission Denial: writing com.android.providers.settings.SettingsProvider uri content://settings/system from pid=21407, uid=10133 requires android.permission.WRITE_SETTINGS, or grantUriPermission()

所以,您只需要在您的清单文件中添加此权限即可:

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

在应用标签下。

希望对您有所帮助。


如果需要提示,请参考这里。@vo12 - MysticMagicϡ
1
很难找到我提到的设备进行测试。我会添加权限,并在下一个更新中发布它。 - virendrao
谢谢,但这将是用户特定的,也许我应该捕获异常并让用户知道您没有权限? - virendrao
@vo12 是的。可能需要在那行代码周围使用try catch。并查看更多信息,请参见此处 - MysticMagicϡ
我只在安装有Kitkat的三星手机上遇到了这个异常。 - Robert
显示剩余2条评论

1
您需要在AndroidManifest.xml中添加WRITE_SETTINGS权限。
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

如果您不需要 Bitmap 对象,则可以直接使用 getBitMapFromHttpURL 方法从位图中进行检查,而不需要声明 Bitamp 对象。
if (getBitMapFromHttpURL() != null) {
    wallpaperManager.setBitmap(getBitMapFromHttpURL());
} else {
    Toast.makeText(this, "Failed to set wallpaper",Toast.LENGTH_LONG).show();
}

0

你可能忘记了获取其中的某些权限:

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />

SET_WALLPAPER_HINTS 的作用是什么? - Sam

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