From f2b809504da5f29fd4a8a7fcb87143150d7509f2 Mon Sep 17 00:00:00 2001 From: Everton Hermann Date: Mon, 20 Jul 2020 02:47:15 +0200 Subject: [PATCH] Add key event listener, Enables reading keys using aidl api, can be useful for instance to customize interaction using media keys, volume, headset button, etc --- .../osmand/aidlapi/IOsmAndAidlCallback.aidl | 5 ++ .../osmand/aidlapi/IOsmAndAidlInterface.aidl | 10 +++ .../aidlapi/events/AKeyEventsParams.aidl | 2 + .../aidlapi/events/AKeyEventsParams.java | 70 +++++++++++++++++++ OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java | 36 ++++++++++ .../net/osmand/aidl/OsmandAidlServiceV2.java | 22 ++++++ .../activities/MapActivityKeyListener.java | 6 +- 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl create mode 100644 OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl index 1d7f954815..0598f31854 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl @@ -51,4 +51,9 @@ interface IOsmAndAidlCallback { * Callback for {@link IOsmAndAidlInterface} registerForVoiceRouterMessages() method. */ void onVoiceRouterNotify(in OnVoiceNavigationParams params); + + /** + * Callback for {@link IOsmAndAidlInterface} registerForKeyEvents() method. + */ + void onKeyEvent(in KeyEvent params); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index 45bf3907f7..242c0a7d8b 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -95,6 +95,7 @@ import net.osmand.aidlapi.mapmarker.RemoveMapMarkersParams; import net.osmand.aidlapi.quickaction.QuickActionParams; import net.osmand.aidlapi.quickaction.QuickActionInfoParams; +import net.osmand.aidlapi.events.AKeyEventsParams; // NOTE: Add new methods at the end of file!!! @@ -841,4 +842,13 @@ interface IOsmAndAidlInterface { boolean executeQuickAction(in QuickActionParams params); boolean getQuickActionsInfo(out List quickActions); + /** + * Method to register for key events. + * + * @params subscribeToUpdates (boolean) - boolean flag to subscribe or unsubscribe from key events + * @params callbackId (long) - id of callback, needed to unsubscribe key events + * @params callback (IOsmAndAidlCallback) - callback to notify user on key event + * @params keyEventList (List) - list of requested key events + */ + long registerForKeyEvents(in AKeyEventsParams params, IOsmAndAidlCallback callback); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl new file mode 100644 index 0000000000..972b2cb218 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl @@ -0,0 +1,2 @@ +package net.osmand.aidlapi.events; +parcelable AKeyEventsParams; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java new file mode 100644 index 0000000000..814eb6dfac --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java @@ -0,0 +1,70 @@ +package net.osmand.aidlapi.events; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import net.osmand.aidlapi.AidlParams; + +import java.util.ArrayList; + +public class AKeyEventsParams extends AidlParams { + + private long callbackId = -1L; + private boolean subscribeToUpdates = true; + private ArrayList keyEventList; + + public AKeyEventsParams() { } + + protected AKeyEventsParams(Parcel in) { + readFromParcel(in); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public AKeyEventsParams createFromParcel(Parcel in) { + return new AKeyEventsParams(in); + } + + @Override + public AKeyEventsParams[] newArray(int size) { + return new AKeyEventsParams[size]; + } + }; + + public long getCallbackId() { + return callbackId; + } + + public void setCallbackId(long callbackId) { + this.callbackId = callbackId; + } + + public void setSubscribeToUpdates(boolean subscribeToUpdates) { + this.subscribeToUpdates = subscribeToUpdates; + } + + public boolean isSubscribeToUpdates() { + return subscribeToUpdates; + } + public void setKeyEventList( ArrayList keyEventList){ + this.keyEventList=keyEventList; + } + public ArrayList getKeyEventList() { + return keyEventList; + } + + @Override + protected void readFromBundle(Bundle bundle) { + callbackId = bundle.getLong("callbackId"); + subscribeToUpdates = bundle.getBoolean("subscribeToUpdates"); + keyEventList = bundle.getIntegerArrayList("keyEventList"); + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putLong("callbackId", callbackId); + bundle.putBoolean("subscribeToUpdates", subscribeToUpdates); + bundle.putIntegerArrayList("keyEventList", keyEventList); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 583915f081..772b8870a3 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -15,6 +15,7 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; +import android.view.KeyEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -101,8 +102,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -130,6 +133,7 @@ public class OsmandAidlApi { public static final int KEY_ON_NAV_DATA_UPDATE = 2; public static final int KEY_ON_CONTEXT_MENU_BUTTONS_CLICK = 4; public static final int KEY_ON_VOICE_MESSAGE = 5; + public static final int KEY_ON_KEY_EVENT = 6; private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class); @@ -2327,6 +2331,38 @@ public class OsmandAidlApi { a.points, a.wptPoints, a.wptCategoryNames); } + + private Map> keyEventCallbacks = new ConcurrentHashMap<>(); + + public boolean onKeyEvent(KeyEvent event) { + if (aidlCallbackListenerV2 != null) { + for (Map.Entry entry : aidlCallbackListenerV2.getAidlCallbacks().entrySet()) { + OsmandAidlServiceV2.AidlCallbackParams cb = entry.getValue(); + if ((cb.getKey() & KEY_ON_KEY_EVENT) > 0) { + Set keyEventsList = keyEventCallbacks.get(entry.getKey()); + //An empty list means all key are requested + if (keyEventsList != null && (keyEventsList.isEmpty() || keyEventsList.contains(event.getKeyCode()))) { + try { + cb.getCallback().onKeyEvent(event); + return true; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + } + } + } + return false; + } + + void registerForKeyEvents(long id, ArrayList keyEventLst) { + keyEventCallbacks.put(id, new HashSet<>(keyEventLst)); + } + + public void unregisterFromKeyEvents(long id) { + keyEventCallbacks.remove(id); + } + public interface SearchCompleteCallback { void onSearchComplete(List resultSet); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 413eb1a68c..83d8a71652 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -1115,6 +1115,28 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener return UNKNOWN_API_ERROR; } } + @Override + public long registerForKeyEvents(AKeyEventsParams params, final IOsmAndAidlCallback callback) { + try { + OsmandAidlApi api = getApi("registerForKeyEvents"); + if (api != null) { + if (!params.isSubscribeToUpdates() && params.getCallbackId() != -1) { + api.unregisterFromKeyEvents(params.getCallbackId()); + removeAidlCallback(params.getCallbackId()); + return -1; + } else { + long id = addAidlCallback(callback, KEY_ON_NAV_DATA_UPDATE); + api.registerForKeyEvents(id, params.getKeyEventList()); + return id; + } + } else { + return -1; + } + } catch (Exception e) { + handleException(e); + return UNKNOWN_API_ERROR; + } + } @Override public long addContextMenuButtons(ContextMenuButtonsParams params, final IOsmAndAidlCallback callback) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java index be642ff80d..acb1ac6e46 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java @@ -62,6 +62,8 @@ public class MapActivityKeyListener implements KeyEvent.Callback { } } else if (mapScrollHelper.isScrollingDirectionKeyCode(keyCode)) { return mapScrollHelper.onKeyDown(keyCode, event); + } else if(app.getAidlApi().onKeyEvent(event)) { + return true; } return false; } @@ -123,7 +125,9 @@ public class MapActivityKeyListener implements KeyEvent.Callback { mapActivity.changeZoom(1); return true; } - } else { + } else if (app.getAidlApi().onKeyEvent(event)){ + return true; + } else{ return OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode); } return false;