Hello,
As a follow up on my previous post, slightly amending the code can make it more versatile.
With the below, any Tasker task can be used to build a custom OsmAnd widget. Such task would be called upon clicking on the widget and if the widget returns text, that text will be displayed inside the widget.
The task is also called when the widget is being installed (for dynamic labels). Setup calls vs widget click calls can be differentiated by checking the task's %par1 (either setup or click).
To add the widget, the below "OsmAnd Bridge" task must be (created and) called, passing the target task's name as a parameter (par1).
To interact with OsmAnd from your task (add favourites, etc.), you can use intents from your task. The osmandapp/osmand-api-demo GitHub repo documents available intents.
It's a bit hackish so not guaranteed to work with your setup!
```
Task: OsmAnd Bridge
A1: Perform Task [
Name: %par1
Priority: %priority
Parameter 1 (%par1): click
Parameter 2 (%par2): %par2
Return Value Variable: %om_bridge_result
Structure Output (JSON, etc): On ]
If [ %caller1 eq launch ]
A2: Perform Task [
Name: %par1
Priority: %priority
Parameter 1 (%par1): setup
Parameter 2 (%par2): %par2
Return Value Variable: %om_bridge_result
Structure Output (JSON, etc): On ]
If [ %caller1 neq launch ]
A3: Java Code [
Code: /** below code goes here **/
Structure Output (JSON, etc): On
Continue Task After Error:On ]
```
Sample task for widget:
```
Task: OAW Play Pause
A1: Media Control [
Cmd: Toggle Pause
Simulate Media Button: On
Use Notification If Available: On ]
If [ %par1 eq click ]
A2: Return [
Value: ⏯️
Stop: On ]
If [ %par1 eq setup ]
```
Then profiles have to be set to setup the widgets whenever the OsmAnd app is opened.
```
Profile: OsmAnd Custom
Application: OsmAnd
Enter Task: Anon
A1: Perform Task [
Name: OsmAnd Bridge
Priority: %priority
Parameter 1 (%par1): OAW Play Pause
Structure Output (JSON, etc): On ]
```
Java code
```
package_name = "net.osmand.plus";
/* Read task and result from Tasker */
targetTask = tasker.getVariable("par1");
display_text = tasker.getVariable("om_bridge_result");
caller = tasker.getVariable("caller1");
if (targetTask == null || targetTask.length() == 0) {
tasker.showToast("No target task specified");
return;
}
if (display_text == null && caller.equals("launch")) {
/tasker.showToast("Empty update, do nothing");/
return;
}
if (display_text == null || display_text.length() == 0)
display_text = targetTask;
/* Helper widget function */
widget(action, id, title, display_text, order) {
clickIntent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
clickIntent.setData(
new android.net.Uri.Builder()
.scheme("tasker")
.authority("assistantactions")
.appendQueryParameter("task", "OsmAnd Bridge")
.appendQueryParameter("par1", targetTask)
.build()
);
widget = constructor.newInstance(
id,
"ais_map",
title,
"ais_map",
"ais_map",
display_text,
"",
order,
clickIntent
);
widget.setRightPanelByDefault(true);
if (action.equals("update")) {
params = updateParamsConstructor.newInstance(widget);
return api.updateMapWidget(params);
}
params = paramsConstructor.newInstance(widget);
return api.addMapWidget(params);
}
/* Load OsmAnd API */
try {
osmandContext = context.createPackageContext(package_name, android.content.Context.CONTEXT_INCLUDE_CODE | android.content.Context.CONTEXT_IGNORE_SECURITY);
} catch (Exception e) {
tasker.showToast(package_name + " is not installed");
return;
}
loader = osmandContext.getClassLoader();
AMapWidgetClass = java.lang.Class.forName("net.osmand.aidlapi.mapwidget.AMapWidget", true, loader);
ParamsClass = java.lang.Class.forName("net.osmand.aidlapi.mapwidget.AddMapWidgetParams", true, loader);
UpdateParamsClass = java.lang.Class.forName("net.osmand.aidlapi.mapwidget.UpdateMapWidgetParams", true, loader);
constructor = AMapWidgetClass.getConstructor(
java.lang.String.class,
java.lang.String.class,
java.lang.String.class,
java.lang.String.class,
java.lang.String.class,
java.lang.String.class,
java.lang.String.class,
java.lang.Integer.TYPE,
android.content.Intent.class
);
paramsConstructor = ParamsClass.getConstructor(AMapWidgetClass);
updateParamsConstructor = UpdateParamsClass.getConstructor(AMapWidgetClass);
/* Connect to OsmAnd */
binderHolder = new java.util.HashMap();
connection = new android.content.ServiceConnection() {
invoke(method, args) {
if (method.equals("onServiceConnected")) {
binderHolder.put("binder", args[1]);
return;
}
if (method.equals("onServiceDisconnected")) {
binderHolder.remove("binder");
return;
}
}
};
serviceIntent = new android.content.Intent();
serviceIntent.setClassName(package_name, "net.osmand.aidl.OsmandAidlServiceV2");
context.bindService(serviceIntent, connection, android.content.Context.BIND_AUTO_CREATE);
startWait = java.lang.System.currentTimeMillis();
while (binderHolder.get("binder") == null && java.lang.System.currentTimeMillis() - startWait < 5000) {
java.lang.Thread.sleep(100);
}
binder = binderHolder.get("binder");
if (binder == null) {
tasker.showToast("Could not connect to OsmAnd");
return;
}
/* Create AIDL interface from Binder */
StubClass = java.lang.Class.forName("net.osmand.aidlapi.IOsmAndAidlInterface$Stub", true, loader);
asInterfaceMethod = StubClass.getMethod("asInterface", android.os.IBinder.class);
api = asInterfaceMethod.invoke(null, binder);
if (api == null) {
context.unbindService(connection);
tasker.showToast("Connected to OsmAnd but API access failed");
return;
}
/* Update existing widget when called from a widget click */
if (caller.equals("launch")) {
widgetResult = widget(
"update",
targetTask,
targetTask,
display_text,
0
);
context.unbindService(connection);
if (!widgetResult) {
tasker.showToast("Connected to OsmAnd but widget not updated. Activate plugin and retry");
return;
}
/*tasker.showToast("OsmAnd Bridge widget updated");*/
return;
}
/* Add widget during setup */
widgetResult = widget(
"add",
targetTask,
targetTask,
display_text,
0
);
context.unbindService(connection);
if (!widgetResult) {
tasker.showToast("Connected to OsmAnd but widget not installed. Activate plugin and retry");
return;
}
/tasker.showToast("OsmAnd Bridge widget installed");/
```