diff --git a/WallpaperPicker/res/values/arrays.xml b/WallpaperPicker/res/values/arrays.xml new file mode 100644 index 0000000000..5c10b98fb4 --- /dev/null +++ b/WallpaperPicker/res/values/arrays.xml @@ -0,0 +1,22 @@ + + + + + @string/which_wallpaper_option_home_screen + @string/which_wallpaper_option_lock_screen + @string/which_wallpaper_option_home_screen_and_lock_screen + + \ No newline at end of file diff --git a/WallpaperPicker/res/values/strings.xml b/WallpaperPicker/res/values/strings.xml index 2bfd4767fc..aef6a1a50c 100644 --- a/WallpaperPicker/res/values/strings.xml +++ b/WallpaperPicker/res/values/strings.xml @@ -53,4 +53,11 @@ Wallpapers Crop wallpaper + + + Home screen + + Lock screen + + Home screen and lock screen diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java index 8b51447484..2d10b7265a 100644 --- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java +++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java @@ -33,7 +33,9 @@ import android.os.AsyncTask; import android.util.Log; import android.widget.Toast; +import com.android.launcher3.NycWallpaperUtils; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -42,7 +44,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -public class BitmapCropTask extends AsyncTask { +public class BitmapCropTask extends AsyncTask { public interface OnBitmapCroppedHandler { public void onBitmapCropped(byte[] imageBytes); @@ -175,7 +177,7 @@ public class BitmapCropTask extends AsyncTask { public Bitmap getCroppedBitmap() { return mCroppedBitmap; } - public boolean cropBitmap() { + public boolean cropBitmap(int whichWallpaper) { boolean failure = false; @@ -189,7 +191,11 @@ public class BitmapCropTask extends AsyncTask { try { InputStream is = regenerateInputStream(); if (is != null) { - wallpaperManager.setStream(is); + if (!Utilities.isNycOrAbove()) { + wallpaperManager.setStream(is); + } else { + NycWallpaperUtils.setStream(mContext, is, null, true, whichWallpaper); + } Utils.closeSilently(is); } } catch (IOException e) { @@ -375,7 +381,13 @@ public class BitmapCropTask extends AsyncTask { if (mSetWallpaper && wallpaperManager != null) { try { byte[] outByteArray = tmpOut.toByteArray(); - wallpaperManager.setStream(new ByteArrayInputStream(outByteArray)); + if (!Utilities.isNycOrAbove()) { + wallpaperManager.setStream(new ByteArrayInputStream(outByteArray)); + } else { + NycWallpaperUtils.setStream(mContext, + new ByteArrayInputStream(outByteArray), null, true, + whichWallpaper); + } if (mOnBitmapCroppedHandler != null) { mOnBitmapCroppedHandler.onBitmapCropped(outByteArray); } @@ -393,8 +405,8 @@ public class BitmapCropTask extends AsyncTask { } @Override - protected Boolean doInBackground(Void... params) { - return cropBitmap(); + protected Boolean doInBackground(Integer... params) { + return cropBitmap(params.length == 0 ? NycWallpaperUtils.FLAG_SET_SYSTEM : params[0]); } @Override diff --git a/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java new file mode 100644 index 0000000000..abac830a2a --- /dev/null +++ b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java @@ -0,0 +1,79 @@ +package com.android.launcher3; + +import android.app.AlertDialog; +import android.app.WallpaperManager; +import android.content.Context; +import android.content.DialogInterface; +import android.graphics.Rect; +import android.os.AsyncTask; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Utility class used to help set lockscreen wallpapers on N+. + */ +public class NycWallpaperUtils { + public static final int FLAG_SET_SYSTEM = 1 << 0; // TODO: use WallpaperManager.FLAG_SET_SYSTEM + public static final int FLAG_SET_LOCK = 1 << 1; // TODO: use WallpaperManager.FLAG_SET_LOCK + + /** + * Calls cropTask.execute(), once the user has selected which wallpaper to set. On pre-N + * devices, the prompt is not displayed since there is no API to set the lockscreen wallpaper. + */ + public static void executeCropTaskAfterPrompt( + Context context, final AsyncTask cropTask, + DialogInterface.OnCancelListener onCancelListener) { + if (Utilities.isNycOrAbove()) { + new AlertDialog.Builder(context) + .setTitle(R.string.wallpaper_instructions) + .setItems(R.array.which_wallpaper_options, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int selectedItemIndex) { + int whichWallpaper; + if (selectedItemIndex == 0) { + whichWallpaper = FLAG_SET_SYSTEM; + } else if (selectedItemIndex == 1) { + whichWallpaper = FLAG_SET_LOCK; + } else { + whichWallpaper = FLAG_SET_SYSTEM | FLAG_SET_LOCK; + } + cropTask.execute(whichWallpaper); + } + }) + .setOnCancelListener(onCancelListener) + .show(); + } else { + cropTask.execute(FLAG_SET_SYSTEM); + } + } + + public static void setStream(Context context, final InputStream data, Rect visibleCropHint, + boolean allowBackup, int whichWallpaper) throws IOException { + WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); + try { + // TODO: use mWallpaperManager.setStream(data, visibleCropHint, allowBackup, which) + // without needing reflection. + Method setStream = WallpaperManager.class.getMethod("setStream", InputStream.class, + Rect.class, boolean.class, int.class); + setStream.invoke(wallpaperManager, data, visibleCropHint, allowBackup, whichWallpaper); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + // Fall back to previous implementation (set system) + wallpaperManager.setStream(data); + } + } + + public static void clear(Context context, int whichWallpaper) throws IOException { + WallpaperManager wallpaperManager = WallpaperManager.getInstance(context); + try { + // TODO: use mWallpaperManager.clear(whichWallpaper) without needing reflection. + Method clear = WallpaperManager.class.getMethod("clear", int.class); + clear.invoke(wallpaperManager, whichWallpaper); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + // Fall back to previous implementation (clear system) + wallpaperManager.clear(); + } + } +} \ No newline at end of file diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java index 75bdb8a618..364cdb88de 100644 --- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java +++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java @@ -21,6 +21,7 @@ import android.app.ActionBar; import android.app.Activity; import android.app.WallpaperManager; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -86,6 +87,18 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb @Thunk Set mReusableBitmaps = Collections.newSetFromMap(new WeakHashMap()); + private final DialogInterface.OnCancelListener mOnDialogCancelListener = + new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + getActionBar().show(); + View wallpaperStrip = findViewById(R.id.wallpaper_strip); + if (wallpaperStrip != null) { + wallpaperStrip.setVisibility(View.VISIBLE); + } + } + }; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -242,6 +255,10 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb } } + public DialogInterface.OnCancelListener getOnDialogCancelListener() { + return mOnDialogCancelListener; + } + protected void onLoadRequestComplete(LoadRequest req, boolean success) { mCurrentLoadRequest = null; if (success) { @@ -326,7 +343,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb }; cropTask.setOnEndRunnable(onEndCrop); cropTask.setNoCrop(true); - cropTask.execute(); + NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener()); } protected void cropImageAndSetWallpaper(Resources res, int resId, @@ -335,8 +352,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb // this device int rotation = BitmapUtils.getRotationFromExif(res, resId); Point inSize = mCropView.getSourceDimensions(); - Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), - getWindowManager()); + Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), getWindowManager()); RectF crop = Utils.getMaxCropRect( inSize.x, inSize.y, outSize.x, outSize.y, false); BitmapCropTask.OnEndCropHandler onEndCrop = new BitmapCropTask.OnEndCropHandler() { @@ -355,7 +371,7 @@ public class WallpaperCropActivity extends BaseActivity implements Handler.Callb }; BitmapCropTask cropTask = new BitmapCropTask(getContext(), res, resId, crop, rotation, outSize.x, outSize.y, true, false, onEndCrop); - cropTask.execute(); + NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener()); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java index 4998bf4b73..46e4716587 100644 --- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java +++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java @@ -849,7 +849,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity { (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned); cropTask.setCropBounds(cropRect); - if (cropTask.cropBitmap()) { + if (cropTask.cropBitmap(NycWallpaperUtils.FLAG_SET_SYSTEM)) { return cropTask.getCroppedBitmap(); } else { return null;