diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/AndroidManifest.xml | 29 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/Config.java | 3 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java | 171 | ||||
-rw-r--r-- | src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java | 101 | ||||
-rw-r--r-- | src/main/res/layout/share_locaction_activity.xml | 99 | ||||
-rw-r--r-- | src/main/res/layout/show_locaction_activity.xml | 23 | ||||
-rw-r--r-- | src/main/res/values-de/strings.xml | 8 | ||||
-rw-r--r-- | src/main/res/values/strings.xml | 6 |
8 files changed, 438 insertions, 2 deletions
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 9b85f1a4d..1310816c4 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -15,6 +15,9 @@ <uses-permission android:name="android.permission.NFC"/> <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" @@ -25,7 +28,9 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/ConversationsTheme" + android:name="android.support.multidex.MultiDexApplication" tools:replace="android:label"> + <service android:name=".services.XmppConnectionService"/> <receiver android:name=".services.EventReceiver"> @@ -172,6 +177,30 @@ <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> + <meta-data + android:name="com.google.android.gms.version" + android:value="@integer/google_play_services_version" /> + <meta-data + android:name="com.google.android.maps.v2.API_KEY" + android:value="@string/google_maps_api_key" /> + + <activity + android:name=".ui.ShareLocationActivity" + android:label="@string/share_location" > + <intent-filter> + <action android:name="eu.siacs.conversations.location.request" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <activity + android:name=".ui.ShowLocationActivity" + android:label="@string/show_location" > + <intent-filter> + <action android:name="eu.siacs.conversations.location.show" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> <activity android:name=".ui.TrustKeysActivity" android:label="@string/trust_omemo_fingerprints" diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 810aab229..78067b905 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -6,7 +6,6 @@ import eu.siacs.conversations.xmpp.chatstate.ChatState; public final class Config { - private static final int UNENCRYPTED = 1; private static final int OPENPGP = 2; private static final int OTR = 4; @@ -75,6 +74,8 @@ public final class Config { public static final int FILE_MAX_SIZE = 1048576; //1 MiB + public static final int DEFAULT_ZOOM = 15; //for locations + public static final int MESSAGE_MERGE_WINDOW = 20; public static final int PAGE_SIZE = 20; diff --git a/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java new file mode 100644 index 000000000..f532ab38c --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java @@ -0,0 +1,171 @@ +package eu.siacs.conversations.ui; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Intent; +import android.location.Location; +import android.os.Build; +import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.view.View; +import android.widget.Button; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.location.LocationListener; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.model.LatLng; + +public class ShareLocationActivity extends Activity implements OnMapReadyCallback, + GoogleApiClient.ConnectionCallbacks, + GoogleApiClient.OnConnectionFailedListener, + LocationListener{ + + private GoogleMap mGoogleMap; + private GoogleApiClient mGoogleApiClient; + private LocationRequest mLocationRequest; + private Location mLastLocation; + private Button mCancelButton; + private Button mShareButton; + private RelativeLayout mSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.share_locaction_activity); + MapFragment fragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map_fragment); + fragment.getMapAsync(this); + mGoogleApiClient = new GoogleApiClient.Builder(this) + .addApi(LocationServices.API) + .addConnectionCallbacks(this) + .addOnConnectionFailedListener(this) + .build(); + mCancelButton = (Button) findViewById(R.id.cancel_button); + mCancelButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + setResult(RESULT_CANCELED); + finish(); + } + }); + mShareButton = (Button) findViewById(R.id.share_button); + mShareButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (mLastLocation != null) { + Intent result = new Intent(); + result.putExtra("latitude",mLastLocation.getLatitude()); + result.putExtra("longitude",mLastLocation.getLongitude()); + result.putExtra("altitude",mLastLocation.getAltitude()); + result.putExtra("accuracy",(int) mLastLocation.getAccuracy()); + setResult(RESULT_OK, result); + finish(); + } + } + }); + mSnackbar = (RelativeLayout) findViewById(R.id.snackbar); + TextView snackbarAction = (TextView) findViewById(R.id.snackbar_action); + snackbarAction.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)); + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + this.mLastLocation = null; + if (isLocationEnabled()) { + this.mSnackbar.setVisibility(View.GONE); + } else { + this.mSnackbar.setVisibility(View.VISIBLE); + } + mShareButton.setEnabled(false); + mShareButton.setTextColor(0x8a000000); + mShareButton.setText(R.string.locating); + mGoogleApiClient.connect(); + } + + @Override + protected void onPause() { + mGoogleApiClient.disconnect(); + super.onPause(); + } + + @Override + public void onMapReady(GoogleMap googleMap) { + this.mGoogleMap = googleMap; + this.mGoogleMap.setMyLocationEnabled(true); + } + + private void centerOnLocation(LatLng location) { + this.mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(location, Config.DEFAULT_ZOOM)); + } + + @Override + public void onConnected(Bundle bundle) { + mLocationRequest = LocationRequest.create(); + mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + mLocationRequest.setInterval(1000); + + LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); + } + + @Override + public void onConnectionSuspended(int i) { + + } + + @Override + public void onConnectionFailed(ConnectionResult connectionResult) { + + } + + @Override + public void onLocationChanged(Location location) { + if (this.mLastLocation == null) { + centerOnLocation(new LatLng(location.getLatitude(), location.getLongitude())); + this.mShareButton.setEnabled(true); + this.mShareButton.setTextColor(0xde000000); + this.mShareButton.setText(R.string.share); + } + this.mLastLocation = location; + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + private boolean isLocationEnabledKitkat() { + try { + int locationMode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE); + return locationMode != Settings.Secure.LOCATION_MODE_OFF; + } catch (Settings.SettingNotFoundException e) { + return false; + } + } + + @SuppressWarnings("deprecation") + private boolean isLocationEnabledLegacy() { + String locationProviders = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); + return !TextUtils.isEmpty(locationProviders); + } + + private boolean isLocationEnabled() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){ + return isLocationEnabledKitkat(); + }else{ + return isLocationEnabledLegacy(); + } + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java b/src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java new file mode 100644 index 000000000..79219a01c --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/ShowLocationActivity.java @@ -0,0 +1,101 @@ +package eu.siacs.conversations.ui; + +import android.app.ActionBar; +import android.app.Activity; +import android.content.Intent; +import android.location.Location; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.location.LocationListener; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.MapFragment; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.MarkerOptions; + +public class ShowLocationActivity extends Activity implements OnMapReadyCallback { + + private GoogleMap mGoogleMap; + private LatLng mLocation; + private String mLocationName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ActionBar actionBar = getActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + + setContentView(R.layout.show_locaction_activity); + MapFragment fragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map_fragment); + fragment.getMapAsync(this); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onResume() { + super.onResume(); + Intent intent = getIntent(); + + this.mLocationName = intent != null ? intent.getStringExtra("name") : null; + + if (intent != null && intent.hasExtra("longitude") && intent.hasExtra("latitude")) { + double longitude = intent.getDoubleExtra("longitude",0); + double latitude = intent.getDoubleExtra("latitude",0); + this.mLocation = new LatLng(latitude,longitude); + if (this.mGoogleMap != null) { + markAndCenterOnLocation(this.mLocation, this.mLocationName); + } + } + } + + @Override + protected void onPause() { + super.onPause(); + } + + @Override + public void onMapReady(GoogleMap googleMap) { + this.mGoogleMap = googleMap; + this.mGoogleMap.setMyLocationEnabled(true); + if (this.mLocation != null) { + this.markAndCenterOnLocation(this.mLocation,this.mLocationName); + } + } + + private void markAndCenterOnLocation(LatLng location, String name) { + this.mGoogleMap.clear(); + MarkerOptions options = new MarkerOptions(); + options.position(location); + if (name != null) { + options.title(name); + this.mGoogleMap.addMarker(options).showInfoWindow(); + } else { + this.mGoogleMap.addMarker(options); + } + this.mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(location, Config.DEFAULT_ZOOM)); + } + +} diff --git a/src/main/res/layout/share_locaction_activity.xml b/src/main/res/layout/share_locaction_activity.xml new file mode 100644 index 000000000..a52632666 --- /dev/null +++ b/src/main/res/layout/share_locaction_activity.xml @@ -0,0 +1,99 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:map="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/ripple_material_dark"> + <fragment + android:name="com.google.android.gms.maps.MapFragment" + android:id="@+id/map_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_above="@+id/snackbar" + map:mapType="normal" + map:uiCompass="false" + map:uiRotateGestures="false" + map:uiScrollGestures="true" + map:uiTiltGestures="false" + map:uiZoomControls="false" + map:uiZoomGestures="true" + tools:ignore="MissingPrefix"/> + + <RelativeLayout + android:id="@+id/snackbar" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginBottom="4dp" + android:layout_marginLeft="8dp" + android:layout_marginRight="8dp" + android:layout_above="@+id/button_bar" + android:background="@drawable/snackbar" + android:minHeight="48dp" + android:visibility="visible" > + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_centerVertical="true" + android:layout_toLeftOf="@+id/snackbar_action" + android:paddingLeft="24dp" + android:textColor="@color/grey50" + android:textSize="?attr/TextSizeBody" + android:text="@string/location_sharing_disabled"/> + + <TextView + android:id="@+id/snackbar_action" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingBottom="16dp" + android:paddingLeft="24dp" + android:paddingRight="24dp" + android:paddingTop="16dp" + android:textAllCaps="true" + android:textColor="@color/grey50" + android:textSize="?attr/TextSizeBody" + android:textStyle="bold" + android:text="@string/enable" + android:layout_alignParentTop="true" + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true"/> + </RelativeLayout> + + <LinearLayout + android:id="@+id/button_bar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:layout_alignParentLeft="true" + android:layout_alignParentRight="true" > + + <Button + android:id="@+id/cancel_button" + style="?android:attr/borderlessButtonStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/cancel" + android:textColor="@color/primary" /> + + <View + android:layout_width="1dp" + android:layout_height="fill_parent" + android:layout_marginBottom="7dp" + android:layout_marginTop="7dp" + android:background="@color/primary" /> + + <Button + android:id="@+id/share_button" + style="?android:attr/borderlessButtonStyle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:enabled="false" + android:text="@string/share" + android:textColor="@color/secondary_text_disabled_material_light" /> + </LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/src/main/res/layout/show_locaction_activity.xml b/src/main/res/layout/show_locaction_activity.xml new file mode 100644 index 000000000..d22422015 --- /dev/null +++ b/src/main/res/layout/show_locaction_activity.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:map="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <fragment + + android:name="com.google.android.gms.maps.MapFragment" + android:id="@+id/map_fragment" + android:layout_width="match_parent" + android:layout_height="match_parent" + map:mapType="normal" + map:uiCompass="false" + map:uiRotateGestures="false" + map:uiScrollGestures="true" + map:uiTiltGestures="false" + map:uiZoomControls="false" + map:uiZoomGestures="true" + tools:ignore="MissingPrefix"/> + +</RelativeLayout>
\ No newline at end of file diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 660bbf68d..117dd0993 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -634,4 +634,12 @@ <string name="presence_xa">Nicht verfügbar</string> <string name="presence_dnd">Beschäftigt</string> <string name="secure_password_generated">Ein sicheres Passwort wurde erstellt</string> + <string name="device_does_not_support_battery_op">Dein Gerät unterstützt keine Batterieoptimierungen</string> + <string name="locating">Lokalisiere…</string> + <string name="location_sharing_disabled">GPS ist in den Android-Einstellungen deaktiviert</string> + <string name="no_mic_permissions">Keine Berechtigung zur Audioaufnahme </string> + <string name="openpgp_has_been_published">Öffentlicher OpenPGP Schlüssel wurde veröffentlicht.</string> + <string name="republish_pgp_keys">Deine öffentliche OpenPGP Schlüssel müssen veröffentlicht werden!</string> + <string name="share">Teilen</string> + <string name="share_location">Standort teilen</string> </resources> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 643a8168d..a5190236b 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -672,7 +672,11 @@ <string name="presence_dnd">Busy</string> <string name="secure_password_generated">A secure password has been generated</string> <string name="device_does_not_support_battery_op">Your device does not support opting out of battery optimization</string> - <string name="share">Teilen</string> + <string name="share">Share</string> <string name="no_mic_permissions">No permissions to record audio</string> + <string name="share_location">Share location</string> + <string name="location_sharing_disabled">Location sharing is disabled in settings</string> + <string name="locating">Locating…</string> + <string name="captcha_ocr">Captcha Text</string> </resources> |