Search code examples
androidwallpaperhomescreen

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

Solution

  • 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();
    
            }
        });
    
    }