Java Question Creating a library for Android Wear Watchfaces

corwin42

Expert
Licensed User
Longtime User
It all started here. In short: I want to create a library for Android Wear Watchfaces.

Erel was so kind to post the source of the LiveWallpaper library.
This is a great starting point since the structure of LiveWallpapers and Watchfaces are very similar.

My current problem is that the livewallpaper library will only work with one service. With this limitation I think watchfaces would be restricted to one per app.

The cause is that the B4A service name is somewhat "hardcoded" into the library:

B4X:
    @Override
    public void onCreate() {
        super.onCreate();
        try {
            Intent i = new Intent(this, Class.forName(getPackageName() + ".wallpaperservice"));
            startService(i);
        } catch (ClassNotFoundException e) {
            Common.Log("WallpaperService not found.");
            throw new RuntimeException(e);
        }
    }

The other thing is that you configure the wallpaper/watchface service in the manifest:

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>
)

The question now is how to make this dynamic so that I can have several services (one for each watchface).
My idea was to #Extend the B4A service module so I can create as many services (and watchfaces) as I want. Now Erel said this should be possible otherwise but I can't see how.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
As I wrote there are all kinds of ways to implement it. I'm not sure which one is the best way as it depends on the native API structure (which I'm not familiar with).

A brute force solution is to implement the class that extends CanvasWatchFaceService and then create 5 classes that extend this class:
WatchFace1, WatchFace2, ...

B4X:
public abstract class BaseWatchFace extends CanvasWatchFaceService 
private final String name;
 public BaseWatchFace (String name) {
  this.name = name;
}
@Overridepublic void onCreate() {
 super.onCreate();try {Intent i = new Intent(this, Class.forName(getPackageName() + ".watchface" + name));
startService(i);} catch (ClassNotFoundException e) {
 Common.Log("WallpaperService not found.");
 throw new RuntimeException(e);
 }
 }

public WatchFace1 extends BaseWatchFace {
  public WatchFace1() {
   super("1");
}
}
public WatchFace2 extends BaseWatchFace {
  public WatchFace2() {
   super("2");
}
}
...
Developers can now add one or more services. They only need to declare the ones they use in the manifest editor.
 

corwin42

Expert
Licensed User
Longtime User
Thanks for your suggestion.

I will try the way with 1..x watchface services.

So after my surgery I hope I will have some time now to complete this.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
My solution to the 1 livewallpaper service was to let you pick a wallpaper in the app itself. The livewallpaper service just loads the setting. I intend to do something similar for watch faces rather than making multiple services
 

corwin42

Expert
Licensed User
Longtime User
Any progress?

A basic framework is running. It will require B4A 6.50 or later because it uses the new #Extends for service modules.
Currently the library creates only log output. Still much work to do.
 

corwin42

Expert
Licensed User
Longtime User
A first Test Watchface created completely with B4A and with the Help of ABExtDrawing Library.

Works nice so far. Still some tests needed but I'm getting close...

1stWatchface.png
 
Top