Creating Android live wallpaper

Download source code of this article.

As you all know live wallpaper is introduced in Android from version 2.1 onwards. Live wallpapers are animated backgrounds for your home screen. You can set your live wallpaper by long pressing the home screen and selecting Wallpapers->Live Wallpaper menu item. A list of live wallpapers installed in the system will be shown and you can select one of them to make it active. Live Wallpaper is like a normal application Android and can use any feature that normal application uses like MapView, Accelerometer, GPS, etc.

Live Wallpaper is like a normal service application in Android. It has two components, WallpaperService and WallpaperService.Engine. The service component is like normal service application but with extra method onCreateEngine(). The purpose of this method is to return a instance of Wallpaper.Engine class which actually do all the tasks including drawing wallpaper and managing the lifetime. The WallpaperService will call the onCreateEngine() method when a wallpaper is active. A wallpaper can provide a settings screen if needed. Settings screen can be used to configure the wallpaper (in our sample application we provide this settings screen to select the pattern to draw on the wallpaper screen, see the sample application section).

To create our own wallpaper we create the WallpaperService and override the onCreateEngine method. Then specify the wallpaper in AndroidManifest.xml file. Following is sample manifest entry:

<application android:label="@string/app_name" android:icon="@drawable/icon">
	<service android:label="@string/wallpaper_pattern" android:permission="android.permission.BIND_WALLPAPER" android:name="com.varma.samples.patternwallpaper.PatternWallpaper">
        	<intent-filter>
                	<action android:name="android.service.wallpaper.WallpaperService" />
		</intent-filter>
            	<meta-data android:name="android.service.wallpaper" android:resource="@xml/patternwallpaper" />
        </service>

	<activity android:label="@string/wallpaper_settings" android:name="com.varma.samples.patternwallpaper.PatternWallpaperSettings" android:exported="true"/>

</application>

The <service> specifies our wallpaper service. The <intnet-filter> should be android.service.wallpaper.WallpaperService. We should create an XML resource that specify our wallpaper service and give it in <meta-data> tag to describe the wallpaper. Finally we have to specify the settings activity if there is any. In addition to this, we have to specify the <users-sdk> and <uses-feature> tags, the <users-sdk> tag should specify 7 or above since the feature is only available 7 or above. A sample entry is:

<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />

Once we specify these entries we create a service and extend from WallpaperService class and override the onCreateEngine method. From this method we return our own instance of WallpaperService.Engine implementation. The system will provide a SurfaceView class for drawing purpose. The WallpaperService.Engine has following important method which we have to override to implement the wallpaper engine:

public void onCreate(SurfaceHolder surfaceHolder) Called while creating the Wallpaper.Engine object. Note that the system provides a SurfaceHolder implementation
public void onDestroy() Called while destroying the object
public void onOffsetsChanged(

float xOffset,

float yOffset,

float xOffsetStep,

float yOffsetStep,

int xPixelOffset,

int yPixelOffset)

Called when offsets changed.
public void onSurfaceChanged(

SurfaceHolder holder,

int format,

int width,

int height)

Called when the SurfaceHolder’s surface is changed.
public void onSurfaceCreated(SurfaceHolder holder) Called when the SurfaceHolder’s surface is created.
public void onSurfaceDestroyed(SurfaceHolder holder) Called when the SurfaceHolder is destroyed.
public void onVisibilityChanged(boolean visible) Called when the visibility of the wallpaper changed. The parameter visible is true when visible otherwise false. Here we have to start and stop drawing depending on the visibility.
public void onTouchEvent (MotionEvent event) Called when touch events occurred. There are different events, some of them are:

android.wallpaper.tap

when the user taps the home screen.

android.home.drop

when the user drops an icon on home screen.

Our sample application does not use onTouchEvent but a live wallpaper can use this to implement different effects.

Normally while creating wallpaper we override these method and start ad stop the drawing in onVisibilityChanged. For drawing the wallpaper we create separate thread or a runnable routine. The following code snippet creates a runnable routine:

private final Runnable drawrunnable = new Runnable() {
	public void run() {
		draw();
	}
};


 

The draw method actually draws the wallpaper. In this method we post the drawrunnable routine every 5 seconds using a Handler class. The draw method implementation is (from sample application):

private void draw(){
	final SurfaceHolder holder = getSurfaceHolder();
	Canvas canvas = null;

	handler.removeCallbacks(drawrunnable);

	try
	{
		canvas = holder.lockCanvas();

		drawPattern(canvas);
	}
	finally
	{
		if (canvas != null)
			holder.unlockCanvasAndPost(canvas);
	}

	if(isVisible)
	{
		handler.postDelayed(drawrunnable,DRAW_DELAY);
	}
}

Sample Application

The sample application of this article is a simple live wallpaper that draws three different pattern; spirograph, circle pattern and sierpinski triangle. Use can choose the pattern to draw. The pattern is drawn with random values in every 5 seconds.

Following are some of the screenshots of the application:

spirograph circlepattern sierpinski

Hope this article is helpful.

Happy Live Wallpaper coding! Smile

6 Comments

Add yours →

  1. Thanks u so much, this article was very helpful and easy to understand while implementing Live Wallpaper.

  2. i loved the way you explained !!!really amazing article…

  3. I loved the way you explain.Very simple you made it for me to start working on livewallpaper!!

  4. Is it possible to change an Installed Wallpaper programmatically? I mean via my Application to manage the installed wallpapers?

  5. Most of the time, the live wallpaper doesn’t work in emulator. Try with a real device. (samsung galaxy for greats!)

  6. I have created one launcher activity from which user had the option to set wallpaper(this activty is having one button) which calls following code:
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

    if (Build.VERSION.SDK_INT >= 16) {
    /*
    * Open live wallpaper preview (API Level 16 or greater).
    */
    Intent intent = new Intent();
    intent.setAction(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
    String pkg = Service.class.getPackage().getName();
    String cls = Service.class.getCanonicalName();
    intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
    new ComponentName(pkg, cls));

    startActivityForResult(intent, 0);
    // finish();

    } else {
    /*
    * Open live wallpaper picker (API Level 15 or lower).
    * Display a quick little message (toast) with instructions.
    */
    Intent intent = new Intent();
    intent.setAction(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER);
    Resources res = getResources();
    String hint = res.getString(R.string.picker_toast_prefix)
    + res.getString(R.string.lwp_name)
    + res.getString(R.string.picker_toast_suffix);
    Toast toast = Toast.makeText(TestPreview.this, hint, Toast.LENGTH_LONG);
    toast.show();

    TestPreview.this.startActivity(new Intent(“android.service.wallpaper.LIVE_WALLPAPER_CHOOSER”));
    }

    }
    });

    But the problem is the screen which displays the change wallpaper screen is not loading on button click.

Leave a Reply