Piotr Suchanek
Piotr Suchanek

Reputation: 384

Android set wallpaper of home screen with centering the image

I wrote a simple application that sets the wallpaper on the device. I can't achieve one effect. I wish the picture automatically centrated horizontally. This means that the center of the image was on the most central desktop of Luncher app. The picture at the bottom shows how it looks now: enter image description here

Effect that I want to achieve:

enter image description here

And the image itself:

enter image description here

I tried to use the code from this question, however, did not achieve the desired effect.

My code:

public class SystemWallpaperHelper {
private Context context;
private ImageLoader imageLoader;
private DisplayImageOptions imageLoaderOptions;

public SystemWallpaperHelper(Context context){
    this.context = context;
    setImageLoaderOptions();
}

private void setImageLoaderOptions() {
    final int width = SharedHelper.getDeviceWidth(context) << 1 ; // best wallpaper width is twice screen width
    imageLoaderOptions = new DisplayImageOptions.Builder()
            .imageScaleType(ImageScaleType.NONE)
            .cacheInMemory(false)
            .cacheOnDisk(false)
            .postProcessor(new BitmapProcessor() {
                @Override
                public Bitmap process(Bitmap bmp) {
                    float scale =  (float) width / bmp.getWidth() ;
                    int height = (int) (scale * bmp.getHeight());
                    return Bitmap.createScaledBitmap(bmp, width, height, false);
                }
            })
            .build();
    imageLoader = ImageLoader.getInstance();
}

public void setDeviceWallpaper(Wallpaper wallpaper){
    imageLoader.loadImage(wallpaper.getSrcUrl(), imageLoaderOptions, new SimpleImageLoadingListener(){
        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
        {
            WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
            try {
                wallpaperManager.setBitmap(loadedImage);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}
}

Upvotes: 2

Views: 3820

Answers (2)

Redwolf
Redwolf

Reputation: 559

Here is a more generic version, that can be pasted in any java android class. As an addition, it is not dependend on the display orientation.

public static void setWallpaper(Context context, BitmapDrawable wallpaper) {
    try {
        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
        if(wallpaper != null) {
            Bitmap bmp = wallpaper.getBitmap();
            DisplayMetrics metrics = new DisplayMetrics();
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            windowManager.getDefaultDisplay().getMetrics(metrics);
            int height = metrics.heightPixels;
            int width = metrics.widthPixels;
            wallpaperManager.setWallpaperOffsetSteps(1, 1);
            wallpaperManager.suggestDesiredDimensions(width, height);
            Bitmap bitmap = centerCropWallpaper(context, bmp, Math.min(wallpaperManager.getDesiredMinimumWidth(), wallpaperManager.getDesiredMinimumHeight()));
            wallpaperManager.setBitmap(bitmap);
        } else {
            Log.e(TAG, "wallpaper could not be set.");
        }
    } catch (Exception ex) {
        Log.e(TAG, "error setting wallpaper. " + ex.getMessage(), ex);
    }
}

private static Bitmap centerCropWallpaper(Context context, Bitmap wallpaper, int desiredHeight){
    float scale = (float) desiredHeight / wallpaper.getHeight();
    int scaledWidth = (int) (scale * wallpaper.getWidth());
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    windowManager.getDefaultDisplay().getMetrics(metrics);
    int deviceWidth = metrics.widthPixels;
    int imageCenterWidth = scaledWidth /2;
    int widthToCut = imageCenterWidth - deviceWidth / 2;
    int leftWidth = scaledWidth - widthToCut;
    Bitmap scaledWallpaper = Bitmap.createScaledBitmap(wallpaper, scaledWidth, desiredHeight, false);
    return Bitmap.createBitmap(scaledWallpaper, widthToCut, 0, leftWidth, desiredHeight);
}

Upvotes: 2

Piotr Suchanek
Piotr Suchanek

Reputation: 384

After several attempts, I managed to achieve the desired effect.

public class SystemWallpaperHelper {
private Context context;
private ImageLoader imageLoader;
private DisplayImageOptions imageLoaderOptions;
private WallpaperManager wallpaperManager;

public SystemWallpaperHelper(Context context) {
    this.context = context;
    setImageLoaderOptions();
    wallpaperManager = WallpaperManager.getInstance(context);
}

private void setImageLoaderOptions() {
    imageLoaderOptions = new DisplayImageOptions.Builder()
            .imageScaleType(ImageScaleType.NONE)
            .cacheInMemory(false)
            .cacheOnDisk(false)
            .postProcessor(new BitmapProcessor() {
                @Override
                public Bitmap process(Bitmap bmp) {
                return centerCropWallpaper(bmp, wallpaperManager.getDesiredMinimumWidth(), wallpaperManager.getDesiredMinimumHeight());
                }
            })
            .build();
    imageLoader = ImageLoader.getInstance();
}

private Bitmap centerCropWallpaper(Bitmap wallpaper, int desiredWidth, int desiredHeight){
    float scale = (float) desiredHeight / wallpaper.getHeight();
    int scaledWidth = (int) (scale * wallpaper.getWidth());
    int deviceWidth = SharedHelper.getDeviceWidth(context);
    int imageCenterWidth = scaledWidth /2;
    int widthToCut = imageCenterWidth - deviceWidth / 2;
    int leftWidth = scaledWidth - widthToCut;
    Bitmap scaledWallpaper = Bitmap.createScaledBitmap(wallpaper, scaledWidth, desiredHeight, false);
    Bitmap croppedWallpaper = Bitmap.createBitmap(
        scaledWallpaper,
        widthToCut,
        0,
        leftWidth,
        desiredHeight
    );
    return croppedWallpaper;
}

public void setDeviceWallpaper(final Wallpaper wallpaper, final boolean adjusted) {
    imageLoader.loadImage(wallpaper.getSrcUrl(), imageLoaderOptions, new SimpleImageLoadingListener() {
        @TargetApi(Build.VERSION_CODES.KITKAT)
        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            if (adjusted) {
                wallpaperManager.getCropAndSetWallpaperIntent(SharedHelper.getImageUriForBitmap(context, loadedImage));
            } else {
                try {
                    int width = wallpaperManager.getDesiredMinimumWidth();
                    int height = wallpaperManager.getDesiredMinimumHeight();
                    int bitWidth = loadedImage.getWidth();
                    wallpaperManager.setBitmap(loadedImage);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });
}
}

Upvotes: 4

Related Questions