AndroidNoob
AndroidNoob

Reputation: 2821

WallpaperManager zooms image even though the dimension match the screen

I have an app that applies wallpaper to the home screen with images that match the screen size, however on the galaxy s3 the wallpaper is zoomed in when I apply it, even though the image used exactly matched the screen dimensions! It is a static image and does not even scroll when you switch between pages on the home screen. The odd thing is that if I apply the image using the built in gallery the wallpaper is applied fine without the zoom (it comes up with the 'crop image' screen but the crop region itself matches the edges of the image)

The code i use works fine on a whole array of phones (galaxy note, ace 2, s2 among others) but not on the s3; I was wondering if there was anything i can do to force the wallpaper to fill the screen properly? The current code i use to apply the wallpaper is:

WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);   
wallpaperManager.setWallpaperOffsets(wallpaperViewer.getApplicationWindowToken(), 0, 0);
wallpaperManager.setBitmap(BitmapFactory.decodeFile(file.getPath()));//file is jpg on sd card

Upvotes: 8

Views: 6390

Answers (4)

AndroidNoob
AndroidNoob

Reputation: 2821

EDIT: Added Y offset fix - thanks @Jason Goff!

Ok so it turns out that the minimum width of the home screen on the s3 is not 720 but actually 1280! You can find out the desired minimum width and height of wallpaper by calling

wallpaperManager.getDesiredMinimumWidth();//returned 1280 on s3
wallpaperManager.getDesiredMinimumHeight();//also returned 1280 on s3

So in order to apply the wallpaper to the centre of the screen i had to create a blank bitmap 1280x1280 on the fly, then overlay my wallpaper into the centre of the blank bitmap, I created a static BitmapHelper class with methods for tweaking bitmaps, here's the methods for creating the bitmaps and overlaying the wallpaper image:

public class BitmapHelper {

public static Bitmap overlayIntoCentre(Bitmap bmp1, Bitmap bmp2) {
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(bmp1, new Matrix(), null);//draw background bitmap

    //overlay the second in the centre of the first 
    //(may experience issues if the first bitmap is smaller than the second, but then why would you want to overlay a bigger one over a smaller one?!)
     //EDIT: added Y offest fix - thanks @Jason Goff!
     canvas.drawBitmap(bmp2, (bmp1.getWidth()/2)-(bmp2.getWidth()/2), (bmp1.getHeight()/2)-(bmp2.getHeight/2), null);

    return bmOverlay;
}

public static Bitmap createNewBitmap(int width, int height)
{
            //create a blanks bitmap of the desired width/height
    return Bitmap.createBitmap(width, height, Config.ARGB_8888);
}
}

and heres the rest of my code using my BitmapHelper:

private void applyWallpaperFromFile(final File file)
{
    Bitmap wallpaperImage = BitmapFactory.decodeFile(file.getPath());
    try {
        if((wallpaperManager.getDesiredMinimumWidth()>0)&&(wallpaperManager.getDesiredMinimumHeight()>0))
        {
            Bitmap blank = BitmapHelper.createNewBitmap(wallpaperManager.getDesiredMinimumWidth(), wallpaperManager.getDesiredMinimumHeight());
            Bitmap overlay = BitmapHelper.overlayIntoCentre(blank, wallpaperImage);

            wallpaperManager.setBitmap(overlay);

        }
        else
        {
            wallpaperManager.setBitmap(wallpaperImage);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(WallpaperActivity.this,"Wallpaper set to:"+file.getName(), Toast.LENGTH_SHORT).show();

        }
    });

}

Upvotes: 10

Jason Goff
Jason Goff

Reputation: 131

Thanks for the article. I found that my wallpapers were getting jammed into the top of my device screen, so I changed the overlayIntoCentre method slightly, substituting the 0 in the second drawBitmap call for the height calculation below.

public static Bitmap overlayIntoCentre(Bitmap bmp1, Bitmap bmp2) {
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
    Canvas canvas = new Canvas(bmOverlay);
    canvas.drawBitmap(bmp1, new Matrix(), null);//draw background bitmap

    //overlay the second in the centre of the first 
    //(may experience issues if the first bitmap is smaller than the second, but then why would you want to overlay a bigger one over a smaller one?!)
    canvas.drawBitmap(bmp2, (bmp1.getWidth()/2)-(bmp2.getWidth()/2), (bmp1.getHeight()/2)-(bmp2.getHeight/2), null);

return bmOverlay;

}

Upvotes: 4

Joni
Joni

Reputation: 31

You may want to have a look at this again: http://developer.android.com/reference/android/app/WallpaperManager.html#suggestDesiredDimensions(int, int)

From the developer reference:

public void suggestDesiredDimensions (int minimumWidth, int minimumHeight)

Since: API Level 5 For use only by the current home application, to specify the size of wallpaper it would like to use. This allows such applications to have a virtual wallpaper that is larger than the physical screen, matching the size of their workspace.

Note developers, who don't seem to be reading this. This is for home screens to tell what size wallpaper they would like. Nobody else should be calling this! Certainly not other non-home-screen apps that change the wallpaper. Those apps are supposed to retrieve the suggested size so they can construct a wallpaper that matches it.

Upvotes: 2

user510164
user510164

Reputation: 646

you can try using suggestDesiredDimensions() method

Upvotes: -1

Related Questions