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
This commit is contained in:
Everton Hermann 2020-07-20 02:47:15 +02:00
parent 3945656658
commit f2b809504d
7 changed files with 150 additions and 1 deletions

View file

@ -51,4 +51,9 @@ interface IOsmAndAidlCallback {
* Callback for {@link IOsmAndAidlInterface} registerForVoiceRouterMessages() method. * Callback for {@link IOsmAndAidlInterface} registerForVoiceRouterMessages() method.
*/ */
void onVoiceRouterNotify(in OnVoiceNavigationParams params); void onVoiceRouterNotify(in OnVoiceNavigationParams params);
/**
* Callback for {@link IOsmAndAidlInterface} registerForKeyEvents() method.
*/
void onKeyEvent(in KeyEvent params);
} }

View file

@ -95,6 +95,7 @@ import net.osmand.aidlapi.mapmarker.RemoveMapMarkersParams;
import net.osmand.aidlapi.quickaction.QuickActionParams; import net.osmand.aidlapi.quickaction.QuickActionParams;
import net.osmand.aidlapi.quickaction.QuickActionInfoParams; import net.osmand.aidlapi.quickaction.QuickActionInfoParams;
import net.osmand.aidlapi.events.AKeyEventsParams;
// NOTE: Add new methods at the end of file!!! // NOTE: Add new methods at the end of file!!!
@ -841,4 +842,13 @@ interface IOsmAndAidlInterface {
boolean executeQuickAction(in QuickActionParams params); boolean executeQuickAction(in QuickActionParams params);
boolean getQuickActionsInfo(out List<QuickActionInfoParams> quickActions); boolean getQuickActionsInfo(out List<QuickActionInfoParams> 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<Integer>) - list of requested key events
*/
long registerForKeyEvents(in AKeyEventsParams params, IOsmAndAidlCallback callback);
} }

View file

@ -0,0 +1,2 @@
package net.osmand.aidlapi.events;
parcelable AKeyEventsParams;

View file

@ -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<Integer> keyEventList;
public AKeyEventsParams() { }
protected AKeyEventsParams(Parcel in) {
readFromParcel(in);
}
public static final Parcelable.Creator<AKeyEventsParams> CREATOR = new Parcelable.Creator<AKeyEventsParams>() {
@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<Integer> keyEventList){
this.keyEventList=keyEventList;
}
public ArrayList<Integer> 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);
}
}

View file

@ -15,6 +15,7 @@ import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -101,8 +102,10 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap; 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_NAV_DATA_UPDATE = 2;
public static final int KEY_ON_CONTEXT_MENU_BUTTONS_CLICK = 4; 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_VOICE_MESSAGE = 5;
public static final int KEY_ON_KEY_EVENT = 6;
private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class); private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class);
@ -2327,6 +2331,38 @@ public class OsmandAidlApi {
a.points, a.wptPoints, a.wptCategoryNames); a.points, a.wptPoints, a.wptCategoryNames);
} }
private Map<Long, Set<Integer>> keyEventCallbacks = new ConcurrentHashMap<>();
public boolean onKeyEvent(KeyEvent event) {
if (aidlCallbackListenerV2 != null) {
for (Map.Entry<Long, OsmandAidlServiceV2.AidlCallbackParams> entry : aidlCallbackListenerV2.getAidlCallbacks().entrySet()) {
OsmandAidlServiceV2.AidlCallbackParams cb = entry.getValue();
if ((cb.getKey() & KEY_ON_KEY_EVENT) > 0) {
Set<Integer> 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<Integer> keyEventLst) {
keyEventCallbacks.put(id, new HashSet<>(keyEventLst));
}
public void unregisterFromKeyEvents(long id) {
keyEventCallbacks.remove(id);
}
public interface SearchCompleteCallback { public interface SearchCompleteCallback {
void onSearchComplete(List<AidlSearchResultWrapper> resultSet); void onSearchComplete(List<AidlSearchResultWrapper> resultSet);
} }

View file

@ -1115,6 +1115,28 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener
return UNKNOWN_API_ERROR; 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 @Override
public long addContextMenuButtons(ContextMenuButtonsParams params, final IOsmAndAidlCallback callback) { public long addContextMenuButtons(ContextMenuButtonsParams params, final IOsmAndAidlCallback callback) {

View file

@ -62,6 +62,8 @@ public class MapActivityKeyListener implements KeyEvent.Callback {
} }
} else if (mapScrollHelper.isScrollingDirectionKeyCode(keyCode)) { } else if (mapScrollHelper.isScrollingDirectionKeyCode(keyCode)) {
return mapScrollHelper.onKeyDown(keyCode, event); return mapScrollHelper.onKeyDown(keyCode, event);
} else if(app.getAidlApi().onKeyEvent(event)) {
return true;
} }
return false; return false;
} }
@ -123,6 +125,8 @@ public class MapActivityKeyListener implements KeyEvent.Callback {
mapActivity.changeZoom(1); mapActivity.changeZoom(1);
return true; return true;
} }
} else if (app.getAidlApi().onKeyEvent(event)){
return true;
} else{ } else{
return OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode); return OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode);
} }