Release v0.2

This commit is contained in:
Daniele 2021-09-10 09:45:46 +02:00
parent 809616aefa
commit e558fa28b5
7 changed files with 170 additions and 49 deletions

View File

@ -4,6 +4,7 @@
<option name="filePathToZoomLevelMap">
<map>
<entry key="../../../../layout/custom_preview.xml" value="0.5661458333333333" />
<entry key="app/src/main/res/layout/activity_geofavorite_detail.xml" value="0.4" />
<entry key="app/src/main/res/layout/activity_list_view.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/layout/item_geofav.xml" value="0.5307291666666667" />

View File

@ -24,8 +24,8 @@ android {
applicationId "it.danieleverducci.nextcloudmaps"
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "0.1"
versionCode 2
versionName "0.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -0,0 +1,20 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "it.danieleverducci.nextcloudmaps",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 2,
"versionName": "0.2",
"outputFile": "app-release.apk"
}
],
"elementType": "File"
}

View File

@ -20,11 +20,14 @@ package it.danieleverducci.nextcloudmaps.activity.detail;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
@ -33,6 +36,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.util.Date;
import it.danieleverducci.nextcloudmaps.R;
import it.danieleverducci.nextcloudmaps.api.ApiProvider;
import it.danieleverducci.nextcloudmaps.databinding.ActivityGeofavoriteDetailBinding;
@ -44,32 +49,38 @@ import retrofit2.Response;
public class GeofavoriteDetailActivity extends AppCompatActivity implements LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
public static final String TAG = "GeofavDetail";
public static final String DEFAULT_CATEGORY = "Personal";
public static final int MINIMUM_ACCEPTABLE_ACCURACY = 50; // In meters
public static final String ARG_GEOFAVORITE = "geofav";
private static final int PERMISSION_REQUEST_CODE = 9999;
private ActivityGeofavoriteDetailBinding binding;
private ViewHolder mViewHolder;
private Geofavorite mGeofavorite;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityGeofavoriteDetailBinding.inflate(getLayoutInflater());
setContentView(binding.root);
mViewHolder = new ViewHolder(getLayoutInflater());
mViewHolder.setOnSubmitListener(this::saveGeofavorite);
setContentView(mViewHolder.getRootView());
if (getIntent().hasExtra(ARG_GEOFAVORITE)) {
// Opening geofavorite from list
Geofavorite gfFromList = (Geofavorite) getIntent().getSerializableExtra(ARG_GEOFAVORITE);
binding.setGeofavorite(gfFromList);
mGeofavorite = (Geofavorite) getIntent().getSerializableExtra(ARG_GEOFAVORITE);
mViewHolder.hideAccuracy();
} else {
// New geofavorite
Geofavorite gf = new Geofavorite();
gf.setDateCreated(System.currentTimeMillis());
gf.setDateModified(System.currentTimeMillis());
binding.setGeofavorite(gf);
mGeofavorite = new Geofavorite();
mGeofavorite.setCategory(DEFAULT_CATEGORY);
mGeofavorite.setDateCreated(System.currentTimeMillis());
mGeofavorite.setDateModified(System.currentTimeMillis());
// Precompile location
getLocation();
}
mViewHolder.updateView(mGeofavorite);
}
/**
@ -84,23 +95,20 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
* 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());
mViewHolder.updateModel(mGeofavorite);
if (!gf.valid()) {
if (!mGeofavorite.valid()) {
Toast.makeText(GeofavoriteDetailActivity.this, R.string.incomplete_geofavorite, Toast.LENGTH_SHORT).show();
return;
}
Call<Geofavorite> call;
if (gf.getId() == 0) {
if (mGeofavorite.getId() == 0) {
// New geofavorite
call = ApiProvider.getAPI().createGeofavorite(gf);
call = ApiProvider.getAPI().createGeofavorite(mGeofavorite);
} else {
// Update existing geofavorite
call = ApiProvider.getAPI().updateGeofavorite(gf.getId(), gf);
call = ApiProvider.getAPI().updateGeofavorite(mGeofavorite.getId(), mGeofavorite);
}
call.enqueue(new Callback<Geofavorite>() {
@Override
@ -145,9 +153,12 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
* @param location to set in the geofavorite
*/
private void updateLocationField(Location location) {
binding.getGeofavorite().setLat(location.getLatitude());
binding.getGeofavorite().setLng(location.getLongitude());
binding.notifyChange();
// Update model
mGeofavorite.setLat(location.getLatitude());
mGeofavorite.setLng(location.getLongitude());
// Update view
mViewHolder.updateViewCoords(mGeofavorite.getCoordinatesString());
mViewHolder.setAccuracy(location.getAccuracy());
}
@ -185,4 +196,68 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
}
}
}
private class ViewHolder implements View.OnClickListener {
private final ActivityGeofavoriteDetailBinding binding;
private OnSubmitListener listener;
public ViewHolder(LayoutInflater inflater) {
this.binding = ActivityGeofavoriteDetailBinding.inflate(inflater);
this.binding.submitBt.setOnClickListener(this);
}
public View getRootView() {
return this.binding.root;
}
public void updateView(Geofavorite item) {
binding.nameEt.setText(item.getName());
binding.descriptionEt.setText(item.getComment());
binding.createdTv.setText(new Date(item.getDateCreated() * 1000).toString());
binding.modifiedTv.setText(new Date(item.getDateModified() * 1000).toString());
binding.categoryTv.setText(item.getCategory()); // TODO: Category spinner from existing categories
binding.coordsTv.setText(item.getCoordinatesString());
}
public void updateViewCoords(String coords) {
binding.coordsTv.setText(coords);
}
public void updateModel(Geofavorite item) {
item.setName(binding.nameEt.getText().toString());
item.setComment(binding.descriptionEt.getText().toString());
item.setDateModified(System.currentTimeMillis() / 1000);
}
public void setAccuracy(float accuracy) {
binding.accuracyTv.setText(getString(R.string.accuracy).replace("{accuracy}", ((int)accuracy) + ""));
// Color the accuracy background with a scale from red (MINIMUM_ACCEPTABLE_ACCURACY) to green (0 meters)
float red = accuracy / MINIMUM_ACCEPTABLE_ACCURACY;
if (red > 1.0f) red = 1.0f;
float green = 1.0f - red;
if (Build.VERSION.SDK_INT >= 26)
binding.accuracyTv.setBackgroundColor(Color.rgb(red, green, 0.0f));
}
public void hideAccuracy() {
binding.accuracyTv.setVisibility(View.GONE);
}
public void setOnSubmitListener(OnSubmitListener listener) {
this.listener = listener;
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.submit_bt && this.listener != null) {
this.listener.onSubmit();
}
}
}
protected interface OnSubmitListener {
void onSubmit();
}
}

View File

@ -25,6 +25,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.databinding.BindingAdapter;
import com.google.gson.annotations.Expose;
@ -90,13 +92,13 @@ public class Geofavorite implements Serializable {
}
public void setName(String name) {
if (!name.equals(this.name))
this.name = name;
}
public long getDateModified() {
return dateModified;
}
public void setDateModified(long dateModified) {
this.dateModified = dateModified;
}
@ -104,7 +106,6 @@ public class Geofavorite implements Serializable {
public long getDateCreated() {
return dateCreated;
}
public void setDateCreated(long dateCreated) {
this.dateCreated = dateCreated;
}
@ -112,7 +113,6 @@ public class Geofavorite implements Serializable {
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
@ -120,7 +120,6 @@ public class Geofavorite implements Serializable {
public double getLng() {
return lng;
}
public void setLng(double lng) {
this.lng = lng;
}
@ -128,7 +127,6 @@ public class Geofavorite implements Serializable {
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
@ -137,24 +135,20 @@ public class Geofavorite implements Serializable {
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public static Comparator<Geofavorite> ByTitleAZ = (note, t1) -> note.name.compareTo(t1.name);
public static Comparator<Geofavorite> ByLastCreated = (note, t1) -> t1.id - note.id;
public String getCoordinatesString() {
return this.lat + " N, " + this.lng + " E";
}
public Uri getGeoUri() {
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;
}

View File

@ -2,12 +2,6 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="geofavorite"
type="it.danieleverducci.nextcloudmaps.model.Geofavorite"/>
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -41,8 +35,7 @@
android:lines="1"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="end"
android:text="@{geofavorite.name}"/>
android:ellipsize="end"/>
<EditText
android:id="@+id/description_et"
@ -51,9 +44,10 @@
android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
android:lines="5"
android:maxLines="10"
android:hint="@string/description"
android:ellipsize="end"
android:text="@{geofavorite.comment}" />
android:ellipsize="end" />
<TextView
android:layout_width="match_parent"
@ -66,8 +60,33 @@
android:id="@+id/created_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="textEnd"
app:formatDate="@{geofavorite.dateCreated}" />
android:textAlignment="textEnd" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textStyle="bold"
android:text="@string/modified" />
<TextView
android:id="@+id/modified_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="textEnd" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textStyle="bold"
android:text="@string/category" />
<TextView
android:id="@+id/category_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="textEnd" />
<TextView
android:layout_width="match_parent"
@ -80,8 +99,17 @@
android:id="@+id/coords_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="textEnd"
android:text="@{geofavorite.lat +` °N, ` + geofavorite.lng + ` °E`}" />
android:textAlignment="textEnd" />
<TextView
android:id="@+id/accuracy_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textAlignment="center"
android:text="@string/accuracy"
android:textColor="@android:color/white"
android:background="@android:color/darker_gray"/>
<Button
android:id="@+id/submit_bt"

View File

@ -49,7 +49,10 @@
<string name="name">Name</string>
<string name="description">Description</string>
<string name="created">Created</string>
<string name="modified">Modified</string>
<string name="category">Category</string>
<string name="coords">Coordinates</string>
<string name="accuracy">Accuracy: {accuracy} m</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>