Introduction
Starting with Android 2.1. (API Level 7), developers can create live wallpapers - richer, animated, interactive backgrounds - on their home screens. A live wallpaper is very similar to a normal Android application: you can create menu with settings, use SGL and OpenGL for drawing, accelerometer, etc.
In this article, I want to demonstrate how to create live wallpaper from scratch. Step-by-step, we will create live wallpaper that would output TV test pattern on out home screen. Just like on real TV during night hours!
This article will highlight the following aspects of Live Wallpaper development:
- Drawing on graphic primitives (circles, rectangles) using
android.graphics.Canvas
class - Developing of applications for screens with different resolution and orientation
- Creation of settings dialog for live wallpaper
- Reading of variables values for resource XML file
- Actual creation of live wallpaper for Android
Background
In this article, I show how to create a very simple live wallpaper.
On the internet, you can find much more profound and cooler apps, but I want you to check the following examples:
Using the Code
1. Making Android Virtual Device
As I mentioned earlier, we have to create an appropriate Android Virtual Device (AVD) to run our application.
Open Android SDK and AVD manager.
And create AVD with the following capabilities:
- Target platform Android 2.1 or higher
- With accelerometer support (we will add support for screen rotation detection)
- Touch-screen support
Resolution might be any. Our application will detect screen resolution and rescale graphic elements if necessary.
2. Creating Project Files
I named the app as LiveWallpaper
.
When creating Android project, set Build Target as Android 2.1.
By default, project will be created with the following files:
We have to change them slightly and add new files that would contain values for application's variables.
First, delete layout folder and main.xml file in res directory. This file is used for creating layout for application controls which we won't use in our project.
Instead of this, create folder xml where we will create two files livewallpaper.xml and livewallpaper_settings.xml that will contain values for live wallpaper service and settings dialog.
Livewallpaper.xml contains the following data:
="1.0"="utf-8"
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:settingsActivity="ca.jvsh.livewallpaper.LiveWallpaperSettings"
android:thumbnail="@drawable/icon"/>
Where wallpaper
tag says that we are creating live wallpaper service. This file will be processed during apk file creation.
Livewallpaper_settings.xml contains description of available settings for our live wallpaper:
="1.0"="utf-8"
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/livewallpaper_settings"
android:key="livewallpaper_settings">
<ListPreference
android:key="livewallpaper_testpattern"
android:title="@string/livewallpaper_settings_title"
android:summary="@string/livewallpaper_settings_summary"
android:entries="@array/livewallpaper_testpattern_names"
android:entryValues="@array/livewallpaper_testpattern_prefix"/>
<CheckBoxPreference android:key="livewallpaper_movement"
android:summary="@string/livewallpaper_movement_summary"
android:title="@string/livewallpaper_movement_title"
android:summaryOn="Moving test pattern"
android:summaryOff="Still test pattern"/>
</PreferenceScreen>
Where tag ListPreference
shows that we provide user option to choose between several items and the tag CheckBoxPreference
shows that we have check box (Yes/No) option.
File strings.xml in values folder contains all string
s values that we are using in our project.
="1.0"="utf-8"
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<skip />
<string name="app_name">Live Wallpaper</string>
<string name="livewallpaper_settings">Settings</string>
<string name="livewallpaper_settings_title">Select test pattern</string>
<string name="livewallpaper_settings_summary">
Choose which test pattern to display</string>
<string name="livewallpaper_movement_title">Motion</string>
<string name="livewallpaper_movement_summary">
Apply movement to test pattern</string>
</resources>
You can modify this file during localization of your software.
Also in project, you will find testpattern.xml file. This file contains TV test patterns names and colors that they are using (TV test patterns mostly consist of rectangles).
3. Let's Explore the Code!
You can check the code in the project file I've provided. I will just show the important points.
How to detect screen size and orientation?
You have to use DisplayMetrics
class!
DisplayMetrics metrics = new DisplayMetrics();
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
display.getMetrics(metrics);
mRectFrame = new Rect(0, 0, metrics.widthPixels, metrics.heightPixels);
int rotation = display.getOrientation();
if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180)
mHorizontal = false;
else
mHorizontal = true;
How to draw a gradient?
You should use GradientDrawable
class!
private Rect mGradientRect;
GradientDrawable mGradient;
mGradientRect = new Rect(10,10, 40, 40);
mGradient = new GradientDrawable(Orientation.LEFT_RIGHT, new int[]
{ 0xff050505, 0xfffdfdfd });
mGradient.setBounds(mGradientRect);
mGradient.draw(c);
Check out this code:
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key)
{
mShape = prefs.getString("livewallpaper_testpattern", "smpte");
mMotion = prefs.getBoolean("livewallpaper_movement", true);
readColors();
}
private void readColors()
{
int pid = getResources().getIdentifier(mShape + "colors", "array", getPackageName());
rectColor = getResources().getIntArray(pid);
mRectCount = rectColor.length;
mColorRectangles = new Rect[mRectCount];
System.out.println("mRectCount "+mRectCount);
initFrameParams();
}
Those functions are called when we change our settings.
In readColors()
function, we are reading color values from resources (testpatterns.xml file).
4. Editing AndroidManifest.xml
Proving a proper AndroidManifest.xml file is a crucial point if you want your app to be accepted at Android Market.
In our project, Android Manifest looks as follows:
="1.0"="utf-8"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ca.jvsh.livewallpaper"
android:versionName="1.0.20100908.1"
android:versionCode="1">
<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:permission="android.permission.BIND_WALLPAPER">
<service android:name=".LiveWallpaper"
android:label="@string/app_name"
android:icon="@drawable/icon">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"
android:resource="@xml/livewallpaper" />
</service>
<activity android:label="@string/livewallpaper_settings"
android:name=".LiveWallpaperSettings"
android:theme="@android:style/Theme.Light.WallpaperSettings"
android:exported="true"
android:icon="@drawable/icon">
</activity>
</application>
</manifest>
It is very important to set up android:permission="android.permission.BIND_WALLPAPER"
because this will allow the wallpaper to stay on your home screen.
5. Result
Points of Interest
Android live wallpapers are supported only on Android 2.1. (API level 7) and higher versions of the platform. To ensure that your application can only be installed on devices that support live wallpapers, remember to add to the applications's manifest before publishing to Android Market which indicates to Android Market and the platform that your app requires Android 2.1 or higher.
<uses-feature android:name="android.software.live_wallpaper" />
which tells Android Market that your application includes a live wallpaper.
History
- 2010.08.09 Initial sample commit