Search code examples
androidlockscreenandroid-wallpaper

How to get android lock screen wallpaper?


I use the code below to retrieve the android lock screen wallpaper on an android 8.1 phone:

WallpaperManager manager = WallpaperManager.getInstance(getActivity());
ParcelFileDescriptor pfd = manager.getWallpaperFile(WallpaperManager.FLAG_LOCK);
if (pfd == null) // pfd is always null for FLAG_LOCK, why?
    return;
Bitmap lockScreenWallpaper = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
// ...

I have granted the READ_EXTERNAL_STORAGE permission and set a lock screen wallpaper beforehand.

I run the demo on a real phone, and found the pfd is always null for FLAG_LOCK, so I cannot get the lock screen wallpaper. Please help fix the problem, thanks.


Solution

  • I find the answer myself, I hope it can help others with the same question.

    The official docs for getWallpaperFile says: If no lock-specific wallpaper has been configured for the given user, then this method will return null when requesting FLAG_LOCK rather than returning the system wallpaper's image file.

    The description is vague, at least not clear enough, what does it mean? If you set a photo as both lock screen and home screen wallpaper, the two share the same file, then by calling

    ParcelFileDescriptor pfd = wallpaperManager.getWallpaperFile(WallpaperManager.FLAG_LOCK);
    

    pfd will always be null, then you should get the lock screen wallpaper this way:

    if (pfd == null)
        pfd = wallpaperManager.getWallpaperFile(WallpaperManager.FLAG_SYSTEM);
    

    you will get the non-null pfd. This is the case no lock-specific wallpaper has been configured.

    On the contrary, lock-specific wallpaper has been configured if you set a photo as lock screen wallpaper directly, wallpaperManager.getWallpaperFile(WallpaperManager.FLAG_SYSTEM) will return a non-null value.

    So this is the code I use to retrieve the lock screen wallpaper:

    /**
     * please check permission outside
     * @return Bitmap or Drawable
     */
    public static Object getLockScreenWallpaper(Context context)
    {
        WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
        if (Build.VERSION.SDK_INT >= 24)
        {
            ParcelFileDescriptor pfd = wallpaperManager.getWallpaperFile(WallpaperManager.FLAG_LOCK);
            if (pfd == null)
                pfd = wallpaperManager.getWallpaperFile(WallpaperManager.FLAG_SYSTEM);
            if (pfd != null)
            {
                final Bitmap result = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
    
                try
                {
                    pfd.close();
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
    
                return result;
            }
        }
        return wallpaperManager.getDrawable();
    }
    

    Don't forget to add READ_EXTERNAL_STORAGE in the manifest file and grant it outside.