Skip to content

Instantly share code, notes, and snippets.

@ardovic
Last active August 15, 2023 04:06
Show Gist options
  • Save ardovic/f0c5b367cab2c6ec100be3e31ffe9c30 to your computer and use it in GitHub Desktop.
Save ardovic/f0c5b367cab2c6ec100be3e31ffe9c30 to your computer and use it in GitHub Desktop.
Sample GIF Wallpaper Service implementation (Android WallpaperService)
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;
import java.io.IOException;
public class SampleGIFWallpaperService extends WallpaperService {
@Override
public SampleGIFWallpaperService.Engine onCreateEngine() {
try{
Movie movie = Movie.decodeStream(getResources().getAssets().open("nature.gif"));
return new GIFWallpaperEngine(movie);
} catch(IOException e) {
Log.d("GIF", "Asset loading unsuccessful");
return null;
}
}
private class GIFWallpaperEngine extends WallpaperService.Engine {
private final int frameDuration = 20;
private SurfaceHolder holder;
private Movie movie;
private boolean visible;
private Handler handler;
public GIFWallpaperEngine(Movie movie) {
this.movie = movie;
handler = new Handler();
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
this.holder = surfaceHolder;
}
private Runnable drawGIF = new Runnable() {
@Override
public void run() {
draw();
}
};
private void draw() {
if(visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
// Adjust size and position of the wallpaper image
canvas.scale(3f, 3f);
movie.draw(canvas, -100, 0);
canvas.restore();
holder.unlockCanvasAndPost(canvas);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
handler.removeCallbacks(drawGIF);
handler.postDelayed(drawGIF, frameDuration);
}
}
@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if(visible) {
handler.post(drawGIF);
} else {
handler.removeCallbacks(drawGIF);
}
}
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawGIF);
}
}
}
@ardovic
Copy link
Author

ardovic commented Jun 3, 2019

This implementation also requires special declaration in AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.serjardovic.livewallpaper">

    <uses-feature
        android:name="android.software.live_wallpaper"
        android:required="true">
        </uses-feature>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <service android:name=".GIFWallpaperService"
            android:enabled="true"
            android:label="GIF Wallpaper"
            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/wallpaper">
            </meta-data>
        </service>
    </application>
</manifest>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment