问题描述
设置壁纸A为桌面和锁屏壁纸,设置默认壁纸为桌面壁纸,锁屏壁纸也变为默认壁纸A。
问题分析
设置默认壁纸为桌面壁纸时 vendor/mediatek/proprietary/packages/apps/WallpaperPicker/src/com/android/wallpaperpicker/tileinfo/DefaultWallpaperInfo.java
@Override
public void onSave(final WallpaperPickerActivity a) {
CropAndSetWallpaperTask.OnEndCropHandler onEndCropHandler
= new CropAndSetWallpaperTask.OnEndCropHandler() {
@Override
public void run(boolean cropSucceeded) {
if (cropSucceeded) {
a.setResult(Activity.RESULT_OK);
}
a.finish();
}
};
CropAndSetWallpaperTask setWallpaperTask = new CropAndSetWallpaperTask(
null, a, null, -1, -1, -1, onEndCropHandler) {
@Override
protected Boolean doInBackground(Integer... params) {
int whichWallpaper = params[0];
boolean succeeded;
if (whichWallpaper == WallpaperManagerCompat.FLAG_SET_LOCK) {
succeeded = setDefaultOnLock(a);
} else {
succeeded = clearWallpaper(a, whichWallpaper);
}
return succeeded;
}
};
DialogUtils.executeCropTaskAfterPrompt(a, setWallpaperTask, a.getOnDialogCancelListener());
}
思路1
修改wallpaperPick应用,细分默认壁纸设置。 优势:只需要修改app,不需要修改framework层逻辑。 缺点:单独设置默认壁纸为桌面或者锁屏壁纸时,耗时严重
@Override
protected Boolean doInBackground(Integer... params) {
int whichWallpaper = params[0];
boolean succeeded;
if (whichWallpaper == WallpaperManagerCompat.FLAG_SET_LOCK || whichWallpaper == WallpaperManagerCompat.FLAG_SET_SYSTEM) {
succeeded = setDefaultOnLockOrHome(a,whichWallpaper);
} else {
succeeded = clearWallpaper(a, whichWallpaper);
}
return succeeded;
}
private boolean setDefaultOnLock(WallpaperPickerActivity a) {
boolean succeeded = true;
try {
Bitmap defaultWallpaper = ((BitmapDrawable) WallpaperManager.getInstance(
a.getApplicationContext()).getBuiltInDrawable()).getBitmap();
ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
if (defaultWallpaper.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) {
byte[] outByteArray = tmpOut.toByteArray();
WallpaperManagerCompat.getInstance(a.getApplicationContext())
.setStream(new ByteArrayInputStream(outByteArray), null,
true, WallpaperManagerCompat.FLAG_SET_LOCK);
}
} catch (IOException e) {
Log.w(TAG, "Setting wallpaper to default threw exception", e);
succeeded = false;
}
return succeeded;
}
对setDefaultOnLock方法进行改造,修改后
private boolean setDefaultOnLockOrHome(WallpaperPickerActivity a,int whichWallpaper) {
boolean succeeded = true;
try {
Bitmap defaultWallpaper = ((BitmapDrawable) WallpaperManager.getInstance(
a.getApplicationContext()).getBuiltInDrawable()).getBitmap();
ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
if (defaultWallpaper.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) {
byte[] outByteArray = tmpOut.toByteArray();
WallpaperManagerCompat.getInstance(a.getApplicationContext())
.setStream(new ByteArrayInputStream(outByteArray), null,
true, whichWallpaper);
}
} catch (IOException e) {
Log.w(TAG, "Setting wallpaper to default threw exception", e);
succeeded = false;
}
return succeeded;
}
思路2
我们注意到,clearWallpaper(a, whichWallpaper);其实是有传入参数的,那么按照这个逻辑,应该是可以分别对锁屏或者桌面壁纸进行清除,使它显示默认壁纸,而不影响另一个。
frameworks/base/core/java/android/app/WallpaperManager.java
public void clear(@SetWallpaperFlags int which) throws IOException {
if ((which & FLAG_SYSTEM) != 0) {
clear();
}
if ((which & FLAG_LOCK) != 0) {
clearWallpaper(FLAG_LOCK, mContext.getUserId());
}
}
修改为:
public void clear(@SetWallpaperFlags int which) throws IOException {
if ((which & FLAG_SYSTEM) != 0 && (which & FLAG_LOCK) != 0){
clear();
}
if ((which & FLAG_SYSTEM) != 0) {
clearWallpaper(FLAG_SYSTEM, mContext.getUserId());
}
if ((which & FLAG_LOCK) != 0) {
clearWallpaper(FLAG_LOCK, mContext.getUserId());
}
}
按照理解,这样就可以了。但是实际上测下来还是没有效果。 原因 1、桌面壁纸显示为:vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/ImageWallpaper.java 当桌面和锁屏显示不同的壁纸,锁屏壁纸显示为: vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java中的private ImageView mBackdropFront;
2、桌面和锁屏显示同一张壁纸的时候,锁屏其实不显示壁纸,透明过去显示桌面壁纸。 直接清除桌面壁纸,从效果上来说,锁屏不显示壁纸,透过去看到桌面壁纸,所以看上去桌面壁纸和锁屏壁纸都变了。
我们需要在清除壁纸之前,把桌面壁纸设置为锁屏壁纸,再去清除桌面壁纸。
这个思想来自于WallpaperManagerService的setWallpaper。见下文↓
frameworks/base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
private final SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
private final SparseArray<WallpaperData> mLockWallpaperMap = new SparseArray<WallpaperData>();
public ParcelFileDescriptor setWallpaper(String name, String callingPackage,
Rect cropHint, boolean allowBackup, Bundle extras, int which,
IWallpaperManagerCallback completion, int userId) {
...
synchronized (mLock) {
if (DEBUG) Slog.v(TAG, "setWallpaper which=0x" + Integer.toHexString(which));
WallpaperData wallpaper;
if (which == FLAG_SYSTEM && mLockWallpaperMap.get(userId) == null) {
Slog.i(TAG, "Migrating current wallpaper to be lock-only before"
+ "updating system wallpaper");
migrateSystemToLockWallpaperLocked(userId);
}
...
wallpaper = getWallpaperSafeLocked(userId, which);
}
}
@Override
public void clearWallpaper(String callingPackage, int which, int userId) {
if (DEBUG) Slog.v(TAG, "clearWallpaper");
...
synchronized (mLock) {
if (which == FLAG_SYSTEM && mLockWallpaperMap.get(userId) == null) {
Slog.i(TAG, "Migrating current wallpaper to be lock-only before"
+ "clear system wallpaper");
migrateSystemToLockWallpaperLocked(userId);
}
clearWallpaperLocked(false, which, userId, null);
if (which == FLAG_LOCK) {
data = mLockWallpaperMap.get(userId);
}
if (which == FLAG_SYSTEM || data == null) {
data = mWallpaperMap.get(userId);
}
}
...
}
|