diff options
Diffstat (limited to 'main/src/cgeo/geocaching/apps')
-rw-r--r-- | main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java | 183 |
1 files changed, 163 insertions, 20 deletions
diff --git a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java index 13a81ff..6053948 100644 --- a/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java +++ b/main/src/cgeo/geocaching/apps/cache/navi/NavigationAppFactory.java @@ -6,6 +6,7 @@ import cgeo.geocaching.Settings; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgGeo; import cgeo.geocaching.cgWaypoint; +import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.apps.AbstractAppFactory; import cgeo.geocaching.geopoint.Geopoint; @@ -15,6 +16,10 @@ import android.content.DialogInterface; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; import java.util.ArrayList; import java.util.List; @@ -22,16 +27,27 @@ import java.util.List; public final class NavigationAppFactory extends AbstractAppFactory { public enum NavigationAppsEnum { + /** The internal compass activity */ COMPASS(new CompassApp(), 0), + /** The external radar app */ RADAR(new RadarApp(), 1), + /** The selected map */ INTERNAL_MAP(new InternalMap(), 2), + /** The internal static map activity */ STATIC_MAP(new StaticMapApp(), 3), + /** The external Locus app */ LOCUS(new LocusApp(), 4), + /** The external RMaps app */ RMAPS(new RMapsApp(), 5), + /** Google Maps */ GOOGLE_MAPS(new GoogleMapsApp(), 6), + /** Google Navigation */ GOOGLE_NAVIGATION(new GoogleNavigationApp(), 7), + /** Google Streetview */ GOOGLE_STREETVIEW(new StreetviewApp(), 8), + /** The external OruxMaps app */ ORUX_MAPS(new OruxMapsApp(), 9), + /** The external navigon app */ NAVIGON(new NavigonApp(), 10); NavigationAppsEnum(NavigationApp app, int id) { @@ -49,35 +65,88 @@ public final class NavigationAppFactory extends AbstractAppFactory { public final int id; } - private static final int MENU_ITEM_OFFSET = 12345; - - public static void addMenuItems(final Menu menu, final Activity activity) { - addMenuItems(menu, activity, true, false); + /** + * Default way to handle selection of navigation tool.<br /> + * A dialog is created for tool selection and the selected tool is started afterwards. + * <p /> + * Delegates to + * {@link #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint, boolean, boolean)} with + * <code>showInternalMap = true</code> and <code>showDefaultNavigation = false</code> + * + * @param geo + * @param activity + * @param cache + * @param search + * @param waypoint + * @param destination + */ + public static void showNavigationMenu(final cgGeo geo, final Activity activity, + final cgCache cache, final SearchResult search, final cgWaypoint waypoint, final Geopoint destination) { + showNavigationMenu(geo, activity, cache, search, waypoint, destination, true, false); } - public static void addMenuItems(final Menu menu, final Activity activity, + /** + * Specialized way to handle selection of navigation tool.<br /> + * A dialog is created for tool selection and the selected tool is started afterwards. + * + * @param geo + * @param activity + * @param cache + * may be <code>null</code> + * @param search + * may be <code>null</code> + * @param waypoint + * may be <code>null</code> + * @param destination + * may be <code>null</code> + * @param showInternalMap + * should be <code>false</code> only when called from within the internal map + * @param showDefaultNavigation + * should be <code>false</code> by default + * + * @see #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint) + */ + public static void showNavigationMenu(final cgGeo geo, final Activity activity, + final cgCache cache, final SearchResult search, final cgWaypoint waypoint, final Geopoint destination, final boolean showInternalMap, final boolean showDefaultNavigation) { + final AlertDialog.Builder builder = new AlertDialog.Builder(activity); + builder.setTitle(R.string.cache_menu_navigate); + builder.setIcon(android.R.drawable.ic_menu_mapmode); + final List<NavigationAppsEnum> items = new ArrayList<NavigationAppFactory.NavigationAppsEnum>(); final int defaultNavigationTool = Settings.getDefaultNavigationTool(); + final boolean isOffline = cache != null ? cgeoapplication.getInstance().isOffline(cache.getGeocode(), null) : false; for (NavigationAppsEnum navApp : getInstalledNavigationApps(activity)) { if ((showInternalMap || !(navApp.app instanceof InternalMap)) && - (showDefaultNavigation || defaultNavigationTool != navApp.id)) { - menu.add(0, MENU_ITEM_OFFSET + navApp.id, 0, navApp.app.getName()); + (showDefaultNavigation || defaultNavigationTool != navApp.id) && + (isOffline && NavigationAppsEnum.STATIC_MAP.id == navApp.id)) { + items.add(navApp); } } - } + /* + * Using an ArrayAdapter with list of NavigationAppsEnum items avoids + * handling between mapping list positions allows us to do dynamic filtering of the list based on usecase. + */ + final ArrayAdapter<NavigationAppsEnum> adapter = new ArrayAdapter<NavigationAppsEnum>(activity, android.R.layout.select_dialog_item, items) { + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView textView = (TextView) super.getView(position, convertView, parent); + textView.setText(getItem(position).app.getName()); + return textView; + } - public static void showNavigationMenu(final cgGeo geo, final Activity activity, final cgCache cache, final SearchResult search) { - final AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle(R.string.cache_menu_navigate); - builder.setIcon(android.R.drawable.ic_menu_mapmode); - final List<NavigationAppsEnum> installed = getInstalledNavigationApps(activity); - final String[] items = new String[installed.size()]; - for (int i = 0; i < installed.size(); i++) { - items[i] = installed.get(i).app.getName(); - } - builder.setItems(items, new DialogInterface.OnClickListener() { + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + TextView textView = (TextView) super.getDropDownView(position, convertView, parent); + textView.setText(getItem(position).app.getName()); + return textView; + } + }; + adapter.setDropDownViewResource(android.R.layout.select_dialog_item); + + builder.setAdapter(adapter, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { - installed.get(item).app.invoke(geo, activity, cache, search, null, null); + NavigationAppsEnum selectedItem = adapter.getItem(item); + selectedItem.app.invoke(geo, activity, cache, search, waypoint, destination); } }); final AlertDialog alert = builder.create(); @@ -85,6 +154,12 @@ public final class NavigationAppFactory extends AbstractAppFactory { } + /** + * Returns all installed navigation apps. + * + * @param activity + * @return + */ public static List<NavigationAppsEnum> getInstalledNavigationApps(final Activity activity) { final List<NavigationAppsEnum> installedNavigationApps = new ArrayList<NavigationAppsEnum>(); for (NavigationAppsEnum appEnum : NavigationAppsEnum.values()) { @@ -95,6 +170,64 @@ public final class NavigationAppFactory extends AbstractAppFactory { return installedNavigationApps; } + /** + * This offset is used to build unique menu ids to avoid collisions of ids in menus + */ + private static final int MENU_ITEM_OFFSET = 12345; + + /** + * Adds the installed navigation tools to the given menu. + * Use {@link #onMenuItemSelected(MenuItem, cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint)} on + * selection event to start the selected navigation tool. + * + * <b>Only use this way if {@link #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint)} + * is not suitable for the given usecase.</b> + * + * @param menu + * @param activity + */ + public static void addMenuItems(final Menu menu, final Activity activity) { + addMenuItems(menu, activity, true, false); + } + + /** + * Adds the installed navigation tools to the given menu. + * Use {@link #onMenuItemSelected(MenuItem, cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint)} on + * selection event to start the selected navigation tool. + * + * <b>Only use this way if + * {@link #showNavigationMenu(cgGeo, Activity, cgCache, SearchResult, cgWaypoint, Geopoint, boolean, boolean)} is + * not suitable for the given usecase.</b> + * + * @param menu + * @param activity + * @param showInternalMap + * @param showDefaultNavigation + */ + public static void addMenuItems(final Menu menu, final Activity activity, + final boolean showInternalMap, final boolean showDefaultNavigation) { + final int defaultNavigationTool = Settings.getDefaultNavigationTool(); + for (NavigationAppsEnum navApp : getInstalledNavigationApps(activity)) { + if ((showInternalMap || !(navApp.app instanceof InternalMap)) && + (showDefaultNavigation || defaultNavigationTool != navApp.id)) { + menu.add(0, MENU_ITEM_OFFSET + navApp.id, 0, navApp.app.getName()); + } + } + } + + /** + * Handles menu selections for menu entries created with {@link #addMenuItems(Menu, Activity)} or + * {@link #addMenuItems(Menu, Activity, boolean, boolean)}. + * + * @param item + * @param geo + * @param activity + * @param cache + * @param search + * @param waypoint + * @param destination + * @return + */ public static boolean onMenuItemSelected(final MenuItem item, final cgGeo geo, Activity activity, cgCache cache, final SearchResult search, cgWaypoint waypoint, final Geopoint destination) { @@ -114,7 +247,7 @@ public final class NavigationAppFactory extends AbstractAppFactory { return false; } - public static NavigationApp getAppFromMenuItem(MenuItem item) { + private static NavigationApp getAppFromMenuItem(MenuItem item) { final int id = item.getItemId(); for (NavigationAppsEnum navApp : NavigationAppsEnum.values()) { if (MENU_ITEM_OFFSET + navApp.id == id) { @@ -124,6 +257,16 @@ public final class NavigationAppFactory extends AbstractAppFactory { return null; } + /** + * Starts the default navigation tool if correctly set and installed or the compass app as default fallback. + * + * @param geo + * @param activity + * @param cache + * @param search + * @param waypoint + * @param destination + */ public static void startDefaultNavigationApplication(final cgGeo geo, Activity activity, cgCache cache, final SearchResult search, cgWaypoint waypoint, final Geopoint destination) { final NavigationApp app = getDefaultNavigationApplication(activity); |