以下のコードを試します。
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;
}
}
...
}
android-27
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;
}
}
...
}
android-26 のコードに比べて catch (SecurityException e) { ... } の部分↓が増えていました。
targetSdkVersion が27以降なら SecurityException をそのまま流すように変わったということです。
} 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;
}
}
さらに、getCurrentWallpaperLocked() の引数に context が増えています。
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;
}
android-27
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;
}
IWallpaperManager.getWallpaper() にも新しい引数が増えており、この context を使ってその引数に
context.getOpPackageName() を渡しています。
ちなみに 27 (Android 8.1)では WallpaperColors API が追加されています。
0 件のコメント:
コメントを投稿