offer 'open with' in context menu for geo uris

This commit is contained in:
Daniel Gultsch 2019-01-11 10:13:25 +01:00
parent 394e252777
commit a38cd88702
4 changed files with 89 additions and 38 deletions

View File

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

View File

@ -7,6 +7,8 @@ import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import org.osmdroid.util.GeoPoint;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
@ -46,42 +48,43 @@ public class GeoHelper {
} }
} }
public static ArrayList<Intent> createGeoIntentsFromMessage(Context context, Message message) { private static GeoPoint parseGeoPoint(String body) throws IllegalArgumentException {
final ArrayList<Intent> intents = new ArrayList<>(); Matcher matcher = GEO_URI.matcher(body);
Matcher matcher = GEO_URI.matcher(message.getBody());
if (!matcher.matches()) { if (!matcher.matches()) {
return intents; throw new IllegalArgumentException("Invalid geo uri");
} }
double latitude; double latitude;
double longitude; double longitude;
try { try {
latitude = Double.parseDouble(matcher.group(1)); latitude = Double.parseDouble(matcher.group(1));
if (latitude > 90.0 || latitude < -90.0) { if (latitude > 90.0 || latitude < -90.0) {
return intents; throw new IllegalArgumentException("Invalid geo uri");
} }
longitude = Double.parseDouble(matcher.group(2)); longitude = Double.parseDouble(matcher.group(2));
if (longitude > 180.0 || longitude < -180.0) { 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; return intents;
} }
final Conversational conversation = message.getConversation(); final Conversational conversation = message.getConversation();
String label; final String label = getLabel(context, message);
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 = "";
}
if (isLocationPluginInstalledAndDesired(context)) { if (isLocationPluginInstalledAndDesired(context)) {
Intent locationPluginIntent = new Intent(SHOW_LOCATION_PACKAGE_NAME); Intent locationPluginIntent = new Intent(SHOW_LOCATION_PACKAGE_NAME);
locationPluginIntent.putExtra("latitude", latitude); locationPluginIntent.putExtra("latitude", geoPoint.getLatitude());
locationPluginIntent.putExtra("longitude", longitude); locationPluginIntent.putExtra("longitude", geoPoint.getLongitude());
if (message.getStatus() != Message.STATUS_RECEIVED) { if (message.getStatus() != Message.STATUS_RECEIVED) {
locationPluginIntent.putExtra("jid", conversation.getAccount().getJid().toString()); locationPluginIntent.putExtra("jid", conversation.getAccount().getJid().toString());
locationPluginIntent.putExtra("name", conversation.getAccount().getJid().getLocal()); locationPluginIntent.putExtra("name", conversation.getAccount().getJid().getLocal());
@ -98,18 +101,46 @@ public class GeoHelper {
} else { } else {
Intent intent = new Intent(context, ShowLocationActivity.class); Intent intent = new Intent(context, ShowLocationActivity.class);
intent.setAction(SHOW_LOCATION_PACKAGE_NAME); intent.setAction(SHOW_LOCATION_PACKAGE_NAME);
intent.putExtra("latitude", latitude); intent.putExtra("latitude", geoPoint.getLatitude());
intent.putExtra("longitude", longitude); intent.putExtra("longitude", geoPoint.getLongitude());
intents.add(intent); intents.add(intent);
} }
Intent geoIntent = new Intent(Intent.ACTION_VIEW); intents.add(geoIntent(geoPoint, label));
geoIntent.setData(Uri.parse("geo:" + String.valueOf(latitude) + "," + String.valueOf(longitude) + "?q=" + String.valueOf(latitude) + "," + String.valueOf(longitude) + label));
intents.add(geoIntent);
Intent httpIntent = new Intent(Intent.ACTION_VIEW); 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); intents.add(httpIntent);
return intents; 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);
}
}
} }

View File

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?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 <item
android:id="@+id/share_with" android:id="@+id/share_with"
android:title="@string/share_with" android:title="@string/share_with"

View File

@ -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="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="ebook">e-book</string>
<string name="video_original">Original (uncompressed)</string> <string name="video_original">Original (uncompressed)</string>
<string name="open_with">Open with…</string>
</resources> </resources>