Live Wallpaper in Android

Live wallpaper is richer, animated, interactive backgrounds on the home screen of Android devices. A live wallpaper is very similar to a normal Android application and has access to all the facilities of the platform: SGL (2D drawing), OpenGL (3D drawing), GPS, accelerometers, network access, etc.

A live wallpaper is very similar to a regular Android service. The only difference is the addition of a new method, onCreateEngine() whose goal is to create a WallpaperService.Engine. The engine is responsible for handling the lifecycle and the drawing of a wallpaper.

Here, I am showing a general method for creating Live Wallpaper. According to our requirement or to our wish, we can draw some image when we touch anywhere on the screen, or according to the time, we can set different images like for morning from 6AM to 12PM, then 12PM to 6PM another image like that. or according to the location, we can set some image. In office one image, in home, another image like that.

First thing for creating Live Wallpaper in android is, declare the service in manifest file.


<service android:label="@string/wallpaper_cube1"
android:name=".LiveWallpaper"
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>


A file named "livewallpaper.xml" should be placed in res/xml, which should look like this as,


<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
/>


In the manifest file, we also need to put,


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


Live Wallpaper is from 2.1 SDK onwards.


The implementation of the live LiveWallpaper.java is as,


public class LiveWallpaperService extends WallpaperService {

@Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
super.onDestroy();
}
public class WallpaperEngine extends Engine {
private LiveWallpaperPainting painting;

WallpaperEngine () {
SurfaceHolder holder = getSurfaceHolder();
painting = new LiveWallpaperPainting(holder,
getApplicationContext());
}

@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}

@Override
public void onDestroy() {
super.onDestroy();
painting.stopPainting();
}

@Override
public void onVisibilityChanged(boolean visible) {
if (visible) {
painting.resumePainting();
} else {
painting.pausePainting();
}
}

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
painting.setSurfaceSize(width, height);
}

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
// start painting
painting.start();
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
boolean retry = true;
painting.stopPainting();
while (retry) {
try {
painting.join();
retry = false;
} catch (InterruptedException e) {}
}
}

@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
}

@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
painting.doTouchEvent(event);
}
}
}



The "LiveWallpaperPainting .java" is as follows,


public class LiveWallpaperPainting extends Thread {

private SurfaceHolder surfaceHolder;
private Context context;

private boolean wait;
private boolean run;

private int width;
private int height;

private long previousTime;
private long currentTime;

public LiveWallpaperPainting(SurfaceHolder surfaceHolder,
Context context) {
this.surfaceHolder = surfaceHolder;
this.context = context;
this.wait = true;
}

public void pausePainting() {
this.wait = true;
synchronized(this) {
this.notify();
}
}

public void resumePainting() {
this.wait = false;
synchronized(this) {
this.notify();
}
}

public void stopPainting() {
this.run = false;
synchronized(this) {
this.notify();
}
}

@Override
public void run() {
this.run = true;
Canvas c = null;
while (run) {
try {
c = this.surfaceHolder.lockCanvas(null);
synchronized (this.surfaceHolder) {
currentTime = System.currentTimeMillis();
updatePhysics();
doDraw(c);
previousTime = currentTime;
}
} finally {
if (c != null) {
this.surfaceHolder.unlockCanvasAndPost(c);
}
}
synchronized (this) {
if (wait) {
try {
wait();
} catch (Exception e) {}
}
}
}
}

public void setSurfaceSize(int width, int height) {
this.width = width;
this.height = height;
synchronized(this) {
this.notify();
}
}

public void doTouchEvent(MotionEvent event) {
this.wait = false;
synchronized(this) {
notify();
}
}

private void doDraw(Canvas canvas) {}

private void updatePhysics() {
// if nothing was updated :
// this.wait = true;
}

}

Comments

Popular posts from this blog

AlarmManager and Notification in Android

Swipe Action and ViewFlipper in Android

Difference between SurfaceView and View in Android