1

If you vote to close this, please explain why.

Background

For my tiny live wallpaper app (here), I offer to import previous wallpaper. I've noticed an issue of targeting API 33 that will cause me to use a more broad storage permission (written here and here).

The problem

In addition to the problematic storage permission, I've noticed that even getting the current live wallpaper is problematic.

What I've found is that without QUERY_ALL_PACKAGES , I can't find the current live wallpaper using getWallpaperInfo:

val wallpaperManager: WallpaperManager =...
val wallpaperInfo = wallpaperManager.wallpaperInfo

And I know that if I use this, I might have trouble publishing the app on the Play Store. I already have such an issue for the storage permission...

What I've tried

I know of the queries tag in the manifest, so I tried this, but it didn't work:

   <queries>
        <intent >
            <action android:name="android.service.wallpaper.WallpaperService"/>
        </intent>
    </queries>

The logic behind trying this, is that live wallpaper apps have to have this:

        <service
            android:name="..."
            android:exported="true"
            android:label="..."
            android:permission="android.permission.BIND_WALLPAPER">
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
            </intent-filter>

            <meta-data
                android:name="android.service.wallpaper" android:resource="..." />
        </service>

The question

Is there any way to avoid using QUERY_ALL_PACKAGES permission, and still reliably be able to reach this API of getting the current live wallpaper?

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Maybe show a new Activity which can get the current wallpaper? – CoolMind Dec 21 '22 at 11:08
  • @CoolMind I don't understand your suggestion. What difference would it make to have yet another Activity? The permission is needed, whether it's on one Activity or the other... – android developer Dec 21 '22 at 21:10
  • @CoolMind No, that's not how it works. – android developer Dec 22 '22 at 07:57
  • If you want to use it you will definitely need to report to Android about your use case. REF: https://developer.android.com/about/versions/12/non-sdk-12#list-changes – Android Newbie A Dec 23 '22 at 09:45
  • 1
    @AndroidNewbieA First, your link is about Android 12. I'm talking about Android 13. Second, you are talking about hidden APIs on Java. Not public one as I've shown, which got restricted (either on purpose or not) and not about Android framework, either : https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces#feature-request – android developer Dec 23 '22 at 09:51

2 Answers2

1

QUERY_ALL_PACKAGES permission is required and enforced directly by wallpaper manager there is no way around it.

Tho if you just want to get current wallpaper info you can use something like this

  <queries>
        <intent>
            <action android:name="android.service.wallpaper.WallpaperService"/>
        </intent>
    </queries>
       val currentWallpaperService = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            packageManager.resolveService(
                Intent(WallpaperService.SERVICE_INTERFACE),
                PackageManager.ResolveInfoFlags.of(PackageManager.GET_META_DATA.toLong())
            )
        } else {
            packageManager.resolveService(
                Intent(WallpaperService.SERVICE_INTERFACE),
                PackageManager.GET_META_DATA
            )
        }

        val wallpaperInfo =  WallpaperInfo(this, currentWallpaperService)
Pratyush
  • 401
  • 3
  • 11
  • I tested it , and for some reason it doesn't always work. Tried it on this live wallpaper app, after I've set it : https://play.google.com/store/apps/details?id=net.nurik.roman.muzei . For some reason, it insisted that I have a live wallpaper with this package name, instead (which I might have, but it's not correct anymore) : "com.google.android.wallpaper.effects" – android developer Dec 22 '22 at 22:21
  • I tried to use `packageManager.queryIntentServices` instead, and indeed it gave me the current live wallpaper, but also all the others. – android developer Dec 23 '22 at 00:41
1

It seems Google has noticed this issue, and made some adjustments so that at least on Android 14 the query I've mentioned would work:

Returns the information about the home screen wallpaper if its current wallpaper is a live wallpaper component. Otherwise, if the wallpaper is a static image, this returns null.

In order to use this, apps should declare a tag with the action "android.service.wallpaper.WallpaperService". Otherwise, this method will return null if the caller doesn't otherwise have visibility of the wallpaper package.

So, if your app is supposed to run on Android 13 and below, QUERY_ALL_PACKAGES is required, but on Android 14 and above, you should be fine with just a query.

For once, the Play policy team also approves this kind of thing. This is as opposed to fetching the wallpaper image, which requires MANAGE_EXTERNAL_STORAGE permission:

https://issuetracker.google.com/issues/237124750

In any case, the solution is:

<uses-permission
    android:name="android.permission.QUERY_ALL_PACKAGES" android:maxSdkVersion="33"
    tools:ignore="QueryAllPackagesPermission" />

<queries>
    <intent>
        <action android:name="android.service.wallpaper.WallpaperService"/>
    </intent>
</queries>
android developer
  • 114,585
  • 152
  • 739
  • 1,270