Merge pull request #7016 from osmandapp/CustomizationImprovements

Customization improvements
This commit is contained in:
Alexey 2019-06-07 19:20:56 +03:00 committed by GitHub
commit 12d52a6af4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 568 additions and 159 deletions

View file

@ -71,6 +71,8 @@ import net.osmand.aidl.navigation.NavigateSearchParams;
import net.osmand.aidl.customization.SetWidgetsParams; import net.osmand.aidl.customization.SetWidgetsParams;
import net.osmand.aidl.customization.OsmandSettingsParams; import net.osmand.aidl.customization.OsmandSettingsParams;
import net.osmand.aidl.customization.OsmandSettingsInfoParams;
import net.osmand.aidl.customization.CustomizationInfoParams;
import net.osmand.aidl.gpx.AGpxFile; import net.osmand.aidl.gpx.AGpxFile;
import net.osmand.aidl.gpx.AGpxFileDetails; import net.osmand.aidl.gpx.AGpxFileDetails;
@ -699,4 +701,8 @@ interface IOsmAndAidlInterface {
long addContextMenuButtons(in ContextMenuButtonsParams params, IOsmAndAidlCallback callback); long addContextMenuButtons(in ContextMenuButtonsParams params, IOsmAndAidlCallback callback);
boolean removeContextMenuButtons(in RemoveContextMenuButtonsParams params); boolean removeContextMenuButtons(in RemoveContextMenuButtonsParams params);
boolean updateContextMenuButtons(in UpdateContextMenuButtonsParams params); boolean updateContextMenuButtons(in UpdateContextMenuButtonsParams params);
boolean areOsmandSettingsCustomized(in OsmandSettingsInfoParams params);
boolean setCustomization(in CustomizationInfoParams params);
} }

View file

@ -23,7 +23,6 @@ import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter;
import net.osmand.CallbackWithObject; import net.osmand.CallbackWithObject;
import net.osmand.GPXUtilities; import net.osmand.GPXUtilities;
@ -33,6 +32,7 @@ import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.aidl.contextmenu.ContextMenuButtonsParams; import net.osmand.aidl.contextmenu.ContextMenuButtonsParams;
import net.osmand.aidl.copyfile.CopyFileParams; import net.osmand.aidl.copyfile.CopyFileParams;
import net.osmand.aidl.customization.CustomizationInfoParams;
import net.osmand.aidl.favorite.AFavorite; import net.osmand.aidl.favorite.AFavorite;
import net.osmand.aidl.favorite.group.AFavoriteGroup; import net.osmand.aidl.favorite.group.AFavoriteGroup;
import net.osmand.aidl.gpx.AGpxBitmap; import net.osmand.aidl.gpx.AGpxBitmap;
@ -58,7 +58,6 @@ import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.AppInitializer.InitEvents; import net.osmand.plus.AppInitializer.InitEvents;
import net.osmand.plus.ApplicationMode; import net.osmand.plus.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper;
import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper;
@ -109,8 +108,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
@ -126,7 +123,6 @@ import static net.osmand.aidl.OsmandAidlConstants.COPY_FILE_WRITE_LOCK_ERROR;
import static net.osmand.aidl.OsmandAidlConstants.OK_RESPONSE; import static net.osmand.aidl.OsmandAidlConstants.OK_RESPONSE;
import static net.osmand.aidl.OsmandAidlService.KEY_ON_CONTEXT_MENU_BUTTONS_CLICK; import static net.osmand.aidl.OsmandAidlService.KEY_ON_CONTEXT_MENU_BUTTONS_CLICK;
import static net.osmand.aidl.OsmandAidlService.KEY_ON_NAV_DATA_UPDATE; import static net.osmand.aidl.OsmandAidlService.KEY_ON_NAV_DATA_UPDATE;
import static net.osmand.plus.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME;
public class OsmandAidlApi { public class OsmandAidlApi {
@ -194,8 +190,6 @@ public class OsmandAidlApi {
private static final int DEFAULT_ZOOM = 15; private static final int DEFAULT_ZOOM = 15;
private static final int MAX_NAV_DRAWER_ITEMS_PER_APP = 3;
private OsmandApplication app; private OsmandApplication app;
private Map<String, AMapWidget> widgets = new ConcurrentHashMap<>(); private Map<String, AMapWidget> widgets = new ConcurrentHashMap<>();
private Map<String, TextInfoWidget> widgetControls = new ConcurrentHashMap<>(); private Map<String, TextInfoWidget> widgetControls = new ConcurrentHashMap<>();
@ -1738,123 +1732,11 @@ public class OsmandAidlApi {
} }
boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) { boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) {
if (!TextUtils.isEmpty(appPackage) && items != null) { return app.getAppCustomization().setNavDrawerItems(appPackage, items);
clearNavDrawerItems(appPackage);
if (items.isEmpty()) {
return true;
}
List<NavDrawerItem> newItems = new ArrayList<>(MAX_NAV_DRAWER_ITEMS_PER_APP);
boolean success = true;
for (int i = 0; i < items.size() && i <= MAX_NAV_DRAWER_ITEMS_PER_APP; i++) {
net.osmand.aidl.navdrawer.NavDrawerItem item = items.get(i);
String name = item.getName();
String uri = item.getUri();
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(uri)) {
newItems.add(new NavDrawerItem(name, uri, item.getIconName(), item.getFlags()));
} else {
success = false;
break;
}
}
if (success) {
saveNavDrawerItems(appPackage, newItems);
}
return success;
}
return false;
} }
public void registerNavDrawerItems(final Activity activity, ContextMenuAdapter adapter) { public void registerNavDrawerItems(final Activity activity, ContextMenuAdapter adapter) {
PackageManager pm = activity.getPackageManager(); app.getAppCustomization().registerNavDrawerItems(activity, adapter);
for (Map.Entry<String, List<NavDrawerItem>> entry : getNavDrawerItems().entrySet()) {
String appPackage = entry.getKey();
for (NavDrawerItem item : entry.getValue()) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.uri));
if (intent.resolveActivity(pm) == null) {
intent = pm.getLaunchIntentForPackage(appPackage);
}
if (intent != null) {
if (item.flags != -1) {
intent.addFlags(item.flags);
}
final Intent finalIntent = intent;
adapter.addItem(new ContextMenuItem.ItemBuilder()
.setId(item.getId())
.setTitle(item.name)
.setIcon(getIconId(item.iconName))
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) {
activity.startActivity(finalIntent);
return true;
}
})
.createItem());
}
}
}
}
private int getIconId(@Nullable String iconName) {
if (!TextUtils.isEmpty(iconName)) {
int id = app.getResources().getIdentifier(iconName, "drawable", app.getPackageName());
return id == 0 ? -1 : id;
}
return -1;
}
private void clearNavDrawerItems(String appPackage) {
try {
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
allItems.put(appPackage, new JSONArray());
app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
private void saveNavDrawerItems(String appPackage, List<NavDrawerItem> items) {
try {
JSONArray jArray = new JSONArray();
for (NavDrawerItem item : items) {
JSONObject obj = new JSONObject();
obj.put(NavDrawerItem.NAME_KEY, item.name);
obj.put(NavDrawerItem.URI_KEY, item.uri);
obj.put(NavDrawerItem.ICON_NAME_KEY, item.iconName);
obj.put(NavDrawerItem.FLAGS_KEY, item.flags);
jArray.put(obj);
}
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
allItems.put(appPackage, jArray);
app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
private Map<String, List<NavDrawerItem>> getNavDrawerItems() {
Map<String, List<NavDrawerItem>> res = new LinkedHashMap<>();
try {
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
for (Iterator<?> it = allItems.keys(); it.hasNext(); ) {
String appPackage = (String) it.next();
JSONArray jArray = allItems.getJSONArray(appPackage);
List<NavDrawerItem> list = new ArrayList<>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject obj = jArray.getJSONObject(i);
list.add(new NavDrawerItem(
obj.optString(NavDrawerItem.NAME_KEY),
obj.optString(NavDrawerItem.URI_KEY),
obj.optString(NavDrawerItem.ICON_NAME_KEY),
obj.optInt(NavDrawerItem.FLAGS_KEY, -1)
));
}
res.put(appPackage, list);
}
} catch (JSONException e) {
e.printStackTrace();
}
return res;
} }
public List<ConnectedApp> getConnectedApps() { public List<ConnectedApp> getConnectedApps() {
@ -2062,6 +1944,15 @@ public class OsmandAidlApi {
} }
} }
boolean areOsmandSettingsCustomized(String sharedPreferencesName) {
return app.getAppCustomization().areSettingsCustomizedForPreference(sharedPreferencesName);
}
boolean setCustomization(CustomizationInfoParams params) {
app.getAppCustomization().setCustomization(params);
return true;
}
private void addContextMenuButtonListener(ContextMenuButtonsParams buttonsParams, long callbackId) { private void addContextMenuButtonListener(ContextMenuButtonsParams buttonsParams, long callbackId) {
IContextMenuButtonListener listener = new IContextMenuButtonListener() { IContextMenuButtonListener listener = new IContextMenuButtonListener() {
@ -2325,30 +2216,6 @@ public class OsmandAidlApi {
} }
} }
private static class NavDrawerItem {
static final String NAME_KEY = "name";
static final String URI_KEY = "uri";
static final String ICON_NAME_KEY = "icon_name";
static final String FLAGS_KEY = "flags";
private String name;
private String uri;
private String iconName;
private int flags;
NavDrawerItem(String name, String uri, String iconName, int flags) {
this.name = name;
this.uri = uri;
this.iconName = iconName;
this.flags = flags;
}
public String getId() {
return DRAWER_ITEM_ID_SCHEME + name;
}
}
public interface SearchCompleteCallback { public interface SearchCompleteCallback {
void onSearchComplete(List<SearchResult> resultSet); void onSearchComplete(List<SearchResult> resultSet);
} }

View file

@ -10,7 +10,6 @@ import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.util.concurrent.ConcurrentHashMap;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.aidl.OsmandAidlApi.GpxBitmapCreatedCallback; import net.osmand.aidl.OsmandAidlApi.GpxBitmapCreatedCallback;
import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback; import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback;
@ -19,6 +18,9 @@ import net.osmand.aidl.calculateroute.CalculateRouteParams;
import net.osmand.aidl.contextmenu.ContextMenuButtonsParams; import net.osmand.aidl.contextmenu.ContextMenuButtonsParams;
import net.osmand.aidl.contextmenu.RemoveContextMenuButtonsParams; import net.osmand.aidl.contextmenu.RemoveContextMenuButtonsParams;
import net.osmand.aidl.contextmenu.UpdateContextMenuButtonsParams; import net.osmand.aidl.contextmenu.UpdateContextMenuButtonsParams;
import net.osmand.aidl.copyfile.CopyFileParams;
import net.osmand.aidl.customization.CustomizationInfoParams;
import net.osmand.aidl.customization.OsmandSettingsInfoParams;
import net.osmand.aidl.customization.OsmandSettingsParams; import net.osmand.aidl.customization.OsmandSettingsParams;
import net.osmand.aidl.customization.SetWidgetsParams; import net.osmand.aidl.customization.SetWidgetsParams;
import net.osmand.aidl.favorite.AddFavoriteParams; import net.osmand.aidl.favorite.AddFavoriteParams;
@ -71,7 +73,6 @@ import net.osmand.aidl.plugins.PluginParams;
import net.osmand.aidl.search.SearchParams; import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.search.SearchResult; import net.osmand.aidl.search.SearchResult;
import net.osmand.aidl.tiles.ASqliteDbFile; import net.osmand.aidl.tiles.ASqliteDbFile;
import net.osmand.aidl.copyfile.CopyFileParams;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -80,6 +81,7 @@ import org.apache.commons.logging.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import static net.osmand.aidl.OsmandAidlConstants.CANNOT_ACCESS_API_ERROR; import static net.osmand.aidl.OsmandAidlConstants.CANNOT_ACCESS_API_ERROR;
@ -131,7 +133,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
OsmandAidlApi api = getApi("setting_listener"); OsmandAidlApi api = getApi("setting_listener");
if(api != null) { if (api != null) {
api.aidlCallbackListener = this; api.aidlCallbackListener = this;
} }
} }
@ -142,7 +144,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
callbacks.clear(); callbacks.clear();
OsmandAidlApi api = getApi("clear_listener"); OsmandAidlApi api = getApi("clear_listener");
if(api != null) { if (api != null) {
api.aidlCallbackListener = null; api.aidlCallbackListener = null;
} }
mHandlerThread.quit(); mHandlerThread.quit();
@ -1044,7 +1046,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
public long registerForNavigationUpdates(ANavigationUpdateParams params, final IOsmAndAidlCallback callback) { public long registerForNavigationUpdates(ANavigationUpdateParams params, final IOsmAndAidlCallback callback) {
try { try {
OsmandAidlApi api = getApi("registerForNavUpdates"); OsmandAidlApi api = getApi("registerForNavUpdates");
if (api != null ) { if (api != null) {
if (!params.isSubscribeToUpdates() && params.getCallbackId() != -1) { if (!params.isSubscribeToUpdates() && params.getCallbackId() != -1) {
api.unregisterFromUpdates(params.getCallbackId()); api.unregisterFromUpdates(params.getCallbackId());
removeAidlCallback(params.getCallbackId()); removeAidlCallback(params.getCallbackId());
@ -1113,6 +1115,28 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
return false; return false;
} }
} }
@Override
public boolean areOsmandSettingsCustomized(OsmandSettingsInfoParams params) {
try {
OsmandAidlApi api = getApi("areOsmandSettingsCustomized");
return api != null && api.areOsmandSettingsCustomized(params.getSharedPreferencesName());
} catch (Exception e) {
handleException(e);
return false;
}
}
@Override
public boolean setCustomization(CustomizationInfoParams params) {
try {
OsmandAidlApi api = getApi("setCustomization");
return api != null && params != null && api.setCustomization(params);
} catch (Exception e) {
handleException(e);
return false;
}
}
}; };
public static class AidlCallbackParams { public static class AidlCallbackParams {
@ -1141,6 +1165,4 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
this.key = key; this.key = key;
} }
} }
} }

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.customization;
parcelable CustomizationInfoParams;

View file

@ -0,0 +1,172 @@
package net.osmand.aidl.customization;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import net.osmand.aidl.navdrawer.NavDrawerFooterParams;
import net.osmand.aidl.navdrawer.NavDrawerHeaderParams;
import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
import net.osmand.aidl.plugins.PluginParams;
import java.util.ArrayList;
import java.util.List;
public class CustomizationInfoParams implements Parcelable {
private OsmandSettingsParams settingsParams;
private NavDrawerHeaderParams navDrawerHeaderParams;
private NavDrawerFooterParams navDrawerFooterParams;
private SetNavDrawerItemsParams navDrawerItemsParams;
private ArrayList<SetWidgetsParams> visibilityWidgetsParams = new ArrayList<>();
private ArrayList<SetWidgetsParams> availabilityWidgetsParams = new ArrayList<>();
private ArrayList<PluginParams> pluginsParams = new ArrayList<>();
private List<String> featuresEnabledIds = new ArrayList<>();
private List<String> featuresDisabledIds = new ArrayList<>();
private List<String> featuresEnabledPatterns = new ArrayList<>();
private List<String> featuresDisabledPatterns = new ArrayList<>();
public CustomizationInfoParams(OsmandSettingsParams settingsParams,
NavDrawerHeaderParams navDrawerHeaderParams,
NavDrawerFooterParams navDrawerFooterParams,
SetNavDrawerItemsParams navDrawerItemsParams,
ArrayList<SetWidgetsParams> visibilityWidgetsParams,
ArrayList<SetWidgetsParams> availabilityWidgetsParams,
ArrayList<PluginParams> pluginsParams,
List<String> featuresEnabledIds,
List<String> featuresDisabledIds,
List<String> featuresEnabledPatterns,
List<String> featuresDisabledPatterns) {
this.settingsParams = settingsParams;
this.navDrawerHeaderParams = navDrawerHeaderParams;
this.navDrawerFooterParams = navDrawerFooterParams;
this.navDrawerItemsParams = navDrawerItemsParams;
if (visibilityWidgetsParams != null) {
this.visibilityWidgetsParams.addAll(visibilityWidgetsParams);
}
if (availabilityWidgetsParams != null) {
this.availabilityWidgetsParams.addAll(availabilityWidgetsParams);
}
if (pluginsParams != null) {
this.pluginsParams.addAll(pluginsParams);
}
if (featuresEnabledIds != null) {
this.featuresEnabledIds.addAll(featuresEnabledIds);
}
if (featuresDisabledIds != null) {
this.featuresDisabledIds.addAll(featuresDisabledIds);
}
if (featuresEnabledPatterns != null) {
this.featuresEnabledPatterns.addAll(featuresEnabledPatterns);
}
if (featuresDisabledPatterns != null) {
this.featuresDisabledPatterns.addAll(featuresDisabledPatterns);
}
}
public CustomizationInfoParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<CustomizationInfoParams> CREATOR = new Creator<CustomizationInfoParams>() {
@Override
public CustomizationInfoParams createFromParcel(Parcel in) {
return new CustomizationInfoParams(in);
}
@Override
public CustomizationInfoParams[] newArray(int size) {
return new CustomizationInfoParams[size];
}
};
public OsmandSettingsParams getSettingsParams() {
return settingsParams;
}
public NavDrawerHeaderParams getNavDrawerHeaderParams() {
return navDrawerHeaderParams;
}
public NavDrawerFooterParams getNavDrawerFooterParams() {
return navDrawerFooterParams;
}
public SetNavDrawerItemsParams getNavDrawerItemsParams() {
return navDrawerItemsParams;
}
public ArrayList<SetWidgetsParams> getVisibilityWidgetsParams() {
return visibilityWidgetsParams;
}
public ArrayList<SetWidgetsParams> getAvailabilityWidgetsParams() {
return availabilityWidgetsParams;
}
public ArrayList<PluginParams> getPluginsParams() {
return pluginsParams;
}
public List<String> getFeaturesEnabledIds() {
return featuresEnabledIds;
}
public List<String> getFeaturesDisabledIds() {
return featuresDisabledIds;
}
public List<String> getFeaturesEnabledPatterns() {
return featuresEnabledPatterns;
}
public List<String> getFeaturesDisabledPatterns() {
return featuresDisabledPatterns;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(settingsParams, flags);
out.writeParcelable(navDrawerHeaderParams, flags);
out.writeParcelable(navDrawerFooterParams, flags);
out.writeParcelable(navDrawerItemsParams, flags);
out.writeTypedList(visibilityWidgetsParams);
out.writeTypedList(availabilityWidgetsParams);
out.writeTypedList(pluginsParams);
out.writeStringList(featuresEnabledIds);
out.writeStringList(featuresDisabledIds);
out.writeStringList(featuresEnabledPatterns);
out.writeStringList(featuresDisabledPatterns);
}
@SuppressLint("ParcelClassLoader")
private void readFromParcel(Parcel in) {
settingsParams = in.readParcelable(OsmandSettingsParams.class.getClassLoader());
navDrawerHeaderParams = in.readParcelable(NavDrawerHeaderParams.class.getClassLoader());
navDrawerFooterParams = in.readParcelable(NavDrawerFooterParams.class.getClassLoader());
navDrawerItemsParams = in.readParcelable(SetNavDrawerItemsParams.class.getClassLoader());
in.readTypedList(visibilityWidgetsParams, SetWidgetsParams.CREATOR);
in.readTypedList(availabilityWidgetsParams, SetWidgetsParams.CREATOR);
in.readTypedList(pluginsParams, PluginParams.CREATOR);
in.readStringList(featuresEnabledIds);
in.readStringList(featuresDisabledIds);
in.readStringList(featuresEnabledPatterns);
in.readStringList(featuresDisabledPatterns);
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.customization;
parcelable OsmandSettingsInfoParams;

View file

@ -0,0 +1,50 @@
package net.osmand.aidl.customization;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
public class OsmandSettingsInfoParams implements Parcelable {
private String sharedPreferencesName;
public OsmandSettingsInfoParams(@NonNull String sharedPreferencesName) {
this.sharedPreferencesName = sharedPreferencesName;
}
public OsmandSettingsInfoParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<OsmandSettingsInfoParams> CREATOR = new Creator<OsmandSettingsInfoParams>() {
@Override
public OsmandSettingsInfoParams createFromParcel(Parcel in) {
return new OsmandSettingsInfoParams(in);
}
@Override
public OsmandSettingsInfoParams[] newArray(int size) {
return new OsmandSettingsInfoParams[size];
}
};
public String getSharedPreferencesName() {
return sharedPreferencesName;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(sharedPreferencesName);
}
@SuppressLint("ParcelClassLoader")
private void readFromParcel(Parcel in) {
sharedPreferencesName = in.readString();
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -1,8 +1,8 @@
package net.osmand.plus; package net.osmand.plus;
import static net.osmand.plus.osmedit.OpenstreetmapLocalUtil.LOG;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
@ -11,11 +11,16 @@ import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import android.widget.ArrayAdapter;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.aidl.customization.CustomizationInfoParams;
import net.osmand.aidl.customization.OsmandSettingsParams;
import net.osmand.aidl.customization.SetWidgetsParams;
import net.osmand.aidl.navdrawer.NavDrawerFooterParams; import net.osmand.aidl.navdrawer.NavDrawerFooterParams;
import net.osmand.aidl.navdrawer.NavDrawerHeaderParams; import net.osmand.aidl.navdrawer.NavDrawerHeaderParams;
import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
import net.osmand.aidl.plugins.PluginParams; import net.osmand.aidl.plugins.PluginParams;
import net.osmand.data.LocationPoint; import net.osmand.data.LocationPoint;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -28,6 +33,10 @@ import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -36,13 +45,18 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import static net.osmand.plus.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME;
public class OsmAndAppCustomization { public class OsmAndAppCustomization {
private static final int MAX_NAV_DRAWER_ITEMS_PER_APP = 3;
protected OsmandApplication app; protected OsmandApplication app;
protected OsmandSettings osmandSettings; protected OsmandSettings osmandSettings;
@ -209,7 +223,9 @@ public class OsmAndAppCustomization {
} }
@Nullable @Nullable
public ArrayList<String> getNavDrawerLogoParams() {return navDrawerParams; } public ArrayList<String> getNavDrawerLogoParams() {
return navDrawerParams;
}
public boolean setNavDrawerLogo(String uri, @Nullable String packageName, @Nullable String intent) { public boolean setNavDrawerLogo(String uri, @Nullable String packageName, @Nullable String intent) {
if (TextUtils.isEmpty(uri)) { if (TextUtils.isEmpty(uri)) {
@ -283,6 +299,89 @@ public class OsmAndAppCustomization {
return set; return set;
} }
public void regWidgetsVisibility(@NonNull ArrayList<SetWidgetsParams> visibilityWidgetsParams) {
for (SetWidgetsParams setWidgetsParams : visibilityWidgetsParams) {
regWidgetVisibility(setWidgetsParams.getWidgetKey(), setWidgetsParams.getAppModesKeys());
}
}
public void regWidgetsAvailability(@NonNull ArrayList<SetWidgetsParams> availabilityWidgetsParams) {
for (SetWidgetsParams setWidgetsParams : availabilityWidgetsParams) {
regWidgetAvailability(setWidgetsParams.getWidgetKey(), setWidgetsParams.getAppModesKeys());
}
}
public void setCustomization(CustomizationInfoParams params) {
OsmandSettingsParams settingsParams = params.getSettingsParams();
if (settingsParams != null) {
customizeOsmandSettings(settingsParams.getSharedPreferencesName(), settingsParams.getBundle());
}
NavDrawerHeaderParams navDrawerHeaderParams = params.getNavDrawerHeaderParams();
NavDrawerFooterParams navDrawerFooterParams = params.getNavDrawerFooterParams();
SetNavDrawerItemsParams navDrawerItemsParams = params.getNavDrawerItemsParams();
setNavDrawerParams(navDrawerHeaderParams, navDrawerFooterParams, navDrawerItemsParams);
ArrayList<SetWidgetsParams> visibilityWidgetsParams = params.getVisibilityWidgetsParams();
ArrayList<SetWidgetsParams> availabilityWidgetsParams = params.getAvailabilityWidgetsParams();
setWidgetsParams(visibilityWidgetsParams, availabilityWidgetsParams);
ArrayList<PluginParams> pluginsParams = params.getPluginsParams();
if (pluginsParams != null) {
changePluginsStatus(pluginsParams);
}
List<String> enabledIds = params.getFeaturesEnabledIds();
List<String> disabledIds = params.getFeaturesDisabledIds();
setFeaturesIds(enabledIds, disabledIds);
List<String> enabledPatterns = params.getFeaturesEnabledPatterns();
List<String> disabledPatterns = params.getFeaturesDisabledPatterns();
setFeaturesPatterns(enabledPatterns, disabledPatterns);
}
public void setNavDrawerParams(NavDrawerHeaderParams navDrawerHeaderParams, NavDrawerFooterParams navDrawerFooterParams, SetNavDrawerItemsParams navDrawerItemsParams) {
if (navDrawerHeaderParams != null) {
setNavDrawerLogoWithParams(navDrawerHeaderParams.getImageUri(), navDrawerHeaderParams.getPackageName(), navDrawerHeaderParams.getIntent());
}
if (navDrawerFooterParams != null) {
setNavDrawerFooterParams(navDrawerFooterParams);
}
if (navDrawerItemsParams != null) {
setNavDrawerItems(navDrawerItemsParams.getAppPackage(), navDrawerItemsParams.getItems());
}
}
public void setWidgetsParams(ArrayList<SetWidgetsParams> visibilityWidgetsParams, ArrayList<SetWidgetsParams> availabilityWidgetsParams) {
if (visibilityWidgetsParams != null) {
regWidgetsVisibility(visibilityWidgetsParams);
}
if (availabilityWidgetsParams != null) {
regWidgetsAvailability(availabilityWidgetsParams);
}
}
public void setFeaturesIds(List<String> enabledIds, List<String> disabledIds) {
if (enabledIds != null) {
setFeaturesEnabledIds(enabledIds);
}
if (disabledIds != null) {
setFeaturesDisabledIds(disabledIds);
}
}
public void setFeaturesPatterns(List<String> enabledPatterns, List<String> disabledPatterns) {
if (enabledPatterns != null) {
setFeaturesEnabledPatterns(enabledPatterns);
}
if (disabledPatterns != null) {
setFeaturesDisabledPatterns(disabledPatterns);
}
}
public boolean isWidgetVisible(@NonNull String key, ApplicationMode appMode) { public boolean isWidgetVisible(@NonNull String key, ApplicationMode appMode) {
Set<ApplicationMode> set = widgetsVisibilityMap.get(key); Set<ApplicationMode> set = widgetsVisibilityMap.get(key);
if (set == null) { if (set == null) {
@ -304,6 +403,12 @@ public class OsmAndAppCustomization {
return setNavDrawerLogo(imageUri, packageName, intent); return setNavDrawerLogo(imageUri, packageName, intent);
} }
public void changePluginsStatus(List<PluginParams> pluginsParams) {
for (PluginParams pluginParams : pluginsParams) {
changePluginStatus(pluginParams);
}
}
public boolean changePluginStatus(PluginParams params) { public boolean changePluginStatus(PluginParams params) {
if (params.getNewState() == 0) { if (params.getNewState() == 0) {
for (OsmandPlugin plugin : OsmandPlugin.getEnabledPlugins()) { for (OsmandPlugin plugin : OsmandPlugin.getEnabledPlugins()) {
@ -326,6 +431,126 @@ public class OsmAndAppCustomization {
return false; return false;
} }
public boolean setNavDrawerItems(String appPackage, List<net.osmand.aidl.navdrawer.NavDrawerItem> items) {
if (!TextUtils.isEmpty(appPackage) && items != null) {
clearNavDrawerItems(appPackage);
if (items.isEmpty()) {
return true;
}
List<NavDrawerItem> newItems = new ArrayList<>(MAX_NAV_DRAWER_ITEMS_PER_APP);
boolean success = true;
for (int i = 0; i < items.size() && i <= MAX_NAV_DRAWER_ITEMS_PER_APP; i++) {
net.osmand.aidl.navdrawer.NavDrawerItem item = items.get(i);
String name = item.getName();
String uri = item.getUri();
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(uri)) {
newItems.add(new NavDrawerItem(name, uri, item.getIconName(), item.getFlags()));
} else {
success = false;
break;
}
}
if (success) {
saveNavDrawerItems(appPackage, newItems);
}
return success;
}
return false;
}
private void clearNavDrawerItems(String appPackage) {
try {
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
allItems.put(appPackage, new JSONArray());
app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
private void saveNavDrawerItems(String appPackage, List<NavDrawerItem> items) {
try {
JSONArray jArray = new JSONArray();
for (NavDrawerItem item : items) {
JSONObject obj = new JSONObject();
obj.put(NavDrawerItem.NAME_KEY, item.name);
obj.put(NavDrawerItem.URI_KEY, item.uri);
obj.put(NavDrawerItem.ICON_NAME_KEY, item.iconName);
obj.put(NavDrawerItem.FLAGS_KEY, item.flags);
jArray.put(obj);
}
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
allItems.put(appPackage, jArray);
app.getSettings().API_NAV_DRAWER_ITEMS_JSON.set(allItems.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
public void registerNavDrawerItems(final Activity activity, ContextMenuAdapter adapter) {
PackageManager pm = activity.getPackageManager();
for (Map.Entry<String, List<NavDrawerItem>> entry : getNavDrawerItems().entrySet()) {
String appPackage = entry.getKey();
for (NavDrawerItem item : entry.getValue()) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(item.uri));
if (intent.resolveActivity(pm) == null) {
intent = pm.getLaunchIntentForPackage(appPackage);
}
if (intent != null) {
if (item.flags != -1) {
intent.addFlags(item.flags);
}
final Intent finalIntent = intent;
adapter.addItem(new ContextMenuItem.ItemBuilder()
.setId(item.getId())
.setTitle(item.name)
.setIcon(getIconId(item.iconName))
.setListener(new ContextMenuAdapter.ItemClickListener() {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int position, boolean isChecked, int[] viewCoordinates) {
activity.startActivity(finalIntent);
return true;
}
})
.createItem());
}
}
}
}
private Map<String, List<NavDrawerItem>> getNavDrawerItems() {
Map<String, List<NavDrawerItem>> res = new LinkedHashMap<>();
try {
JSONObject allItems = new JSONObject(app.getSettings().API_NAV_DRAWER_ITEMS_JSON.get());
for (Iterator<?> it = allItems.keys(); it.hasNext(); ) {
String appPackage = (String) it.next();
JSONArray jArray = allItems.getJSONArray(appPackage);
List<NavDrawerItem> list = new ArrayList<>();
for (int i = 0; i < jArray.length(); i++) {
JSONObject obj = jArray.getJSONObject(i);
list.add(new NavDrawerItem(
obj.optString(NavDrawerItem.NAME_KEY),
obj.optString(NavDrawerItem.URI_KEY),
obj.optString(NavDrawerItem.ICON_NAME_KEY),
obj.optInt(NavDrawerItem.FLAGS_KEY, -1)
));
}
res.put(appPackage, list);
}
} catch (JSONException e) {
e.printStackTrace();
}
return res;
}
private int getIconId(@Nullable String iconName) {
if (!TextUtils.isEmpty(iconName)) {
int id = app.getResources().getIdentifier(iconName, "drawable", app.getPackageName());
return id == 0 ? -1 : id;
}
return -1;
}
@NonNull @NonNull
private HashSet<ApplicationMode> getAppModesSet(@Nullable List<String> appModeKeys) { private HashSet<ApplicationMode> getAppModesSet(@Nullable List<String> appModeKeys) {
HashSet<ApplicationMode> set = new HashSet<>(); HashSet<ApplicationMode> set = new HashSet<>();
@ -365,10 +590,29 @@ public class OsmAndAppCustomization {
return !isMatchesPattern(id, featuresDisabledPatterns); return !isMatchesPattern(id, featuresDisabledPatterns);
} }
public boolean isOsmandCustomized() {
return areWidgetsCustomized() || areFeaturesCustomized() || areSettingsCustomized();
}
public boolean areWidgetsCustomized() { public boolean areWidgetsCustomized() {
return widgetsCustomized; return widgetsCustomized;
} }
public boolean areFeaturesCustomized() {
return featuresCustomized;
}
public boolean areSettingsCustomized() {
return customOsmandSettings != null;
}
public boolean areSettingsCustomizedForPreference(String sharedPreferencesName) {
if (customOsmandSettings != null && customOsmandSettings.sharedPreferencesName.equals(sharedPreferencesName)) {
return true;
}
return OsmandSettings.areSettingsCustomizedForPreference(sharedPreferencesName, app);
}
private void setFeaturesCustomized() { private void setFeaturesCustomized() {
featuresCustomized = true; featuresCustomized = true;
} }
@ -405,4 +649,28 @@ public class OsmAndAppCustomization {
public void removeListener(OsmAndAppCustomizationListener listener) { public void removeListener(OsmAndAppCustomizationListener listener) {
this.listeners.remove(listener); this.listeners.remove(listener);
} }
private static class NavDrawerItem {
static final String NAME_KEY = "name";
static final String URI_KEY = "uri";
static final String ICON_NAME_KEY = "icon_name";
static final String FLAGS_KEY = "flags";
private String name;
private String uri;
private String iconName;
private int flags;
NavDrawerItem(String name, String uri, String iconName, int flags) {
this.name = name;
this.uri = uri;
this.iconName = iconName;
this.flags = flags;
}
public String getId() {
return DRAWER_ITEM_ID_SCHEME + name;
}
}
} }

View file

@ -4,6 +4,7 @@ package net.osmand.plus;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorManager; import android.hardware.SensorManager;
@ -28,6 +29,7 @@ import net.osmand.plus.access.AccessibilityMode;
import net.osmand.plus.access.RelativeDirectionStyle; import net.osmand.plus.access.RelativeDirectionStyle;
import net.osmand.plus.api.SettingsAPI; import net.osmand.plus.api.SettingsAPI;
import net.osmand.plus.api.SettingsAPI.SettingsEditor; import net.osmand.plus.api.SettingsAPI.SettingsEditor;
import net.osmand.plus.api.SettingsAPIImpl;
import net.osmand.plus.dialogs.RateUsBottomSheetDialog; import net.osmand.plus.dialogs.RateUsBottomSheetDialog;
import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper;
import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapillary.MapillaryPlugin;
@ -120,6 +122,7 @@ public class OsmandSettings {
} }
// These settings are stored in SharedPreferences // These settings are stored in SharedPreferences
private static final String CUSTOM_SHARED_PREFERENCES_PREFIX = "net.osmand.customsettings.";
private static final String SHARED_PREFERENCES_NAME = "net.osmand.settings"; private static final String SHARED_PREFERENCES_NAME = "net.osmand.settings";
private static String CUSTOM_SHARED_PREFERENCES_NAME; private static String CUSTOM_SHARED_PREFERENCES_NAME;
@ -148,8 +151,9 @@ public class OsmandSettings {
protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI, String sharedPreferencesName) { protected OsmandSettings(OsmandApplication clientContext, SettingsAPI settinsAPI, String sharedPreferencesName) {
ctx = clientContext; ctx = clientContext;
this.settingsAPI = settinsAPI; this.settingsAPI = settinsAPI;
CUSTOM_SHARED_PREFERENCES_NAME = "net.osmand.customsettings." + sharedPreferencesName; CUSTOM_SHARED_PREFERENCES_NAME = CUSTOM_SHARED_PREFERENCES_PREFIX + sharedPreferencesName;
initPrefs(); initPrefs();
setCustomized();
} }
private void initPrefs() { private void initPrefs() {
@ -160,6 +164,12 @@ public class OsmandSettings {
registeredPreferences.put(APPLICATION_MODE.getId(), APPLICATION_MODE); registeredPreferences.put(APPLICATION_MODE.getId(), APPLICATION_MODE);
} }
private static final String SETTING_CUSTOMIZED_ID = "settings_customized";
private void setCustomized() {
settingsAPI.edit(globalPreferences).putBoolean(SETTING_CUSTOMIZED_ID, true).commit();
}
public OsmandApplication getContext() { public OsmandApplication getContext() {
return ctx; return ctx;
} }
@ -182,6 +192,14 @@ public class OsmandSettings {
} }
} }
public static boolean areSettingsCustomizedForPreference(String sharedPreferencesName, OsmandApplication app) {
String customPrefName = CUSTOM_SHARED_PREFERENCES_PREFIX + sharedPreferencesName;
SettingsAPIImpl settingsAPI = new net.osmand.plus.api.SettingsAPIImpl(app);
SharedPreferences globalPreferences = (SharedPreferences) settingsAPI.getPreferenceObject(customPrefName);
return globalPreferences != null && globalPreferences.getBoolean(SETTING_CUSTOMIZED_ID, false);
}
public Object getProfilePreferences(ApplicationMode mode) { public Object getProfilePreferences(ApplicationMode mode) {
return settingsAPI.getPreferenceObject(getSharedPreferencesName(mode)); return settingsAPI.getPreferenceObject(getSharedPreferencesName(mode));
} }