offer 'open with' in context menu for geo uris

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 14 
src/main/java/eu/siacs/conversations/utils/GeoHelper.java         | 81 
src/main/res/menu/message_context.xml                             | 31 
src/main/res/values/strings.xml                                   |  1 
4 files changed, 89 insertions(+), 38 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java πŸ”—

@@ -1065,6 +1065,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
             final boolean receiving = m.getStatus() == Message.STATUS_RECEIVED && (t instanceof JingleConnection || t instanceof HttpDownloadConnection);
             activity.getMenuInflater().inflate(R.menu.message_context, menu);
             menu.setHeaderTitle(R.string.message_options);
+            MenuItem openWith = menu.findItem(R.id.open_with);
             MenuItem copyMessage = menu.findItem(R.id.copy_message);
             MenuItem copyLink = menu.findItem(R.id.copy_link);
             MenuItem quoteMessage = menu.findItem(R.id.quote_message);
@@ -1094,6 +1095,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
             }
             if (!showError
                     && relevantForCorrection.getType() == Message.TYPE_TEXT
+                    && !m.isGeoUri()
                     && relevantForCorrection.isLastCorrectableMessage()
                     && m.getConversation() instanceof Conversation
                     && (((Conversation) m.getConversation()).getMucOptions().nonanonymous() || m.getConversation().getMode() == Conversation.MODE_SINGLE)) {
@@ -1132,6 +1134,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
             if (showError) {
                 showErrorMessage.setVisible(true);
             }
+            if (m.isGeoUri() && GeoHelper.openInOsmAnd(getActivity(),m)) {
+                openWith.setVisible(true);
+            }
         }
     }
 
@@ -1174,6 +1179,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
             case R.id.show_error_message:
                 showErrorMessage(selectedMessage);
                 return true;
+            case R.id.open_with:
+                openWith(selectedMessage);
+                return true;
             default:
                 return super.onContextItemSelected(item);
         }
@@ -1618,6 +1626,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
         return null;
     }
 
+    private void openWith(final Message message) {
+        if (message.isGeoUri()) {
+            GeoHelper.view(getActivity(),message);
+        }
+    }
+
     private void showErrorMessage(final Message message) {
         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         builder.setTitle(R.string.error_message);

src/main/java/eu/siacs/conversations/utils/GeoHelper.java πŸ”—

@@ -7,6 +7,8 @@ import android.content.SharedPreferences;
 import android.net.Uri;
 import android.preference.PreferenceManager;
 
+import org.osmdroid.util.GeoPoint;
+
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import java.util.ArrayList;
@@ -46,42 +48,43 @@ public class GeoHelper {
 		}
 	}
 
-	public static ArrayList<Intent> createGeoIntentsFromMessage(Context context, Message message) {
-		final ArrayList<Intent> intents = new ArrayList<>();
-		Matcher matcher = GEO_URI.matcher(message.getBody());
+	private static GeoPoint parseGeoPoint(String body) throws IllegalArgumentException {
+		Matcher matcher = GEO_URI.matcher(body);
 		if (!matcher.matches()) {
-			return intents;
+			throw new IllegalArgumentException("Invalid geo uri");
 		}
 		double latitude;
 		double longitude;
 		try {
 			latitude = Double.parseDouble(matcher.group(1));
 			if (latitude > 90.0 || latitude < -90.0) {
-				return intents;
+				throw new IllegalArgumentException("Invalid geo uri");
 			}
 			longitude = Double.parseDouble(matcher.group(2));
 			if (longitude > 180.0 || longitude < -180.0) {
-				return intents;
+				throw new IllegalArgumentException("Invalid geo uri");
 			}
-		} catch (NumberFormatException nfe) {
+		} catch (NumberFormatException e) {
+			throw new IllegalArgumentException("Invalid geo uri",e);
+		}
+		return new GeoPoint(latitude, longitude);
+	}
+
+	public static ArrayList<Intent> createGeoIntentsFromMessage(Context context, Message message) {
+		final ArrayList<Intent> intents = new ArrayList<>();
+		final GeoPoint geoPoint;
+		try {
+			geoPoint = parseGeoPoint(message.getBody());
+		} catch (IllegalArgumentException e) {
 			return intents;
 		}
 		final Conversational conversation = message.getConversation();
-		String label;
-		if (conversation instanceof Conversation && conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) {
-			try {
-				label = "(" + URLEncoder.encode(((Conversation)conversation).getName().toString(), "UTF-8") + ")";
-			} catch (UnsupportedEncodingException e) {
-				label = "";
-			}
-		} else {
-			label = "";
-		}
+		final String label = getLabel(context, message);
 
 		if (isLocationPluginInstalledAndDesired(context)) {
 			Intent locationPluginIntent = new Intent(SHOW_LOCATION_PACKAGE_NAME);
-			locationPluginIntent.putExtra("latitude", latitude);
-			locationPluginIntent.putExtra("longitude", longitude);
+			locationPluginIntent.putExtra("latitude", geoPoint.getLatitude());
+			locationPluginIntent.putExtra("longitude", geoPoint.getLongitude());
 			if (message.getStatus() != Message.STATUS_RECEIVED) {
 				locationPluginIntent.putExtra("jid", conversation.getAccount().getJid().toString());
 				locationPluginIntent.putExtra("name", conversation.getAccount().getJid().getLocal());
@@ -98,18 +101,46 @@ public class GeoHelper {
 		} else {
 			Intent intent = new Intent(context, ShowLocationActivity.class);
 			intent.setAction(SHOW_LOCATION_PACKAGE_NAME);
-			intent.putExtra("latitude", latitude);
-			intent.putExtra("longitude", longitude);
+			intent.putExtra("latitude", geoPoint.getLatitude());
+			intent.putExtra("longitude", geoPoint.getLongitude());
 			intents.add(intent);
 		}
 
-		Intent geoIntent = new Intent(Intent.ACTION_VIEW);
-		geoIntent.setData(Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude) + "?q=" + String.valueOf(latitude) + "," + String.valueOf(longitude) + label));
-		intents.add(geoIntent);
+		intents.add(geoIntent(geoPoint, label));
 
 		Intent httpIntent = new Intent(Intent.ACTION_VIEW);
-		httpIntent.setData(Uri.parse("https://maps.google.com/maps?q=loc:"+String.valueOf(latitude) + "," + String.valueOf(longitude) +label));
+		httpIntent.setData(Uri.parse("https://maps.google.com/maps?q=loc:"+String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) +label));
 		intents.add(httpIntent);
 		return intents;
 	}
+
+	public static void view(Context context, Message message) {
+		final GeoPoint geoPoint = parseGeoPoint(message.getBody());
+		final String label = getLabel(context, message);
+		context.startActivity(geoIntent(geoPoint,label));
+	}
+
+	private static Intent geoIntent(GeoPoint geoPoint, String label) {
+		Intent geoIntent = new Intent(Intent.ACTION_VIEW);
+		geoIntent.setData(Uri.parse("geo:" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + "?q=" + String.valueOf(geoPoint.getLatitude()) + "," + String.valueOf(geoPoint.getLongitude()) + "("+ label+")"));
+		return geoIntent;
+	}
+
+	public static boolean openInOsmAnd(Context context, Message message) {
+		final GeoPoint geoPoint = parseGeoPoint(message.getBody());
+		final String label = getLabel(context, message);
+		return geoIntent(geoPoint,label).resolveActivity(context.getPackageManager()) != null;
+	}
+
+	private static String getLabel(Context context, Message message) {
+		if(message.getStatus() == Message.STATUS_RECEIVED) {
+			try {
+				return URLEncoder.encode(UIHelper.getMessageDisplayName(message),"UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				throw new AssertionError(e);
+			}
+		} else {
+			return context.getString(R.string.me);
+		}
+	}
 }

src/main/res/menu/message_context.xml πŸ”—

@@ -1,55 +1,60 @@
 <?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        android:id="@+id/open_with"
+        android:title="@string/open_with"
+        android:visible="false" />
 
     <item
         android:id="@+id/share_with"
         android:title="@string/share_with"
-        android:visible="false"/>
+        android:visible="false" />
 
     <item
         android:id="@+id/copy_message"
         android:title="@string/copy_to_clipboard"
-        android:visible="false"/>
+        android:visible="false" />
 
     <item
         android:id="@+id/copy_link"
         android:title="@string/copy_link"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/quote_message"
         android:title="@string/quote"
-        android:visible="false"/>
+        android:visible="false" />
 
     <item
         android:id="@+id/retry_decryption"
         android:title="@string/retry_decryption"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/correct_message"
         android:title="@string/correct_message"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/copy_url"
         android:title="@string/copy_original_url"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/show_error_message"
         android:title="@string/show_error_message"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/send_again"
         android:title="@string/send_again"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/download_file"
         android:title="@string/download_x_file"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/cancel_transmission"
         android:title="@string/cancel_transmission"
-        android:visible="false"/>
+        android:visible="false" />
     <item
         android:id="@+id/delete_file"
         android:title="@string/delete_x_file"
-        android:visible="false"/>
+        android:visible="false" />
 </menu>

src/main/res/values/strings.xml πŸ”—

@@ -809,4 +809,5 @@
     <string name="group_chat_will_make_your_jabber_id_public">This group chat will make your Jabber ID public</string>
     <string name="ebook">e-book</string>
     <string name="video_original">Original (uncompressed)</string>
+    <string name="open_with">Open with…</string>
 </resources>