GeoHelper.java

  1package eu.siacs.conversations.utils;
  2
  3import android.content.Context;
  4import android.content.Intent;
  5import android.content.SharedPreferences;
  6import android.net.Uri;
  7import android.preference.PreferenceManager;
  8import de.gultsch.common.Patterns;
  9import eu.siacs.conversations.R;
 10import eu.siacs.conversations.entities.Contact;
 11import eu.siacs.conversations.entities.Conversational;
 12import eu.siacs.conversations.entities.Message;
 13import eu.siacs.conversations.ui.ShareLocationActivity;
 14import eu.siacs.conversations.ui.ShowLocationActivity;
 15import java.io.UnsupportedEncodingException;
 16import java.net.URLEncoder;
 17import java.util.ArrayList;
 18import java.util.regex.Matcher;
 19import org.osmdroid.util.GeoPoint;
 20
 21public class GeoHelper {
 22
 23    private static final String SHARE_LOCATION_PACKAGE_NAME =
 24            "eu.siacs.conversations.location.request";
 25    private static final String SHOW_LOCATION_PACKAGE_NAME = "eu.siacs.conversations.location.show";
 26
 27    public static boolean isLocationPluginInstalled(Context context) {
 28        return new Intent(SHARE_LOCATION_PACKAGE_NAME).resolveActivity(context.getPackageManager())
 29                != null;
 30    }
 31
 32    public static boolean isLocationPluginInstalledAndDesired(Context context) {
 33        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
 34        final boolean configured =
 35                preferences.getBoolean(
 36                        "use_share_location_plugin",
 37                        context.getResources().getBoolean(R.bool.use_share_location_plugin));
 38        return configured && isLocationPluginInstalled(context);
 39    }
 40
 41    public static Intent getFetchIntent(Context context) {
 42        if (isLocationPluginInstalledAndDesired(context)) {
 43            return new Intent(SHARE_LOCATION_PACKAGE_NAME);
 44        } else {
 45            return new Intent(context, ShareLocationActivity.class);
 46        }
 47    }
 48
 49    public static GeoPoint parseGeoPoint(final Uri uri) {
 50        return parseGeoPoint(uri.toString());
 51    }
 52
 53    private static GeoPoint parseGeoPoint(String body) throws IllegalArgumentException {
 54        final Matcher matcher = Patterns.URI_GEO.matcher(body);
 55        if (!matcher.matches()) {
 56            throw new IllegalArgumentException("Invalid geo uri");
 57        }
 58        final double latitude;
 59        final double longitude;
 60        try {
 61            latitude = Double.parseDouble(matcher.group(1));
 62            if (latitude > 90.0 || latitude < -90.0) {
 63                throw new IllegalArgumentException("Invalid geo uri");
 64            }
 65            longitude = Double.parseDouble(matcher.group(2));
 66            if (longitude > 180.0 || longitude < -180.0) {
 67                throw new IllegalArgumentException("Invalid geo uri");
 68            }
 69        } catch (final NumberFormatException e) {
 70            throw new IllegalArgumentException("Invalid geo uri", e);
 71        }
 72        return new GeoPoint(latitude, longitude);
 73    }
 74
 75    public static ArrayList<Intent> createGeoIntentsFromMessage(Context context, Message message) {
 76        final ArrayList<Intent> intents = new ArrayList<>();
 77        final GeoPoint geoPoint;
 78        try {
 79            geoPoint = parseGeoPoint(message.getRawBody());
 80        } catch (IllegalArgumentException e) {
 81            return intents;
 82        }
 83        final Conversational conversation = message.getConversation();
 84        final String label = getLabel(context, message);
 85
 86        if (isLocationPluginInstalledAndDesired(context)) {
 87            Intent locationPluginIntent = new Intent(SHOW_LOCATION_PACKAGE_NAME);
 88            locationPluginIntent.putExtra("latitude", geoPoint.getLatitude());
 89            locationPluginIntent.putExtra("longitude", geoPoint.getLongitude());
 90            if (message.getStatus() != Message.STATUS_RECEIVED) {
 91                locationPluginIntent.putExtra("jid", conversation.getAccount().getJid().toString());
 92                locationPluginIntent.putExtra(
 93                        "name", conversation.getAccount().getJid().getLocal());
 94            } else {
 95                Contact contact = message.getContact();
 96                if (contact != null) {
 97                    locationPluginIntent.putExtra("name", contact.getDisplayName());
 98                    locationPluginIntent.putExtra("jid", contact.getJid().toString());
 99                } else {
100                    locationPluginIntent.putExtra(
101                            "name", UIHelper.getDisplayedMucCounterpart(message.getCounterpart()));
102                }
103            }
104            intents.add(locationPluginIntent);
105        } else {
106            Intent intent = new Intent(context, ShowLocationActivity.class);
107            intent.setAction(SHOW_LOCATION_PACKAGE_NAME);
108            intent.putExtra("latitude", geoPoint.getLatitude());
109            intent.putExtra("longitude", geoPoint.getLongitude());
110            intents.add(intent);
111        }
112
113        intents.add(geoIntent(geoPoint, label));
114
115        Intent httpIntent = new Intent(Intent.ACTION_VIEW);
116        httpIntent.setData(
117                Uri.parse(
118                        "https://maps.google.com/maps?q=loc:"
119                                + geoPoint.getLatitude()
120                                + ","
121                                + geoPoint.getLongitude()
122                                + label));
123        intents.add(httpIntent);
124        return intents;
125    }
126
127    public static void view(Context context, Message message) {
128        final GeoPoint geoPoint = parseGeoPoint(message.getRawBody());
129        final String label = getLabel(context, message);
130        context.startActivity(geoIntent(geoPoint, label));
131    }
132
133    private static Intent geoIntent(GeoPoint geoPoint, String label) {
134        Intent geoIntent = new Intent(Intent.ACTION_VIEW);
135        geoIntent.setData(
136                Uri.parse(
137                        "geo:"
138                                + geoPoint.getLatitude()
139                                + ","
140                                + geoPoint.getLongitude()
141                                + "?q="
142                                + geoPoint.getLatitude()
143                                + ","
144                                + geoPoint.getLongitude()
145                                + "("
146                                + label
147                                + ")"));
148        return geoIntent;
149    }
150
151    public static boolean openInOsmAnd(Context context, Message message) {
152        try {
153            final GeoPoint geoPoint = parseGeoPoint(message.getRawBody());
154            final String label = getLabel(context, message);
155            return geoIntent(geoPoint, label).resolveActivity(context.getPackageManager()) != null;
156        } catch (IllegalArgumentException e) {
157            return false;
158        }
159    }
160
161    private static String getLabel(Context context, Message message) {
162        if (message.getStatus() == Message.STATUS_RECEIVED) {
163            try {
164                return URLEncoder.encode(UIHelper.getMessageDisplayName(message), "UTF-8");
165            } catch (UnsupportedEncodingException e) {
166                throw new AssertionError(e);
167            }
168        } else {
169            return context.getString(R.string.me);
170        }
171    }
172}