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,237
  • LiveWallpaperImage.zip
    8 KB · Views: 2,447
Last edited:

NeoTechni

Well-Known Member
Licensed User
Longtime User
I don't think that you will be able to get the complete data about multitouch event from the Action parameter.

How would I do it then?

I can't just handle all move events in between screen draws, and clear them on draws, cause non-moving fingers don't send events but should still be triggering where they touch.

Also, is there a list of values for each finger for the up/down events?
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
Well it does support multiple touches, just not on the move event.
I'm able to get which finger it is for up and down events.
Its just that all move events have action = 2, so they interfere with each other.
 

uswin4224

Member
Licensed User
Longtime User
Bouncy/smiley flickr when

Hi all,

After I tried the example LiveWallpaperImage in page one, I noticed that the smiley (bouncing ball) will be flickering if you slide scroll the home screen(whenever event LWM_OffsetChanged triggered ).

But after you stop and not sliding the home screen again, I notice that the smiley's movement is normal again.

Is there any solution for this ?

I tested using Sony Experia Neo V android 2.3.4.

Thanks
Aswin Iskandar
 

uswin4224

Member
Licensed User
Longtime User
I see,

Let me get back to you after I apply your suggestion Erel.

Thanks a lot sir. :sign0188:
 

uswin4224

Member
Licensed User
Longtime User
Sorry, I will post my question in sub forum basic4android question instead of here
 
Last edited:

walterf25

Expert
Licensed User
Longtime User
Live Wallpaper launch activity

this is how i do it

B4X:
Sub button1_click
Dim Intent1 As Intent
Intent1.Initialize(Intent1.ACTION_MAIN, "")
Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperListActivity")
StartActivity(Intent1)
End Sub

note that if you are using an android version higher than 4.0.4 then you need to use this

B4X:
Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperActivity")'this will work for android 4.0.4

cheers,
Walter
 
Last edited:

uswin4224

Member
Licensed User
Longtime User
this is how i do it

B4X:
Sub button1_click
Dim Intent1 As Intent
Intent1.Initialize(Intent1.ACTION_MAIN, "")
Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperListActivity")
StartActivity(Intent1)
End Sub

note that if you are using an android version higher than 4.0.4 then you need to use this

B4X:
Intent1.SetComponent("com.android.wallpaper.livepicker/.LiveWallpaperActivity")'this will work for android 4.0.4

cheers,
Walter

Hi Walter, thanks a lot for your answer. I manage to implement your suggestion and it is indeed work. I also found another solution using this

B4X:
Sub button1_click
Dim Intent1 As Intent
Intent1.Initialize("android.service.wallpaper.LIVE_WALLPAPER_CHOOSER","") 
StartActivity(Intent1)
End Sub
 

bloxa69

Active Member
Licensed User
Longtime User
BG Bitmap jagged edges though it's HD - LW Lib

I've tried Erel's Bitmap Live Wallpaper example. My BG bitmap gets (very) jagged edges, meaning it's probably not anti-aliasing. It is an HD bitmap, cut exactly to the LWP size and the original picture is very smooth. I've tried it on my Acer A500 (800x1280) Android 4.03 and the BG bitmap is 1600x1280, so the live wallpaper's bg should be as smooth as baby skin, but it is not.

Anybody found a solution for that or ran into this problem?
 

bloxa69

Active Member
Licensed User
Longtime User
BG Bitmap jagged edges though it's HD - LW Lib

Erel,
thanks a lot for extremely quick reply. I've tried your suggestion, but couldn't get it work, though I didn't get any error messages. Below is the code.
B4X:
Sub LWM_OffsetChanged (Engine As LWEngine)
   If image.IsInitialized Then
      Engine.Rect.Left = -Engine.CurrentOffsetX
      Engine.Rect.Top = -Engine.CurrentOffsetY
      Engine.Rect.Right = -Engine.CurrentOffsetX + Engine.FullWallpaperWidth
      Engine.Rect.Bottom = -Engine.CurrentOffsetY + Engine.FullWallpaperHeight
      'this is where and how Ive applied the anti-aliasing
      SetAntiAlias(Engine.Canvas)
      'END - this is where and how Ive applied the anti-aliasing
      Engine.Canvas.DrawBitmap(image, Null, Engine.Rect)
      
   Else
      Engine.Canvas.DrawColor(Colors.Black)
      Engine.Canvas.DrawText("No image selected", 120dip, 120dip, Typeface.DEFAULT_BOLD, 30, Colors.White, "LEFT")
   End If
   Engine.RefreshAll
End Sub

Sub SetAntiAlias (c As Canvas)
    Dim r As Reflector
    Dim NativeCanvas As Object
    r.Target = c
    NativeCanvas = r.GetField("canvas")
    Dim PaintFlagsDrawFilter As Object
    PaintFlagsDrawFilter = r.CreateObject2("android.graphics.PaintFlagsDrawFilter", _
        Array As Object(0, 1), Array As String("java.lang.int", "java.lang.int"))
    r.Target = NativeCanvas
    r.RunMethod4("setDrawFilter", Array As Object(PaintFlagsDrawFilter), Array As String("android.graphics.DrawFilter"))
End Sub

Original image:

ImageOrig.png


Live Wallpaper screenshot (all edges are very bitmapped, jagged):

screenshot.png
 

bloxa69

Active Member
Licensed User
Longtime User
I've checked it and changed my bitmap size to match that

Thanks for the hint Erel. I guess you meant Engine.FullWallpaperWidth / Engine.FullWallpaperHeight.
I've checked it and changed my bitmap size to match that - 1920x1280. Worked like a charm, no jagged edges anymore. The question that stays though: how do I proceed about different screen sizes and different images? I've checked it on the phone, and the edges are still bitmapped, though it's not as visible for the phone screen is much smaller.
My guess would be to use BitmapSample to down-sample the picture to the current device wallpaper size before loading it into the canvas.

Thanks for your help Erel.
 

uswin4224

Member
Licensed User
Longtime User
Hi all,

I would like to know, is it possible for me to detect whether the wallpaper is set to scrollable or not ?

I plan to detect,

1. if the wallpaper is not scrollable (scrollable is set to off) in the device, I draw the background in the middle,

2. but if I detect that the wallpaper is scrollable, I would like to draw background like I used to (background is scrollable by changing the x offsite).

How can I detect this, does this is possible ?

Thanks.
 

uswin4224

Member
Licensed User
Longtime User
What do you mean with scrollable? The screen is always scrollable if there is more than one home page.

You can compare Engine.FullWallpaperWidth to the screen size to find whether there are multiple screens.

I mean, for example in Galaxy S3 default launcher, the wallpaper cannot be scroll even if the wallpaper is indeed scrollable.

In galaxy S3, user can activate the scrollable wallpaper mode by installing Go launcher EX and set wallpaper mode as "scrollable" instead of "vertical screen mode", so that when he slide the screen to left or right, the wallpaper is scrolled like intended.

If he activate "vertical screen mode", the wallpaper will become fixed and cannot be scroll to left and right even if tester slide the screen to left/right.

Any advice on this ?
Thanks.
 
Autodesk?

Hello,

I currently develop for iOS, but am interested in creating Live Wallpapers for Android. I want to create very realistic, texture mapped, fully rendered 3D scenes, and am wondering how that's done.

For example, can one use a program like Autodesk 3Ds Max to create the animation, and somehow import that into the LW code? Are there less expensive alternatives?

I'm just at the very beginning of getting started with this, and am considering your platform. In that regard, does your platform involve an emulator on the target device that would have a performance penalty.

Thanks in advance for any help,

Paul
 
Top