Add new geofavorite

This commit is contained in:
Daniele Verducci (ZenPenguin) 2021-08-28 17:14:07 +02:00
parent 2b5cba0dea
commit 63f2ab9520
5 changed files with 181 additions and 63 deletions

View File

@ -40,6 +40,10 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
buildFeatures {
dataBinding true
}
} }
repositories { repositories {

View File

@ -25,6 +25,8 @@ import android.location.LocationListener;
import android.location.LocationManager; import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -33,26 +35,87 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import it.danieleverducci.nextcloudmaps.R; import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
import it.danieleverducci.nextcloudmaps.model.Geofavorite;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class GeofavoriteDetailActivity extends AppCompatActivity implements LocationListener, ActivityCompat.OnRequestPermissionsResultCallback { public class GeofavoriteDetailActivity extends AppCompatActivity implements LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
public static final String TAG = "GeofavDetail";
public static final String ARG_GEOFAVORITE_ID = "geofavid"; public static final String ARG_GEOFAVORITE_ID = "geofavid";
private static final int PERMISSION_REQUEST_CODE = 9999; private static final int PERMISSION_REQUEST_CODE = 9999;
private ActivityGeofavoriteDetailBinding binding;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geofavorite_detail); binding = ActivityGeofavoriteDetailBinding.inflate(getLayoutInflater());
setContentView(binding.root);
int id = getIntent().getIntExtra(ARG_GEOFAVORITE_ID, 0); int id = getIntent().getIntExtra(ARG_GEOFAVORITE_ID, 0);
if (id == 0) { if (id == 0) {
// New geofavorite: precompile location // New geofavorite
Geofavorite gf = new Geofavorite();
gf.setDateCreated(System.currentTimeMillis());
gf.setDateModified(System.currentTimeMillis());
binding.setGeofavorite(gf);
// Precompile location
getLocation(); getLocation();
} else {
// TODO: Load geofavorite from cache for edit
} }
} }
/**
* Called when the submit button is clicked
* @param v The button
*/
public void onSubmit(View v) {
saveGeofavorite();
}
/**
* Checks fields and sends updated geofavorite to Nextcloud instance
*/
private void saveGeofavorite() {
Geofavorite gf = binding.getGeofavorite();
gf.setName(binding.nameEt.getText().toString());
gf.setComment(binding.descriptionEt.getText().toString());
gf.setDateModified(System.currentTimeMillis());
if (!gf.valid()) {
Toast.makeText(GeofavoriteDetailActivity.this, R.string.incomplete_geofavorite, Toast.LENGTH_SHORT).show();
return;
}
Call<Geofavorite> call;
if (gf.getId() == 0) {
// New geofavorite
call = ApiProvider.getAPI().createGeofavorite(gf);
} else {
// Update existing geofavorite
call = ApiProvider.getAPI().updateGeofavorite(gf.getId(), gf);
}
call.enqueue(new Callback<Geofavorite>() {
@Override
public void onResponse(Call<Geofavorite> call, Response<Geofavorite> response) {
finish();
}
@Override
public void onFailure(Call<Geofavorite> call, Throwable t) {
Toast.makeText(GeofavoriteDetailActivity.this, R.string.error_saving_geofavorite, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to update geofavorite: " + t.getMessage());
}
});
}
/** /**
* Obtains the current location (requesting user's permission, if necessary) * Obtains the current location (requesting user's permission, if necessary)
* and calls updateLocationField() * and calls updateLocationField()
@ -73,7 +136,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
updateLocationField(lastKnown); updateLocationField(lastKnown);
// Register for location updates in case the user moves before saving // Register for location updates in case the user moves before saving
locationManager.requestLocationUpdates( locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, this LocationManager.GPS_PROVIDER, 1000, 10, this
); );
} }
@ -82,7 +145,9 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
* @param location to set in the geofavorite * @param location to set in the geofavorite
*/ */
private void updateLocationField(Location location) { private void updateLocationField(Location location) {
Log.d("Location", location.toString()); binding.getGeofavorite().setLat(location.getLatitude());
binding.getGeofavorite().setLng(location.getLongitude());
binding.notifyChange();
} }

View File

@ -21,12 +21,18 @@
package it.danieleverducci.nextcloudmaps.model; package it.danieleverducci.nextcloudmaps.model;
import android.net.Uri; import android.net.Uri;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.BindingAdapter;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.io.Serializable; import java.io.Serializable;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date;
public class Geofavorite implements Serializable { public class Geofavorite implements Serializable {
/** /**
@ -48,6 +54,7 @@ public class Geofavorite implements Serializable {
@SerializedName("id") private int id; @SerializedName("id") private int id;
@Expose @Expose
@Nullable
@SerializedName("name") private String name; @SerializedName("name") private String name;
@Expose @Expose
@ -57,15 +64,16 @@ public class Geofavorite implements Serializable {
@SerializedName("date_created") private long dateCreated; @SerializedName("date_created") private long dateCreated;
@Expose @Expose
@SerializedName("lat") private float lat; @SerializedName("lat") private double lat;
@Expose @Expose
@SerializedName("lng") private float lng; @SerializedName("lng") private double lng;
@Expose @Expose
@SerializedName("category") private String category; @SerializedName("category") private String category;
@Expose @Expose
@Nullable
@SerializedName("comment") private String comment; @SerializedName("comment") private String comment;
public int getId() { public int getId() {
@ -76,6 +84,7 @@ public class Geofavorite implements Serializable {
this.id = id; this.id = id;
} }
@Nullable
public String getName() { public String getName() {
return name; return name;
} }
@ -100,19 +109,19 @@ public class Geofavorite implements Serializable {
this.dateCreated = dateCreated; this.dateCreated = dateCreated;
} }
public float getLat() { public double getLat() {
return lat; return lat;
} }
public void setLat(float lat) { public void setLat(double lat) {
this.lat = lat; this.lat = lat;
} }
public float getLng() { public double getLng() {
return lng; return lng;
} }
public void setLng(float lng) { public void setLng(double lng) {
this.lng = lng; this.lng = lng;
} }
@ -124,6 +133,7 @@ public class Geofavorite implements Serializable {
this.category = category; this.category = category;
} }
@Nullable
public String getComment() { public String getComment() {
return comment; return comment;
} }
@ -140,4 +150,18 @@ public class Geofavorite implements Serializable {
return Uri.parse("geo:" + this.lat + "," + this.lng + "(" + this.name + ")"); return Uri.parse("geo:" + this.lat + "," + this.lng + "(" + this.name + ")");
} }
@BindingAdapter("formatDate")
public static void formatDate(@NonNull TextView textView, long timestamp) {
textView.setText((new Date(timestamp)).toString());
}
public boolean valid() {
return getLat() != 0 && getLng() != 0 && getName() != null && getName().length() > 0;
}
@NonNull
@Override
public String toString() {
return "[" + getName() + " (" + getLat() + "," + getLng() + ")]";
}
} }

View File

@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="geofavorite"
type="it.danieleverducci.nextcloudmaps.model.Geofavorite"/>
</data>
<LinearLayout
android:id="@+id/root"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
@ -24,7 +33,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"
android:hint="@string/name" /> android:hint="@string/name"
android:text="@{geofavorite.name}"/>
<EditText <EditText
android:id="@+id/description_et" android:id="@+id/description_et"
@ -33,7 +43,8 @@
android:ems="10" android:ems="10"
android:gravity="start|top" android:gravity="start|top"
android:inputType="textMultiLine" android:inputType="textMultiLine"
android:hint="@string/description" /> android:hint="@string/description"
android:text="@{geofavorite.comment}" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -47,7 +58,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:text="" /> app:formatDate="@{geofavorite.dateCreated}" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -61,8 +72,19 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" android:textAlignment="textEnd"
android:text="" /> android:text="@{geofavorite.lat +` °N, ` + geofavorite.lng + ` °E`}" />
<Button
android:id="@+id/submit_bt"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="50dp"
android:text="@string/confirm"
app:backgroundTint="@color/defaultBrand"
android:onClick="onSubmit"/>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</layout>

View File

@ -42,6 +42,9 @@
<string name="created">Created</string> <string name="created">Created</string>
<string name="coords">Coordinates</string> <string name="coords">Coordinates</string>
<string name="location_permission_required">Location permission is required to create a geofavorite.</string> <string name="location_permission_required">Location permission is required to create a geofavorite.</string>
<string name="confirm">Save</string>
<string name="error_saving_geofavorite">Unable to save geofavorite</string>
<string name="incomplete_geofavorite">Incomplete geofavorite: Name and GPS coordinates are mandatory</string>
<!-- About --> <!-- About -->
<string name="about_version_title">Version</string> <string name="about_version_title">Version</string>