Skip to main content

Android Live Wallpaper Tutorial (using Android Studio 3.x) | FaultInMyCode

The Android Live Wallpapers are the way to redesign your mobile background into something amazing animated GIF using different effects and motions. Many novice developers are making good money by Henceforth here is Android Live Wallpaper tutorial for you to build your own Live wallpaper and start earning today as a developer!

Android Live Wallpaper Tutorial
Android Live Wallpaper Tutorial


This tutorial is a part of our Blog series on ‘Roadway to Android Development Course’, its suitable for Beginners to programming as well as the android enthusiast to learn about Android development and build their own apps.

In this tutorial for beginners, you’ll learn how by using Android Studio 3.0 and by having basic knowledge of Java, we will teach you to build your own Live wallpaper for Android which you may later publish in the Google Play Store. We assume you have some experience with Android studio, if not please check how to build your own calculator app and how to create simple login app in Android Studio 3.x tutorial.

How to build Android Live Wallpaper App?

To build an Android Live Wallpaper app, the first thing we will need to do is to declare the feature that the app will use (i.e, live wallpaper) in the Manifest file (we will show in the tutorial below) and also the service that will contain the name of a permission that the app must have in order to launch the service or bind to it.

Once this is done, we will create java file named ‘GIFWallpapaerService’ (which is a service as declared in AndroidManifest.xml) in which we create GIFWallpaperService which extends WallpaperService.Engine so that android gets to know when and what to display as GIF wallpaper and when to hide or destroy it also for effective use of memory and mobile battery.

However such services requires android.permission.BIND_WALLPAPER and must be registered via an <intent-filter> for the android.service.wallpaper.WallpaperService action in AndroidManifest.xml.

Here is a sneak peak at what you’ll build today. (Disclaimer: You may not like the wallpaper but you can use any other)

Android Live Wallpaper Tutorial
Android Live Wallpaper Tutorial

Steps to Follow for Android Live Wallpaper App Tutorial

1.Create a New project in Android Studio (We are using version 3.x) named ‘DayTime’

2. Select ‘Empty Activity’ as your base template. Follow the process further and click finish.

3. Open AndroidManifest.xml from the Manifest folder and declare the feature used by the app.

<uses-feature
    android:name="android.software.live_wallpaper"
    android:required="true"></uses-feature>
 
4. Now create service tag after <application> tag, here we will declare service for our app and set required permissions, android.permission.BIND_WALLPAPER and use  <intent-filter> for the android.service.wallpaper.WallpaperService action.

<service
    android:name=".GIFWallpaperService"
    android:enabled="true"
    android:label="DayTime LWP"
    android:permission="android.permission.BIND_WALLPAPER">
    <intent-filter>
        <action android:name="android.service.wallpaper.WallpaperService" />
    </intent-filter>
 
5. Also we will have some meta data here, its an additional information that will be used to declare App name and set icon in Live wallpaper settings of our android app.

<meta-data
    android:name="android.service.wallpaper"
    android:resource="@xml/wallpaper"></meta-data>
 
Here is the compete XML code from AndroidManifest.xml file.

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

    <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:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <service
            android:name=".GIFWallpaperService"
            android:enabled="true"
            android:label="DayTime LWP"
            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>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 
6. Open activity_main.xml file and code the layout of your app. We have used Linear layout with vertical orientation here in which there is a image view of our app, TextView and a button with ‘onClick()’ method declared inMainActivity.java file.

Here is the complete code from activity_main.xml file.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.faultinmycode.daytime.MainActivity">

    <LinearLayout
        android:backgroundTint="@android:color/black"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="386dp"
            android:background="@drawable/icon" />


        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Tutorial series by Faultinmycode.com"
            android:layout_marginBottom="10sp"
            android:textAlignment="center"
            android:textSize="24sp"
            android:textStyle="bold"/>

        <Button
            android:id="@+id/ic1"
            android:layout_width="match_parent"
            android:layout_height="61dp"
            android:background="@color/colorPrimary"
            android:onClick="onClick"
            android:tag="1"
            android:textSize="20sp"
            android:text="Set Wallpaper" />


    </LinearLayout>

</android.support.constraint.ConstraintLayout>
 
7. Now in Project window (See on the Left side of Android Studio v3.x), go to java folder (inside app > java), right click and create a new java file with name, ‘GIFWallpaperService.java’.

8. Once the file is created, extend GIFWallpaperService class to WallpaperService.

public class GIFWallpaperService extends WallpaperService {
 
9. A wallpaper service may have multiple instances running (for example as a real wallpaper and as a preview), each of which is represented by its own Engine instance. Therefore we will implement onCreateEngine() to return concrete Engine implementation.

@Override
public WallpaperService.Engine onCreateEngine() {
    try {
        Movie movie = Movie.decodeStream(
                getResources().getAssets().open("daytime.gif"));

        return new GIFWallpaperEngine(movie);
    }catch(IOException e){
        Log.d("GIF", "Could not load asset");
        return null;
    }
}
 
10. In the code above we have implemented an onCreateEngine() and declared our GIF Wallpaper (which is ‘daytime.gif’, resources will be made available in the links below after the blog!). The try { } catch { } is a Java code in which try block is used to enclose the code that might throw an exception. It must be used within the method.

11. Now create a private GIFWallpaperEngine which extends WallpaperService.Engine that will be used to display Graphic component movie, i.e, daytime.gif.

    public GIFWallpaperEngine(Movie movie) {
        //A Handler allows you to send and process Message and Runnable objects associated
        //with a thread's MessageQueue
        this.movie = movie;
        handler = new Handler();
                }
 
12. In the code above we have used the Handler to help run the GIF movie and using the surfaceholder() as shown below we are setting GIF as wallpaper.

public void onCreate(SurfaceHolder surfaceHolder) {
    /** Abstract interface to someone holding a display surface. Allows you to control
     the surface size and format, edit the pixels in the surface, and monitor changes
     to the surface. This interface is typically available through the SurfaceView class.
     **/
    super.onCreate(surfaceHolder);
    this.holder = surfaceHolder;

}
 
13. Now the Runnable interface below will help us to run the draw method in the thread.

private Runnable drawGIF = new Runnable() {
    public void run() {
        draw();
    }
};
 
14. In this example to draw the GIF wallpaper in the background, we need 3 basic components: the holder (declared above) to hold the pixels, a Canvas to host the draw calls (writing into the holder), a drawing primitive (i.e, the DayTime GIF in this example). Well having said we have coded the draw method below:

private void draw() {
    if (visible) {
        Canvas canvas = holder.lockCanvas();
        canvas.save();
        // Adjust size and position so that
        // the image looks good on your screen
        canvas.scale(1f, 1f);
        movie.draw(canvas, 0, 0);
        canvas.restore();
        holder.unlockCanvasAndPost(canvas);
        movie.setTime((int) (System.currentTimeMillis() % movie.duration()));

        handler.removeCallbacks(drawGIF);
        handler.postDelayed(drawGIF, frameDuration);
    }
}
 
15. You must have heard that Live Wallpapers consume lots of memory and battery, however you wouldn’t like your user to uninstall the app because of this. Therefore we will use the onVisibility() method over here to prevent battery and memory drain which will disable wallpaper when the view is changed and wallpaper is no longer visible!

public void onVisibilityChanged(boolean visible) {
    //Called when the visibility of the view or an ancestor of the view has changed.
    this.visible = visible;
    if (visible) {
        handler.post(drawGIF);
    } else {
        handler.removeCallbacks(drawGIF);
    }
}
 
16. Finally we need the destroy method to destroy our wallpaper.

@Override
public void onDestroy() {
    super.onDestroy();
    handler.removeCallbacks(drawGIF);
}
 
Here is the complete code from GIFWallpaperService.java file.

GIFWallpaperService.java
package com.faultinmycode.daytime;

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 GIFWallpaperService extends WallpaperService {

    @Override
    public WallpaperService.Engine onCreateEngine() {
        try {
            Movie movie = Movie.decodeStream(
                    getResources().getAssets().open("daytime.gif"));

            return new GIFWallpaperEngine(movie);
        }catch(IOException e){
            Log.d("GIF", "Could not load asset");
            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) {
            //A Handler allows you to send and process Message and Runnable objects associated
            //with a thread's MessageQueue
            this.movie = movie;
            handler = new Handler();
                    }

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            /** Abstract interface to someone holding a display surface. Allows you to control
             the surface size and format, edit the pixels in the surface, and monitor changes
             to the surface. This interface is typically available through the SurfaceView class.
             **/
            super.onCreate(surfaceHolder);
            this.holder = surfaceHolder;

        }

        //The Runnable interface should be implemented by any class whose instances are intended to
        // be executed by a thread. The class must define a method of no arguments called run.
        private Runnable drawGIF = new Runnable() {
            public void run() {
                draw();
            }
        };


        private void draw() {
            if (visible) {
                Canvas canvas = holder.lockCanvas();
                canvas.save();
                // Adjust size and position so that
                // the image looks good on your screen
                canvas.scale(1f, 1f);
                movie.draw(canvas, 0, 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) {
            //Called when the visibility of the view or an ancestor of the view has changed.
            this.visible = visible;
            if (visible) {
                handler.post(drawGIF);
            } else {
                handler.removeCallbacks(drawGIF);
            }
        }


        @Override
        public void onDestroy() {
            super.onDestroy();
            handler.removeCallbacks(drawGIF);
        }
    }
}
17. Now go to MainActivity.java and set the Intent in onClick() method to set wallpaper when button in main_activity.xml file is clicked!
public void onClick(View view)
{
    Intent intent = new Intent(
            WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
    intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
            new ComponentName(this, GIFWallpaperService.class));
    startActivity(intent);
}
 
Here is the complete code from MainActivity.java file.

MainActivity.java
package com.faultinmycode.daytime;

import android.app.WallpaperManager;
import android.content.ComponentName;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClick(View view)
    {
        Intent intent = new Intent(
                WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
        intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                new ComponentName(this, GIFWallpaperService.class));
        startActivity(intent);
    }
}
 
18. Now go to Project View (on the Left side window), inside res folder create Android resource directory named, ‘xml’, inside this directory create a resource file named ‘wallpaper.xml’

<?xml version="1.0" encoding="utf-8"?>
<wallpaper
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="DayTime LWP"
    android:thumbnail="@drawable/icon">
</wallpaper>
 
19. Create Assets folder in app folder (Do this in Explorer) and copy ‘daytime.gif’ file here and ‘icon.png’ inside drawable folder (inside res).

20. Run and test your app, if in case you face some issue let us know in comments section below.

Download Android Daytime Live Wallpaper tutorial Project from link here

Comments

  1. Hey, I like your work. I can't get this application working, any chance you could let me know what version of android studio you are running of this or what emulator version I should be using? I tried finding a contact for the site but couldn't find anything, you should add that on the site! Cheers dude/ets

    ReplyDelete
    Replies
    1. I'm was using Android Studio 3.x for this, btw can you detail me on error a bit, i can help!

      Delete
    2. What details on the error do you need? (I don't really know much about android) I Downloaded the files you have provided and I'm using Android Studio 3.1.2, I added the assets and it doesn't seem to be working. Did I miss a step?

      Delete
    3. Can you plz brief on what error you are facing, check your Android studio Logcat, that's what you get after running your app and then press Alt + 6

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. when i changed another live wallpaper in Recycler View it's not updating . please give me solution to this problem

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hi there, I have copied the tutorial exactly, but I'm getting an error about a null object reference.

    2018-09-29 18:39:47.272 4848-4848/com.stonehearts.livetutorialwallpaper D/GIF: Could not load asset
    2018-09-29 18:39:47.272 4848-4848/com.stonehearts.livetutorialwallpaper D/AndroidRuntime: Shutting down VM
    2018-09-29 18:39:47.273 4848-4848/com.stonehearts.livetutorialwallpaper E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.stonehearts.livetutorialwallpaper, PID: 4848
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.service.wallpaper.WallpaperService$Engine.attach(android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper)' on a null object reference

    I assume this means daytime.gif isn't getting found? I put in the assets folder as well as the drawable folder just incase. The location of the gif is app/assets/daytime.gif is that correct?

    ReplyDelete

Post a Comment

Popular posts from this blog

How To Open PDF File in Android Application Example Included

Want to know How To Open PDF File in Android Application Example. To open a PDF File in Android Application, your app can take help from Free Android library available on Github.

Here are few apps made from PDF Library you can look at, click here to know more.

By using Android Library you are not only leveraging the hard work from another developer but also making it easier and quicker to develop an android app.
How To Open PDF File in Android Application Example  In this tutorial series, we will teach you how to open a pdf file in Android Application Example included with the help of Android PDFViewer library developed by Barteksc.

Get inspirtion from here: Top 7 PDF Download for Mobile Android Apps

Before I proceed further, here is the screenshot of the kind of PDF Viewer that’ll be created using Android Studio.



 How To Open PDF File in Android Application Example

The app will open a specified pdf file which will be copied in the assets folder of your Android studio project. I'v…

Open Weather Map API Example | Create Android Weather App

In this tutorial blog, using open weather map API example, we will create an Android weather app. The Android App will able to access Open weather map website server and access weather details of particular location.

The App will look similar to the image shown below. It will fetch real time weather of the location provided in MainActivity.Java file.


Software / Files used:Android Studio (Version 3.x) Files Edited / Created:activity_main.xmlMainActivity.JavaWeather.JavaAndroidManifest.xml Steps Involved in Open Weather Map API Example: Here are the Steps you need to follow on ‘Open Weather map API Example’ to create Android Weather App:

1. Open the Open Weather map API link provided here. Sign up for Current Weather Data API key here.

2. Once the key is received, save it to notepad or on stick notes.

3. Open Android Studio and create a new Project with name, ‘FIMC Weather App’, we will select an empty activity in the wizard and wait for Gradle build.



4. Open AndroidManifest.xml…