Added search feature to aidl api

This commit is contained in:
crimean 2018-08-27 22:04:14 +03:00
parent c8bee8f39b
commit 2f6d331c42
10 changed files with 384 additions and 6 deletions

View file

@ -401,6 +401,10 @@ public class SearchUICore {
}
public void search(final String text, final boolean delayedExecution, final ResultMatcher<SearchResult> matcher) {
search(text, delayedExecution, matcher, searchSettings);
}
public void search(final String text, final boolean delayedExecution, final ResultMatcher<SearchResult> matcher, final SearchSettings searchSettings) {
final int request = requestNumber.incrementAndGet();
final SearchPhrase phrase = this.phrase.generateNewPhrase(text, searchSettings);
this.phrase = phrase;

View file

@ -0,0 +1,7 @@
package net.osmand.aidl;
import net.osmand.aidl.search.SearchResult;
interface IOsmAndAidlCallback {
void onSearchComplete(in List<SearchResult> resultSet);
}

View file

@ -61,6 +61,11 @@ import net.osmand.aidl.navigation.StopNavigationParams;
import net.osmand.aidl.navigation.MuteNavigationParams;
import net.osmand.aidl.navigation.UnmuteNavigationParams;
import net.osmand.aidl.IOsmAndAidlCallback;
import net.osmand.aidl.search.SearchResult;
import net.osmand.aidl.search.SearchParams;
// NOTE: Add new methods at the end of file!!!
interface IOsmAndAidlInterface {
@ -121,4 +126,6 @@ interface IOsmAndAidlInterface {
boolean stopNavigation(in StopNavigationParams params);
boolean muteNavigation(in MuteNavigationParams params);
boolean unmuteNavigation(in UnmuteNavigationParams params);
boolean search(in SearchParams params, IOsmAndAidlCallback callback);
}

View file

@ -1,5 +1,6 @@
package net.osmand.aidl;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -28,9 +29,11 @@ import net.osmand.aidl.maplayer.AMapLayer;
import net.osmand.aidl.maplayer.point.AMapPoint;
import net.osmand.aidl.mapmarker.AMapMarker;
import net.osmand.aidl.mapwidget.AMapWidget;
import net.osmand.aidl.search.SearchResult;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.AppInitializer;
import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
@ -58,6 +61,9 @@ import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
import net.osmand.search.SearchUICore;
import net.osmand.search.SearchUICore.SearchResultCollection;
import net.osmand.search.core.SearchSettings;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
@ -81,6 +87,15 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import static net.osmand.search.core.ObjectType.CITY;
import static net.osmand.search.core.ObjectType.HOUSE;
import static net.osmand.search.core.ObjectType.POI;
import static net.osmand.search.core.ObjectType.POSTCODE;
import static net.osmand.search.core.ObjectType.STREET;
import static net.osmand.search.core.ObjectType.STREET_INTERSECTION;
import static net.osmand.search.core.ObjectType.VILLAGE;
import static net.osmand.search.core.SearchCoreFactory.MAX_DEFAULT_SEARCH_RADIUS;
public class OsmandAidlApi {
private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class);
@ -140,7 +155,7 @@ public class OsmandAidlApi {
private Map<String, TextInfoWidget> widgetControls = new ConcurrentHashMap<>();
private Map<String, AMapLayer> layers = new ConcurrentHashMap<>();
private Map<String, OsmandMapLayer> mapLayers = new ConcurrentHashMap<>();
private Map<String, BroadcastReceiver> receivers = new TreeMap<String, BroadcastReceiver>();
private Map<String, BroadcastReceiver> receivers = new TreeMap<>();
public OsmandAidlApi(OsmandApplication app) {
@ -178,7 +193,7 @@ public class OsmandAidlApi {
LOG.error(e.getMessage(), e);
}
}
receivers = new TreeMap<String, BroadcastReceiver>();
receivers = new TreeMap<>();
}
private void registerRefreshMapReceiver(final MapActivity mapActivity) {
@ -972,6 +987,7 @@ public class OsmandAidlApi {
return false;
}
@SuppressLint("StaticFieldLeak")
private void finishGpxImport(boolean destinationExists, File destination, String color, boolean show) {
int col = ConfigureMapMenu.GpxAppearanceAdapter.parseTrackColor(
app.getRendererRegistry().getCurrentSelectedRenderer(), color);
@ -1113,6 +1129,7 @@ public class OsmandAidlApi {
return false;
}
@SuppressLint("StaticFieldLeak")
boolean showGpx(String fileName) {
if (!Algorithms.isEmpty(fileName)) {
File f = app.getAppPath(IndexConstants.GPX_INDEX_DIR + fileName);
@ -1310,6 +1327,63 @@ public class OsmandAidlApi {
return true;
}
boolean search(final String searchQuery, final double latitude, final double longitude,
final int radiusLevel, final int totalLimit, final SearchCompleteCallback callback) {
if (Algorithms.isEmpty(searchQuery) || latitude == 0 || longitude == 0 || callback == null) {
return false;
}
if (app.isApplicationInitializing()) {
app.getAppInitializer().addListener(new AppInitializer.AppInitializeListener() {
@Override
public void onProgress(AppInitializer init, AppInitializer.InitEvents event) {
}
@Override
public void onFinish(AppInitializer init) {
runSearch(searchQuery, latitude, longitude, radiusLevel, totalLimit, callback);
}
});
} else {
runSearch(searchQuery, latitude, longitude, radiusLevel, totalLimit, callback);
}
return true;
}
private void runSearch(String searchQuery, double latitude, double longitude, int radiusLevel, int totalLimit, final SearchCompleteCallback callback) {
final SearchUICore core = app.getSearchUICore().getCore();
core.setOnResultsComplete(new Runnable() {
@Override
public void run() {
List<SearchResult> resultSet = new ArrayList<>();
SearchResultCollection resultCollection = core.getCurrentSearchResult();
for (net.osmand.search.core.SearchResult r : resultCollection.getCurrentSearchResults()) {
SearchResult result = new SearchResult(r.location.getLatitude(), r.location.getLongitude(), r.localeName, r.alternateName, new ArrayList<>(r.otherNames));
resultSet.add(result);
}
callback.onSearchComplete(resultSet);
}
});
if (radiusLevel < 1) {
radiusLevel = 1;
} else if (radiusLevel > MAX_DEFAULT_SEARCH_RADIUS) {
radiusLevel = MAX_DEFAULT_SEARCH_RADIUS;
}
if (totalLimit <= 0) {
totalLimit = -1;
}
SearchSettings searchSettings = new SearchSettings(core.getSearchSettings())
.setSearchTypes(CITY, VILLAGE, POSTCODE, STREET, HOUSE, STREET_INTERSECTION, POI)
.setRadiusLevel(radiusLevel)
.setEmptyQueryAllowed(false)
.setSortByName(false)
.setOriginalLocation(new LatLon(latitude, longitude))
.setTotalLimit(totalLimit);
core.search(searchQuery, false, null, searchSettings);
}
boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) {
if (!TextUtils.isEmpty(appPackage) && items != null) {
if (items.isEmpty()) {
@ -1448,4 +1522,8 @@ public class OsmandAidlApi {
this.flags = flags;
}
}
public interface SearchCompleteCallback {
void onSearchComplete(List<SearchResult> resultSet);
}
}

View file

@ -2,10 +2,17 @@ package net.osmand.aidl;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcelable;
import android.os.RemoteException;
import net.osmand.PlatformUtil;
import net.osmand.aidl.OsmandAidlApi.SearchCompleteCallback;
import net.osmand.aidl.calculateroute.CalculateRouteParams;
import net.osmand.aidl.favorite.AddFavoriteParams;
import net.osmand.aidl.favorite.RemoveFavoriteParams;
@ -46,17 +53,28 @@ import net.osmand.aidl.note.StartAudioRecordingParams;
import net.osmand.aidl.note.StartVideoRecordingParams;
import net.osmand.aidl.note.StopRecordingParams;
import net.osmand.aidl.note.TakePhotoNoteParams;
import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.search.SearchResult;
import net.osmand.plus.OsmandApplication;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class OsmandAidlService extends Service {
private static final Log LOG = PlatformUtil.getLog(OsmandAidlService.class);
private static final int MSG_RUN_SEARCH = 53;
private static final String DATA_KEY_RESULT_SET = "resultSet";
private ArrayList<IOsmAndAidlCallback> mRemoteCallbacks;
private ServiceHandler mHandler = null;
HandlerThread mHandlerThread = new HandlerThread("OsmAndAidlServiceThread");
OsmandApplication getApp() {
return (OsmandApplication) getApplication();
}
@ -68,15 +86,25 @@ public class OsmandAidlService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Handler Thread handling all call back methods
mHandlerThread.start();
mHandler = new ServiceHandler(mHandlerThread.getLooper());
// Return the interface
return mBinder;
}
@Override
public void onCreate() {
super.onCreate();
mRemoteCallbacks = new ArrayList<>();
}
private final IOsmAndAidlInterface.Stub mBinder = new IOsmAndAidlInterface.Stub() {
private void handleException(Exception e) {
LOG.error("AIDL e.getMessage()", e);
}
@Override
@ -523,5 +551,77 @@ public class OsmandAidlService extends Service {
return false;
}
}
@Override
public boolean search(SearchParams params, final IOsmAndAidlCallback callback) throws RemoteException {
try {
return params != null && getApi("search").search(params.getSearchQuery(),
params.getLatutude(), params.getLongitude(), params.getRadiusLevel(), params.getTotalLimit(), new SearchCompleteCallback() {
@Override
public void onSearchComplete(List<SearchResult> resultSet) {
Bundle data = new Bundle();
if (resultSet.size() > 0) {
data.putParcelableArrayList(DATA_KEY_RESULT_SET, new ArrayList<>(resultSet));
}
sendMsgToHandler(callback, MSG_RUN_SEARCH, data);
}
});
} catch (Exception e) {
handleException(e);
return false;
}
}
};
/**
* Create handler message to be sent
*/
void sendMsgToHandler(IOsmAndAidlCallback callback, int flag, Bundle data) {
mRemoteCallbacks.add(callback);
Message message = mHandler.obtainMessage();
message.arg1 = mRemoteCallbacks.size() - 1;
message.setData(data);
message.what = flag;
mHandler.sendMessage(message);
}
/**
* Handler class sending result in callback to respective
* application
*/
private class ServiceHandler extends Handler {
int callbackIndex = 0;
ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
callbackIndex = msg.arg1;
switch (msg.what) {
case MSG_RUN_SEARCH:
Bundle data = msg.getData();
List<SearchResult> resultSet;
if (data.containsKey(DATA_KEY_RESULT_SET)) {
resultSet = data.getParcelableArrayList(DATA_KEY_RESULT_SET);
} else {
resultSet = Collections.emptyList();
}
try {
mRemoteCallbacks.get(callbackIndex).onSearchComplete(resultSet);
} catch (RemoteException e) {
LOG.error("AIDL e.getMessage()", e);
}
break;
}
}
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.search;
parcelable SearchParams;

View file

@ -0,0 +1,79 @@
package net.osmand.aidl.search;
import android.os.Parcel;
import android.os.Parcelable;
public class SearchParams implements Parcelable {
private String searchQuery;
private double latutude;
private double longitude;
private int radiusLevel = 1;
private int totalLimit = -1;
public SearchParams(String searchQuery, double latutude, double longitude, int radiusLevel, int totalLimit) {
this.searchQuery = searchQuery;
this.latutude = latutude;
this.longitude = longitude;
this.radiusLevel = radiusLevel;
this.totalLimit = totalLimit;
}
public SearchParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<SearchParams> CREATOR = new Creator<SearchParams>() {
@Override
public SearchParams createFromParcel(Parcel in) {
return new SearchParams(in);
}
@Override
public SearchParams[] newArray(int size) {
return new SearchParams[size];
}
};
public String getSearchQuery() {
return searchQuery;
}
public double getLatutude() {
return latutude;
}
public double getLongitude() {
return longitude;
}
public int getRadiusLevel() {
return radiusLevel;
}
public int getTotalLimit() {
return totalLimit;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(searchQuery);
out.writeDouble(latutude);
out.writeDouble(longitude);
out.writeInt(radiusLevel);
out.writeInt(totalLimit);
}
private void readFromParcel(Parcel in) {
searchQuery = in.readString();
latutude = in.readDouble();
longitude = in.readDouble();
radiusLevel = in.readInt();
totalLimit = in.readInt();
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.search;
parcelable SearchResult;

View file

@ -0,0 +1,85 @@
package net.osmand.aidl.search;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
public class SearchResult implements Parcelable {
private double latitude;
private double longitude;
private String localeName;
private String alternateName;
private List<String> otherNames = new ArrayList<>();
public SearchResult(double latitude, double longitude, String localeName, String alternateName, List<String> otherNames) {
this.latitude = latitude;
this.longitude = longitude;
this.localeName = localeName;
this.alternateName = alternateName;
if (otherNames != null) {
this.otherNames = otherNames;
}
}
public SearchResult(Parcel in) {
readFromParcel(in);
}
public static final Creator<SearchResult> CREATOR = new Creator<SearchResult>() {
@Override
public SearchResult createFromParcel(Parcel in) {
return new SearchResult(in);
}
@Override
public SearchResult[] newArray(int size) {
return new SearchResult[size];
}
};
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public String getLocaleName() {
return localeName;
}
public String getAlternateName() {
return alternateName;
}
public List<String> getOtherNames() {
return otherNames;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeDouble(latitude);
out.writeDouble(longitude);
out.writeString(localeName);
out.writeString(alternateName);
out.writeStringList(otherNames);
}
private void readFromParcel(Parcel in) {
latitude = in.readDouble();
longitude = in.readDouble();
localeName = in.readString();
alternateName = in.readString();
in.readStringList(otherNames);
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -91,6 +91,7 @@ public class ExternalApiHelper {
public static final String PARAM_START_LON = "start_lon";
public static final String PARAM_DEST_LAT = "dest_lat";
public static final String PARAM_DEST_LON = "dest_lon";
public static final String PARAM_DEST_SEARCH_QUERY = "dest_search_query";
public static final String PARAM_PROFILE = "profile";
public static final String PARAM_VERSION = "version";
@ -251,9 +252,20 @@ public class ExternalApiHelper {
startDesc = null;
}
double destLat = Double.parseDouble(uri.getQueryParameter(PARAM_DEST_LAT));
double destLon = Double.parseDouble(uri.getQueryParameter(PARAM_DEST_LON));
final LatLon dest = new LatLon(destLat, destLon);
String destSearchQuery = uri.getQueryParameter(PARAM_DEST_SEARCH_QUERY);
String destLatStr = uri.getQueryParameter(PARAM_DEST_LAT);
String destLonStr = uri.getQueryParameter(PARAM_DEST_LON);
final LatLon dest;
if (!Algorithms.isEmpty(destLatStr) && !Algorithms.isEmpty(destLonStr)) {
double destLat = Double.parseDouble(destLatStr);
double destLon = Double.parseDouble(destLonStr);
dest = new LatLon(destLat, destLon);
} else {
dest = null;
}
if (!Algorithms.isEmpty(destSearchQuery)) {
}
final PointDescription destDesc = new PointDescription(PointDescription.POINT_TYPE_LOCATION, destName);
boolean force = uri.getBooleanQueryParameter(PARAM_FORCE, false);