Support for location messages
Start with encoding as a simple image thumbnail for compatibility with MMS and iOS // FREEBIEpull/1/head
parent
4fa6680f83
commit
bcf95e50aa
Binary file not shown.
After Width: | Height: | Size: 521 B |
Binary file not shown.
After Width: | Height: | Size: 371 B |
Binary file not shown.
After Width: | Height: | Size: 675 B |
Binary file not shown.
After Width: | Height: | Size: 970 B |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<FrameLayout android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<com.google.android.gms.maps.MapView
|
||||||
|
android:id="@+id/map_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
|
<ImageView android:id="@+id/image_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:src="@drawable/ic_action_warning_red"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/address_view"
|
||||||
|
android:visibility="visible"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:padding="5dp"
|
||||||
|
tools:text="21 Jump St, Atlanta GA 30311"/>
|
||||||
|
|
||||||
|
</merge>
|
@ -0,0 +1,98 @@
|
|||||||
|
package org.thoughtcrime.securesms.components.location;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.google.android.gms.location.places.Place;
|
||||||
|
import com.google.android.gms.maps.CameraUpdateFactory;
|
||||||
|
import com.google.android.gms.maps.GoogleMap;
|
||||||
|
import com.google.android.gms.maps.MapView;
|
||||||
|
import com.google.android.gms.maps.OnMapReadyCallback;
|
||||||
|
import com.google.android.gms.maps.model.MarkerOptions;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||||
|
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
|
public class SignalMapView extends LinearLayout {
|
||||||
|
|
||||||
|
private MapView mapView;
|
||||||
|
private ImageView imageView;
|
||||||
|
private TextView textView;
|
||||||
|
|
||||||
|
public SignalMapView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SignalMapView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
initialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||||
|
public SignalMapView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
initialize(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize(Context context) {
|
||||||
|
setOrientation(LinearLayout.VERTICAL);
|
||||||
|
LayoutInflater.from(context).inflate(R.layout.signal_map_view, this, true);
|
||||||
|
|
||||||
|
this.mapView = ViewUtil.findById(this, R.id.map_view);
|
||||||
|
this.imageView = ViewUtil.findById(this, R.id.image_view);
|
||||||
|
this.textView = ViewUtil.findById(this, R.id.address_view);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<Bitmap> display(final SignalPlace place) {
|
||||||
|
final SettableFuture<Bitmap> future = new SettableFuture<>();
|
||||||
|
|
||||||
|
this.mapView.onCreate(null);
|
||||||
|
this.mapView.onResume();
|
||||||
|
|
||||||
|
this.mapView.setVisibility(View.VISIBLE);
|
||||||
|
this.imageView.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
this.mapView.getMapAsync(new OnMapReadyCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapReady(final GoogleMap googleMap) {
|
||||||
|
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(place.getLatLong(), 13));
|
||||||
|
googleMap.addMarker(new MarkerOptions().position(place.getLatLong()));
|
||||||
|
googleMap.setBuildingsEnabled(true);
|
||||||
|
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
|
||||||
|
googleMap.getUiSettings().setAllGesturesEnabled(false);
|
||||||
|
googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
|
||||||
|
@Override
|
||||||
|
public void onMapLoaded() {
|
||||||
|
googleMap.snapshot(new GoogleMap.SnapshotReadyCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSnapshotReady(Bitmap bitmap) {
|
||||||
|
future.set(bitmap);
|
||||||
|
imageView.setImageBitmap(bitmap);
|
||||||
|
imageView.setVisibility(View.VISIBLE);
|
||||||
|
mapView.setVisibility(View.GONE);
|
||||||
|
mapView.onPause();
|
||||||
|
mapView.onDestroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.textView.setText(place.getDescription());
|
||||||
|
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.thoughtcrime.securesms.components.location;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.google.android.gms.location.places.Place;
|
||||||
|
import com.google.android.gms.maps.model.LatLng;
|
||||||
|
|
||||||
|
public class SignalPlace {
|
||||||
|
|
||||||
|
private static final String URL = "https://maps.google.com/maps?q=%s,%s";
|
||||||
|
|
||||||
|
private final Place place;
|
||||||
|
|
||||||
|
public SignalPlace(Place place) {
|
||||||
|
this.place = place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LatLng getLatLong() {
|
||||||
|
return place.getLatLng();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
String description = "";
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(place.getName())) {
|
||||||
|
description += (place.getName() + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(place.getAddress())) {
|
||||||
|
description += (place.getAddress() + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
description += String.format(URL, place.getLatLng().latitude, place.getLatLng().longitude);
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.thoughtcrime.securesms.mms;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||||
|
|
||||||
|
public class LocationSlide extends ImageSlide {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
public LocationSlide(@NonNull Context context, @NonNull Uri uri, long size, @NonNull String description)
|
||||||
|
{
|
||||||
|
super(context, uri, size);
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public Optional<String> getBody() {
|
||||||
|
return Optional.of(description);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue