Android Tutorial Android Live Wallpaper tutorial

Using the new LiveWallpaper library you can now create your own live wallpapers. The user can set live wallpapers by long pressing on the home screen and choosing Wallpapers - Live Wallpapers.

Creating a live wallpaper is not too difficult.

A service is responsible for handling the wallpaper events and drawing the wallpaper.

There can be several instances of the same wallpaper at the same time. For example the user can set your wallpaper as the home screen wallpaper and also see a demo of your wallpaper in the wallpaper preview dialog.

LiveWallpaper library contains two objects: LWManager and LWEngine.
LWManager is responsible for raising the events.
The first parameter of each event is of type LWEngine. LWEngine represents a specific wallpaper instance.
LWEngine includes a Canvas property which is used to draw the wallpaper.
When you finish drawing you must call LWEngine.Refresh or LWEngine.RefreshAll. Otherwise the drawing will not appear.

The following example draws a blue background. Red circles are drawn when the user touches the screen:
B4X:
Sub Process_Globals
   Dim lwm As LWManager
End Sub

Sub Service_Create
   lwm.Initialize("lwm", True)
End Sub

Sub LWM_SizeChanged (Engine As LWEngine)
   Engine.Canvas.DrawColor(Colors.Blue)
   Engine.RefreshAll
End Sub

Sub LWM_Touch (Engine As LWEngine, Action As Int, X As Float, Y As Float)
   Engine.Canvas.DrawCircle(X, Y, 20dip, Colors.Red, True, 0)
   Engine.Rect.Left = X - 20dip
   Engine.Rect.Right = X + 20dip
   Engine.Rect.Top = Y - 20dip
   Engine.Rect.Bottom = Y + 20dip
   Engine.Refresh(Engine.Rect)
End Sub
SS-2011-11-15_11.11.45.png


As there could be several different engines, it is convenient to work with the local engine.
LWEngine includes a Tag property which you can use to store data specific to that engine.

LWManager includes an internal timer that you can use if you need to do animations. The Tick event will only be raised for visible wallpapers. This is important to conserve battery.

For example the following code draws the time on the wallpaper:
B4X:
Sub Process_Globals
   Dim lwm As LWManager
End Sub

Sub Service_Create
   lwm.Initialize("lwm", True)
   lwm.StartTicking(1000) 'tick every second
End Sub

Sub LWM_Tick (Engine As LWEngine)
   Engine.Canvas.DrawColor(Colors.Black) 'Erase the background
   Engine.Canvas.DrawText(DateTime.Time(DateTime.Now), _
      300dip, 100dip, Typeface.DEFAULT_BOLD, 40, Colors.White, "LEFT")
   Engine.RefreshAll
End Sub
SS-2011-11-15_11.23.06.png


Offsets
On most devices the wallpaper virtual size is wider than a single screen. When the user moves to a different screen the offset changes.
You can use the OffsetChanged event to handle those changes.
LWEngine.FullWallpaperWidth / Height return the full size of the wallpaper.
LWEngine.CurrentOffsetX / Y return the current position.
Note that the wallpaper scrolls less than the foreground layer with the icons.

The LiveWallpaperImage demonstrates how to use those properties to display an image over the full wallpaper.

LWManager events

SizeChanged - Raised when the engine is first ready and when the screen size changes (for example when the orientation changes).
VisibilityChanged - Raised when a wallpaper becomes visible or invisible.
Touch - Raised when the user touches the wallpaper.
Tick - The internal timer tick event.
OffsetChanged - Raised when the wallpaper offsets change.
EngineDestroyed - Raised when an engine is destroyed.

Configuration
Live wallpapers require some configuration.
1. You should add the inner service declaration to the manifest editor (Project -> Manifest Editor):
B4X:
AddApplicationText(
<!-- ******** Add the internal service declaration - you can change android:label  ******* -->
<service
        android:label="My Livewallpaper"
        android:name="anywheresoftware.b4a.objects.WallpaperInternalService"
        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" />
</service>
)
It is also recommended to change minSdkVersion to 7 (at the beginning of the manifest editor code).

2. Add wallpaper.xml to Objects\res\xml folder and set it to be readonly (otherwise it will be deleted during compilation).
You can find this file in both attached examples.

3. Your service must be named WallpaperService. Note that there is an additional service inside the library named anywheresoftware.b4a.objects.WallpaperInternalService. The internal service connects to your service.

Examples
LiveWallpaperImage - The user can select an image from the activity. This image is set as the wallpaper. When the user changes the wallpaper offset the image is updated accordingly.

LiveWallpaperBall - A bouncing smiley. Clicking on the smiley will change its direction.
Before running the examples you need to set Object\res\xml\wallpaper.xml to be readonly. Otherwise it will be deleted.

Note that it is recommended to test live wallpapers in Release mode (the wallpaper will fail in debug mode when the process is started by the OS).
 

Attachments

  • LiveWallpaperBall.zip
    8.3 KB · Views: 2,225
  • LiveWallpaperImage.zip
    8 KB · Views: 2,432
Last edited:

Highwinder

Active Member
Licensed User
Longtime User
I too was considering loading up that horrible eclipse program to do a LWP. I have to say, this library is extremely easy. I can't wait till the program manages all the XML stuff on it's own though.

No kidding, I was thinking that myself as I was whipping up a new live wallpaper app last night. It would be FANTASTIC if B4A managed the manifest file completely (such as when the Live Wallpaper library is added to a project, the proper additional service code would be inserted into the manifest file, a WallpaperService module would be force-prompted, and the wallpaper.xml file would be automatically copied to the right folder and both marked as read-only, etc).

The full management of the manifest file, as close as B4A already is, would be absolutely incredible.

What a selling point that would be (hint hint). :D

- Highwinder
 

Highwinder

Active Member
Licensed User
Longtime User
Can video clips of any kind me played as live wallpaper?

Can video clips, such as MP4, be played as live wallpaper in any possible way? using B4A?
 

Highwinder

Active Member
Licensed User
Longtime User
Simplicity

Ok, then I'll just keep it simple by producing animation by looping through a set of still images.

But I've been having a problem even doing this (color me stupid on this one).:sign0104:

I must confess, I'm still trying to wrap my head around how to properly load images in a live wallpaper with the new library. It's not the library's fault, I know it works great.

I very much appreciate the examples, but there's not much description or documentation for the code that is in them, and I am having a hard time trying to decipher them, particularly the "image" live wallpaper example, which is not documented or commented very much at all. To be clear, I have read through the tutorial and the library description multiple times, but still have yet to fully understand things as far as image manipulation goes and proper order of events. I'm usually pretty good at this sort of thing, but for the life of me, I'm really embarrassing myself on this one and come groveling to the gurus.

What I'm attempting to do is just cycle some images for animation in a live wallpaper. But the proper order in which to do things and where to place the timer to cycle the images, etc continue to evade me. In a typical app, I have no problem with this, but the live wallpaper I am still struggling with.:BangHead:

My LWP doesn't even need any kind of layout or menu, I just want it to loop through the images I'm including. I'm sure this is ridiculously simple, but for some reason it hasn't "clicked" for me yet.

Erel, you were right - live wallpaper is definitely a ridiculously strange animal.

Can someone point me in the right direction? :sign0163: Once I have this figured out, I plan on posting a really good "How-To", since I know I can't (or won't) be the only one experiencing this issue.

Again, major thanks to Erel for this fantastic library! :sign0098:
 
Last edited:

Highwinder

Active Member
Licensed User
Longtime User
OK

Ok, Erel, I did exactly that. I hate to embarrass myself like this - it ain't gonna be pretty. But I'd be most grateful for any help you have to offer.

- Highwinder
 
Last edited:

ZeroSoft

Member
Licensed User
Longtime User
hi,
i don't know if there is any other way, but to add a description that is displayed at the live wallpaper menu you need to make a folder named "values" in the "Objects/res" folder and add a .xml file with the name "strings".

strings.xml
B4X:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="description">Your description</string>
</resources>

make it read only

and in the wallpaper.xml add android:description="@string/description"

wallpaper.xml

B4X:
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
  android:thumbnail="@drawable/icon"
android:description="@string/description"
/>

I hope this will help someone.

Best,
ZeroSoft
 

vasper

Member
Licensed User
Longtime User
Is there a way to add settings to the wallpaper in B4A? For example I wish to set a number for snowflakes on a snow wallpaper I have created.

snowwall1.jpg
 

vasper

Member
Licensed User
Longtime User
Ok, but how is the preference screen called? I mean a live wallpaper isn't an application I can put a button on.
 

Gigatron

Member
Licensed User
Longtime User
Ok, but how is the preference screen called? I mean a live wallpaper isn't an application I can put a button on.

Ok to call main activity, you must change the wallpaper.xml file, stored on

Objects/res/xml/wallpaper.xml

eg:

<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="@drawable/icon"
android:description="@string/description"
android:settingsActivity="com.gtr.test99.main" <--- this part load the preference of my wallpaper , com.gtr.test is the packagename of the livewallpaper .
/>

After change this don't forget to set this file wallpaper.xml READ ONLY....

Good luck
 

Gigatron

Member
Licensed User
Longtime User
Additional info for your case


On main activity to do number of snow follow this:


eg:
main.b4a
B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim Spinner1 As Spinner
   Dim Button1 as Button  <---- dont forget this button to QUIT the preference Button Text eg: OK or DONE
   End Sub


B4X:
Sub Activity_Create(FirstTime As Boolean)
 
   activity.LoadLayout("lwp")  <--- load menu from designer lwp.bal file
   
   spinner1.AddAll(Array As string("10","20","30","40","50","60","70","100"))
   
End Sub


Sub Button1_Click
   
   activity.Finish  <-- close main activity...
End Sub


B4X:
Sub Spinner1_ItemClick (Position As Int, Value As Object)
   
   File.WriteString(File.DirInternal,"1.txt",spinner1.SelectedItem)
   CallSub(WallpaperService,"numsnowchanged")  <--- informe subactivity wallpaperservice
   ToastMessageShow("Snow number is now... " & value, False)
   
End Sub






Now on WallpaperService ...

B4X:
' subroutine numsnowchanged

Sub numsnowchanged

' Read file saved before to retriev Selected Spinner value.....
'
    
   If File.Exists(File.DirInternal,"1.txt") Then   
   snownum=File.ReadString(File.DirInternal,"1.txt")
   Else
   snownum=30   ' default snow number .....
   End If


End sub

I dont know other way to pass data to wallpaperservice.

Later
 
Last edited:

squaremation

Active Member
Licensed User
Longtime User
Not sure what I've done wrong but I keep getting this error when trying to run on emulator


B4X:
Compiling code.                         0.01
   Using existing AndroidManifest.xml.
(Project - Do Not Overwrite Manifest option is checked)
AndroidManifest-Example.xml file will be created instead.
Generating R file.                      Error
res\xml\AndroidManifest.xml: Invalid file name: must contain only [a-z0-9_.]
res\xml\AndroidManifest.xml: Invalid file name: must contain only [a-z0-9_.]
res\xml\AndroidManifest.xml:34: error: Error: No resource found that matches the given name (at 'resource' with value '@xml/wallpaper').

:sign0104:
 

susu

Well-Known Member
Licensed User
Longtime User
You need to set file "wallpaper.xml" in folder "Objects/res/xml" to read-only before compile project.
 

horizont

New Member
Hi everyone, i am new to the forum.
I'd like to make a live wallpaper based only on a constant image which will show a different text (a quote in this case) every "n" seconds. I would like to design it for tablets.
Is it a good idea to use the first example in the first post and modify it accordingly?

PS: i can't download the example btw :/

PPS: and also this doesnt seem to be java code, what language are you using in your code snippets
 
Top