Some nice guy called Patrick Nagelschmidt contributed a wallpaper backend. After much refucktoring, i was able to make it work seamlessly with the rest of libgdx. Here are the instructions. Note that input is still a bit of a WIP, and i didn’t test on a multitude of devices yet. Maybe you guys can help 🙂 The nightlies should be ready in half an hour, they contain the new classes in the Android backend. Also, i extended gdx-tests-android to also install a livewallpaper that displays the WaterRipples test, see LiveWallpaper.java, LiveWallpaperSettings.java which is just dummy for a settings Activity, livewallpaper.xml which declares metadata for the wallpaper, and finally the modified AndroidManifest.xml.

The starter class for a livewallpaper is called AndroidLiveWallpaperService, here’s an example:

package com.mypackage; // imports snipped for brevity public class LiveWallpaper extends AndroidLiveWallpaperService { @Override public ApplicationListener createListener () { return new MyApplicationListener(); } @Override public AndroidApplicationConfiguration createConfig () { return new AndroidApplicationConfiguration(); } @Override public void offsetChange (ApplicationListener listener, float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { Gdx.app.log("LiveWallpaper", "offset changed: " + xOffset + ", " + yOffset); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com . mypackage ; // imports snipped for brevity public class LiveWallpaper extends AndroidLiveWallpaperService { @ Override public ApplicationListener createListener ( ) { return new MyApplicationListener ( ) ; } @ Override public AndroidApplicationConfiguration createConfig ( ) { return new AndroidApplicationConfiguration ( ) ; } @ Override public void offsetChange ( ApplicationListener listener , float xOffset , float yOffset , float xOffsetStep , float yOffsetStep , int xPixelOffset , int yPixelOffset ) { Gdx . app . log ( "LiveWallpaper" , "offset changed: " + xOffset + ", " + yOffset ) ; } }

The methods createListener() and createConfig() will be called when your livewallpaper is shown in the picker or when it is created to be displayed on the home screen.

The offsetChange() method is scaled when the user swipes through screens on the home screen and tells you by how much the screen is offset from the center screen. This method will be called on the rendering thread, so you don’t have to synchronize anything.

In addition to a starter class, you also have to create an XML file describing your wallpaper. Let’s call that livewallpaper.xml. Create a folder called xml/ in your Android project’s res/ folder and put the file in there (res/xml/livewallpaper.xml). Here’s what to put into that file:

<?xml version="1.0" encoding="UTF-8"?> <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@drawable/ic_launcher" android:description="@string/description" android:settingsActivity="com.mypackage.LivewallpaperSettings"/> 1 2 3 4 5 6 <? xml version = "1.0" encoding = "UTF-8" ?> <wallpaper xmlns : android = "http://schemas.android.com/apk/res/android" android : thumbnail = "@drawable/ic_launcher" android : description = "@string/description" android : settingsActivity = "com.mypackage.LivewallpaperSettings" />

This defines the thumbnail to be displayed for your LWP in the picker, the description and an Activity that will be displayed when the user hits “Settings” in the LWP picker. This should be just a standard Activity that has a few widgets to change settings such as the background color and similar things. You can store those settings in SharedPreferences and load them later in your LWPs ApplicationListener via Gdx.app.getPreferences().

Finally, you’ll need to add things to your AndroidManifest.xml file. Here’s an example for an LWP with a simple settings Activity:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mypackage" android:versionCode="1" android:versionName="1.0" android:installLocation="preferExternal"> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14"/> <uses-feature android:name="android.software.live_wallpaper" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".LivewallpaperSettings" android:label="Livewallpaper Settings"/> <service android:name=".LiveWallpaper" android:label="@string/app_name" android:icon="@drawable/icon" 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="@xml/livewallpaper" /> </service> </application> </manifest> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <? xml version = "1.0" encoding = "utf-8" ?> <manifest xmlns : android = "http://schemas.android.com/apk/res/android" package = "com.mypackage" android : versionCode = "1" android : versionName = "1.0" android : installLocation = "preferExternal" > <uses-sdk android : minSdkVersion = "7" android : targetSdkVersion = "14" /> <uses-feature android : name = "android.software.live_wallpaper" /> <application android : icon = "@drawable/icon" android : label = "@string/app_name" > <activity android : name = ".LivewallpaperSettings" android : label = "Livewallpaper Settings" /> <service android : name = ".LiveWallpaper" android : label = "@string/app_name" android : icon = "@drawable/icon" 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 = "@xml/livewallpaper" /> </service> </application> </manifest>

The manifest defines:

it uses the live wallpaper feature, see .

a permission to be allowed to bind the wallpaper, see android:permission

the settings activity

the livewallpaper service, pointing at the livewallpaper.xml file, see meta-data

Note that livewallpapers are only supported starting from Android 2.1 (SDK level 7).

LWPs have some limitations concerning touch input. In general only tap/drop will be reported. If you want full touch you can see the AndroidApplicationConfiguration#getTouchEventsForLiveWallpaper flag to true to receive full multi-touch events.

Please test this thing and report any issues you have. Chances are that OpenGL context and surfaceview handling might be broken on some devices, which seems to be a problem of all OpenGL based LWP implementations. I couldn’t find an issue yet.