osmandapp / OsmAnd

OsmAnd
https://osmand.net
Other
4.7k stars 1.02k forks source link

[Feature request] LiveMonitoringHelper responseBody should be parsed for OsmandAidlServiceV2 commands #8127

Open goatchurchprime opened 4 years ago

goatchurchprime commented 4 years ago

With some coding in a Node-RED, this would provide a method to share locations in realtime (Issue #7469), as well as other interesting features (see below).

The online tracking feature works by calling the function LiveMonitoringHelper.senddata(LiveMonitoringData data) which populates the user-specified live_monitoring_url format string with positional data and sends out a GET request to the internet. The response string, which is received, is discarded.

(The LiveMonitoringData objects are actually local and are created and queued up in the function LiveMonitoringHelper.updateLocation(net.osmand.Location location).)

Meanwhile there is an API used deep within the Telegram sharing app for moving and changing the state of a set of favourite markers. The function which sends out the positions is TelegramNotification.refreshNotification() and marker updates are done through the telegram.helpers.OsmandAidlHelper.updateFavorite() function.

The same interface exist at OsmandAidlServiceV2 ("Aild" stands for "Android Interface Definition Language").

The interesting functions in this interface are: addFavoriteGroup(), removeFavoriteGroup(), updateFavoriteGroup(), addFavorite(), updateFavorite(), removeFavorite() (Question: is "category string" the same as "favourite group"?)

Proposal: If the return string from LiveMonitoringHelper.updateLocation() were parsed for function calls and parameters in that interface (maybe it's in JSON format), then this could go a very long way towards enabling live tracking and some productive geocaching work.

The application I have in mind is to help with the job of organizing a team to deliver leaflets to a list of addresses. Normally we get handed a set of leaflets and a printed list of addresses. A lot of time gets wasted not knowing exactly where the houses are and losing track of the people you've sent down a cul-de-sac to deliver to a couple of addresses who don't know where you've moved on to next.

If I used the OSM database to scan for house addresses from my list I could generate a list of favourite markers in the group "undelivered". Each delivery person would be in the "person" marker group, so you could see them roving around. As each house gets delivered we'd change its state to "delivered" (in a different colour or made invisible) and be able to update this to everyone else's device. Ultimately it would be like were were a set of pac-men chewing up dots up and down the streets.

All the server side processing could be implemented in a standard Node-RED flow, however a more appropriate protocol to use for uploading and downloading the data would be the MQTT protocol instead of HTTP request.

goatchurchprime commented 4 years ago

I'm making some progress putting the positions into a JSON list of "osmand.api://"-style Uris in the response body from the LiveMonitoringHelper.senddata() function call, then constructing a list of Intents, and posting them to the ExternalApiHelper.processApiRequest() function.

I think the Online tracking web address LIVE_MONITORING_URL ought to have a Username as one of the parameters so it's easier to distinguish between the different players even though they are all using the same URL template.

Also, updateFavorite seems to be missing from the Api, which means it's impossible to implement live tracking without an upgrade. I'm also not sure why the updateFavourite requires the prevLat and prevLon to match exactly as this will cause a failure if a single update gets missed.

goatchurchprime commented 4 years ago

It works perfectly.

Some hints on how to build Osmand using repo command (may need to set the java jre version to the V7 one used by AndroidStudio). Then it runs out of memory and you need to find the config page for the memory settings.

A very modest amount of hacking (about 200 lines in my patch-file) has enabled a response generated from a Node-RED flow of the following form:

msg.payload = {"osmandapicmds":[
    "osmand.api://add_favorite?lat=54.6622970&lon=-5.7666780&name=fav2name&desc=fav2desc&category=fav2cat&color=green&visible=true", 
    "osmand.api://add_map_marker?lat=54.6622958&lon=-5.7666790&name=thing3"
]}; 

to be received within the LiveMonitoringHelper.sendData() function and then parsed and acted upon with the following code:

ExternalApiHelper apiHelper...

    JSONObject obj = new JSONObject(responseBody.toString());
    JSONArray osmandapicmds = obj.getJSONArray("osmandapicmds");
    for (int i = 0; i < osmandapicmds.length(); i++) {
        String osmandapicmd = osmandapicmds.getString(i);
        if (osmandapicmd.startsWith("osmand.api://")) {
            Intent intent = new Intent(activity, app.getAppCustomization().getFavoritesActivity());
            intent.setData(Uri.parse(osmandapicmd));
            apiHelper.processApiRequest(intent);
        }
    }

As shown above, the Intent is processed by ExternalApiHelper.processApiRequest() which then calls functions within the FavouritesDbHelper object to implement them. (This is where a version of update_favorite that could update the attributes of the object given only it's name needed to be written.)

In summary, the basic enabling technology which allows for live tracking is Node-RED in place of Telegram. This has the advantage of (a) not requiring an account and a login to a separate service for each participant, and (b) making it easily possible to implement customizable interactive behaviors that can solve a diverse set of productive use-cases.

Use of this approach in addition (or in replacement) to the Telegram app method of live-tracking would need to be looked at by the core team before I'd dare to make a pull-request

image

vshcherb commented 4 years ago

It looks interesting though it is hard to understand for me cause it deals with many components. If you have pull request to OsmAnd please open it might be easier to understand the needs by reading the code.

As I understand, it is missing updateFavorite - obviously we would need to add it or fix addFavorite (cause favorites are not allowed to have duplicates) we could have same method with meaning of "add or update".

goatchurchprime commented 4 years ago

Agreed. It's a a couple of distinct features that I need to separate and justify as independent pull-requests that have to make sense on their own.

However, the most important part of the proposal is not actually in Osmand -- it's that we can use Node-RED on the server-side to enable these small features to do really useful coordinated things between many different devices.