以下のコードを試します。
- class MainActivity : AppCompatActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
- val d = WallpaperManager.getInstance(this).drawable
- }
- }
targetSdkVersion = 27
targetSdkVersion = 27 で実行すると、READ_EXTERNAL_STORAGE permission が無いと怒られました。Caused by: java.lang.SecurityException: read wallpaper: Neither user 10278 nor current process has android.permission.READ_EXTERNAL_STORAGE.
targetSdkVersion = 26
targetSdkVersion = 26 (compileSdkVersion は 27)で実行すると怒られませんでした。代わりに Warning がログに出ます。W/WallpaperManager: No permission to access wallpaper, suppressing exception to avoid crashing legacy app.
android-27 での変更
26と27の間でコードの変更がありました。android-26
- public Drawable getDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
- if (bm != null) {
- Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
- dr.setDither(false);
- return dr;
- }
- return null;
- }
- static class Globals extends IWallpaperManagerCallback.Stub {
- ...
- public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which, int userId) {
- ...
- synchronized (this) {
- if (mCachedWallpaper != null && mCachedWallpaperUserId == userId) {
- return mCachedWallpaper;
- }
- mCachedWallpaper = null;
- mCachedWallpaperUserId = 0;
- try {
- mCachedWallpaper = getCurrentWallpaperLocked(userId);
- mCachedWallpaperUserId = userId;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "No memory load current wallpaper", e);
- }
- if (mCachedWallpaper != null) {
- return mCachedWallpaper;
- }
- }
- ...
- }
- public Drawable getDrawable() {
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, FLAG_SYSTEM);
- if (bm != null) {
- Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
- dr.setDither(false);
- return dr;
- }
- return null;
- }
- private static class Globals extends IWallpaperManagerCallback.Stub {
- ...
- public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault,
- @SetWallpaperFlags int which, int userId) {
- ...
- synchronized (this) {
- ...
- try {
- mCachedWallpaper = getCurrentWallpaperLocked(context, userId);
- mCachedWallpaperUserId = userId;
- } catch (OutOfMemoryError e) {
- Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
- } catch (SecurityException e) {
- if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.O) {
- Log.w(TAG, "No permission to access wallpaper, suppressing"
- + " exception to avoid crashing legacy app.");
- } else {
- // Post-O apps really most sincerely need the permission.
- throw e;
- }
- }
- if (mCachedWallpaper != null) {
- return mCachedWallpaper;
- }
- }
- ...
- }
- } catch (SecurityException e) {
- if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.O) {
- Log.w(TAG, "No permission to access wallpaper, suppressing"
- + " exception to avoid crashing legacy app.");
- } else {
- // Post-O apps really most sincerely need the permission.
- throw e;
- }
- }
android-26
- private Bitmap getCurrentWallpaperLocked(int userId) {
- ...
- try {
- Bundle params = new Bundle();
- ParcelFileDescriptor fd = mService.getWallpaper(this, FLAG_SYSTEM,
- params, userId);
- ...
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return null;
- }
- private Bitmap getCurrentWallpaperLocked(Context context, int userId) {
- ...
- try {
- Bundle params = new Bundle();
- ParcelFileDescriptor fd = mService.getWallpaper(context.getOpPackageName(),
- this, FLAG_SYSTEM, params, userId);
- ...
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- return null;
- }
ちなみに 27 (Android 8.1)では WallpaperColors API が追加されています。