1

I would to check if my Live Wallpaper App is set as Live Wallpaper.

The following code works on Android <= 12, but not in Android 13 (sdk 33).

public static boolean isLiveWallpaper(Context context) {
    if (Service._handler == null) {
        return false;
    }
    WallpaperManager wpm = WallpaperManager.getInstance(context);
    WallpaperInfo info = wpm.getWallpaperInfo();
    try {
        return (info != null && info.getPackageName().equals(context.getPackageName()));
    } catch (Exception e) {
        return false;
    }
}

On Android 13 wpm.getWallpaperInfo() always return null.

Why? I searched on Google and on the Android Developer Documentation, but I did'n find anything...

Edit: I set the live wallpaper with this code and it works, but I can't check programmatically if the live wallpaper is setted.

Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
        new ComponentName(context, Service.class));
context.startActivity(intent);
Simone Sessa
  • 795
  • 1
  • 12
  • 35
  • The docs on that function claims that it returns null for a static image, could this be the situation? – Paul T. Aug 28 '22 at 19:40
  • @PaulT. no, this is not it, I set the live wallpaper (I added a piece of code). And the same code works on previous versions (<= 12). – Simone Sessa Aug 29 '22 at 06:51
  • Then it sounds like an issue to possibly raise with Android for v13? Your example should be enough information for them to reproduce. – Paul T. Sep 02 '22 at 01:55

2 Answers2

2

Check the source code of WallpaperManagerService.java

    public WallpaperInfo getWallpaperInfo(int userId) {
    final boolean allow =
            hasPermission(READ_WALLPAPER_INTERNAL) || hasPermission(QUERY_ALL_PACKAGES);
    if (allow) {
        userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                Binder.getCallingUid(), userId, false, true, "getWallpaperInfo", null);
        synchronized (mLock) {
            WallpaperData wallpaper = mWallpaperMap.get(userId);
            if (wallpaper != null && wallpaper.connection != null) {
                return wallpaper.connection.mInfo;
            }
        }
    }

    return null;
}

We can see some permissions are needed to query the wallpaper info.

So, please add the following permission request in your AndroidManifest.xml

    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
Robin
  • 10,052
  • 6
  • 31
  • 52
  • Thank you, `QUERY_ALL_PACKAGES` works, but there is a warning: `A declaration should generally be used instead of QUERY_ALL_PACKAGES; - https://developer.android.com/training/package-visibility/declaring` Which is the correct query for the live wallpaper? Or do I have to use `QUERY_ALL_PACKAGES'? – Simone Sessa Sep 18 '22 at 11:54
  • If you are trying to find out if the current live wallpaper component is in a known list of packages, you can provide that entries in the query list. Otherwise, you cannot give a list of names which you don't know yet. But using QUERY_ALL_PACKAGES permission will require additional Google review when you publishing your app on GooglePlay, just be careful. – Robin Sep 21 '22 at 03:57
2

There is a bug reported to Google. I'm not sure if Google is going to fix it. This is the workaround I've been using. LiveWallpaperService.isEngineRunning can tell your app is set as LiveWallpaper or not.

class LiveWallpaperService : WallpaperService() {
    ...
    
    class MyEngine : WallpaperService.Engine() {
        ...

        override fun onCreate(surfaceHolder: SurfaceHolder) {
            if (!isPreview) {
                isEngineRunning = true
            }
        }
    
        override fun onDestroy() {
            if (!isPreview) {
                isEngineRunning = false
            }
        }
    }

    companion object {
       var isEngineRunning = false
    }
}
Chunhui Deng
  • 111
  • 1
  • 4