@@ -39,5 +39,6 @@ dependencies { | |||
testImplementation 'junit:junit:4.12' | |||
androidTestImplementation 'androidx.test.ext:junit:1.1.2' | |||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | |||
compile 'com.google.maps.android:android-maps-utils:0.6.2' | |||
} |
@@ -3,7 +3,6 @@ | |||
package="com.example.meinwald"> | |||
<application | |||
android:name="com.example.meinwald.MyApplication" | |||
android:allowBackup="true" | |||
android:icon="@mipmap/ic_launcher" | |||
android:label="@string/app_name" | |||
@@ -25,7 +24,7 @@ | |||
android:value="@string/google_maps_key" /> | |||
<service | |||
android:name=".ui.area.LocationTrack" | |||
android:name=".ui.area.LocationService" | |||
android:exported="false"> | |||
</service> | |||
@@ -1,18 +0,0 @@ | |||
package com.example.meinwald; | |||
import android.app.Application; | |||
import android.content.Context; | |||
public class MyApplication extends Application { | |||
private static Context context; | |||
public void onCreate() { | |||
super.onCreate(); | |||
MyApplication.context = getApplicationContext(); | |||
} | |||
public static Context getAppContext() { | |||
return MyApplication.context; | |||
} | |||
} |
@@ -3,7 +3,8 @@ package com.example.meinwald.ui.area; | |||
import android.app.AlertDialog; | |||
import android.content.Context; | |||
import android.content.DialogInterface; | |||
import android.graphics.Rect; | |||
import android.database.DataSetObserver; | |||
import android.os.Build; | |||
import android.util.Log; | |||
import android.view.Gravity; | |||
import android.view.LayoutInflater; | |||
@@ -16,23 +17,23 @@ import android.widget.Toast; | |||
import com.example.meinwald.BuildConfig; | |||
import com.example.meinwald.R; | |||
import com.example.meinwald.ui.task.OwnTask; | |||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import androidx.appcompat.widget.AlertDialogLayout; | |||
import androidx.appcompat.widget.LinearLayoutCompat; | |||
import androidx.annotation.RequiresApi; | |||
import androidx.constraintlayout.widget.ConstraintLayout; | |||
import static java.security.AccessController.getContext; | |||
public class AreaAdapter extends BaseAdapter | |||
{ | |||
private final static String TAG = AreaAdapter.class.getSimpleName(); | |||
List<OwnArea> areaList; | |||
LayoutInflater inflater; | |||
Context context; | |||
boolean deleted = false; | |||
Integer deletedPosition = null; | |||
public AreaAdapter(Context applicationContext, List<OwnArea> areaList) | |||
{ | |||
@@ -49,30 +50,30 @@ public class AreaAdapter extends BaseAdapter | |||
} | |||
@Override | |||
public View getView(final int i, View view, final ViewGroup viewGroup) { | |||
public View getView(final int i, final View view, final ViewGroup viewGroup) { | |||
view = inflater.inflate(R.layout.area_element, null); | |||
final ConstraintLayout elementView = view.findViewById(R.id.areaElement); | |||
final ConstraintLayout infovView = view.findViewById(R.id.areaInfoView); | |||
final TextView title = (TextView) view.findViewById(R.id.areaInfoTitle); | |||
final TextView notice = (TextView) view.findViewById(R.id.areaInfoNotice); | |||
final ImageView icon = (ImageView) view.findViewById(R.id.areaIcon); | |||
final ImageView manageArea = (ImageView) view.findViewById(R.id.areaManageArea); | |||
final View areaView = inflater.inflate(R.layout.area_element, null); | |||
final ConstraintLayout elementView = areaView.findViewById(R.id.areaElement); | |||
final ConstraintLayout infovView = areaView.findViewById(R.id.areaInfoView); | |||
final TextView title = (TextView) areaView.findViewById(R.id.areaInfoTitle); | |||
final TextView notice = (TextView) areaView.findViewById(R.id.areaInfoNotice); | |||
final TextView area = (TextView) areaView.findViewById(R.id.areaInfoArea); | |||
final ImageView icon = (ImageView) areaView.findViewById(R.id.areaIcon); | |||
final ImageView manageArea = (ImageView) areaView.findViewById(R.id.areaManageArea); | |||
context = view.getContext(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d("AreaAdapter",areaList.get(i).toString()); | |||
Log.d("AreaAdapter",areaList.get(i).getTitle()); | |||
Log.d("AreaAdapter",areaList.get(i).getNotice()); | |||
} | |||
context = areaView.getContext(); | |||
title.setText(areaList.get(i).getTitle()); | |||
notice.setText(areaList.get(i).getNotice()); | |||
icon.setImageBitmap(areaList.get(i).getImage()); | |||
if (areaList.get(i).getArea() != null) | |||
{ | |||
area.setText(String. format("%.2f", areaList.get(i).getArea()) + " Quadratmeter"); | |||
} | |||
manageArea.setOnClickListener(new View.OnClickListener() { | |||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) | |||
@Override | |||
public void onClick(View v) | |||
{ | |||
@@ -80,22 +81,38 @@ public class AreaAdapter extends BaseAdapter | |||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management, viewGroup, false); | |||
builder.setView(viewInflated); | |||
builder.setCancelable(true); | |||
//get elements | |||
TextView title = viewInflated.findViewById(R.id.areaManageTitle); | |||
final TextView notice = viewInflated.findViewById(R.id.areaManageNotice); | |||
TextView gpscount = viewInflated.findViewById(R.id.areaManageGPSPoints); | |||
ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | |||
final TextView lastChecked = viewInflated.findViewById(R.id.areaManagementLastChecked); | |||
ImageView newNotice = (ImageView) viewInflated.findViewById(R.id.areaManageNewDescription); | |||
ImageView newGPS = (ImageView) viewInflated.findViewById(R.id.areaManageNewGPS); | |||
ImageView newImage = (ImageView) viewInflated.findViewById(R.id.areaManageNewImage); | |||
ImageView deleteArea = (ImageView) viewInflated.findViewById(R.id.areaManageDeleteArea); | |||
ImageView newDate = (ImageView) viewInflated.findViewById(R.id.areaManageNewDate); | |||
//set current vlues | |||
//set current values | |||
title.setText(areaList.get(i).getTitle()); | |||
notice.setText(areaList.get(i).getNotice()); | |||
gpscount.setText(String.valueOf(areaList.get(i).getLocations().size())); | |||
if (areaList.get(i).getCheckHistory() != null) | |||
{ | |||
lastChecked.setText(areaList.get(i).parseAndFormatLastCheckUpdate()); | |||
} | |||
if (areaList.get(i).getLocations() != null) | |||
{ | |||
gpscount.setText(String.valueOf(areaList.get(i).getLocations().size())); | |||
} | |||
else | |||
{ | |||
gpscount.setText(String.valueOf(0)); | |||
} | |||
if (areaList.get(i).getImage() != null) | |||
{ | |||
@@ -112,6 +129,7 @@ public class AreaAdapter extends BaseAdapter | |||
newbuilder.setView(viewInflated); | |||
final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | |||
noticeView.setText(areaList.get(i).getNotice()); | |||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
@@ -133,12 +151,108 @@ public class AreaAdapter extends BaseAdapter | |||
newbuilder.show(); | |||
}}); | |||
newDate.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||
newbuilder.setTitle("Neu Kontrolle hinzufügen?"); | |||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
areaList.get(i).addCheckDate(new Date()); | |||
lastChecked.setText(areaList.get(i).parseAndFormatLastCheckUpdate()); | |||
//notifyDataSetChanged(); | |||
if (BuildConfig.DEBUG) { | |||
for (OwnArea area : areaList) { | |||
Log.d(TAG, "areaList item: " + area.toString()); | |||
} | |||
} | |||
dialog.dismiss(); | |||
} | |||
}); | |||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
newbuilder.show(); | |||
}}); | |||
deleteArea.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(final View v) { | |||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||
newbuilder.setTitle("Das Grundstück wirklich löschen?"); | |||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
areaList.get(i).deleteFromExternalStorage(context); | |||
areaList.remove(i); | |||
notifyDataSetChanged(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
for (OwnArea area: areaList) | |||
{ | |||
Log.d(TAG, "areaList item: " + area.toString()); | |||
} | |||
} | |||
dialog.dismiss(); | |||
((ViewGroup)viewInflated.getParent()).removeView(viewInflated); | |||
builder.show().cancel(); | |||
} | |||
}); | |||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
newbuilder.show(); | |||
}}); | |||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
if (areaList.size() > i && areaList.get(i) != null) | |||
{ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "update area: " + areaList.get(i).toString()); | |||
} | |||
areaList.get(i).deleteFromExternalStorage(context); | |||
areaList.get(i).writeToExternalStorage(context); | |||
} | |||
if (BuildConfig.DEBUG) | |||
{ | |||
for (OwnArea area: areaList) | |||
{ | |||
Log.d(TAG, "areaList item: " + area.toString()); | |||
} | |||
} | |||
dialog.dismiss(); | |||
} | |||
}); | |||
@@ -194,7 +308,16 @@ public class AreaAdapter extends BaseAdapter | |||
} | |||
}); | |||
return view; | |||
return areaView; | |||
} | |||
public boolean isDeleted() { | |||
return deleted; | |||
} | |||
public Integer getDeletedPosition() | |||
{ | |||
return deletedPosition; | |||
} | |||
@Override |
@@ -5,6 +5,8 @@ import android.annotation.SuppressLint; | |||
import android.app.AlertDialog; | |||
import android.content.DialogInterface; | |||
import android.content.pm.PackageManager; | |||
import android.database.DataSetObserver; | |||
import android.location.Location; | |||
import android.os.Bundle; | |||
import android.os.PowerManager; | |||
import android.preference.PreferenceManager; | |||
@@ -28,7 +30,10 @@ import com.example.meinwald.BuildConfig; | |||
import com.example.meinwald.R; | |||
import com.google.android.gms.location.FusedLocationProviderClient; | |||
import com.google.android.gms.location.LocationServices; | |||
import com.google.android.gms.maps.CameraUpdateFactory; | |||
import com.google.android.gms.maps.model.LatLng; | |||
import com.google.android.gms.tasks.OnCompleteListener; | |||
import com.google.android.gms.tasks.Task; | |||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||
import org.json.JSONArray; | |||
@@ -66,6 +71,11 @@ public class AreaFragment extends Fragment { | |||
* LOCATION | |||
*/ | |||
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; | |||
/** | |||
* The geographical location where the device is currently located. | |||
* That is the last-known location retrieved by the Fused Location Provider. | |||
*/ | |||
private Location mLastKnownLocation; | |||
/** | |||
* The entry point to the Fused Location Provider. | |||
*/ | |||
@@ -124,6 +134,10 @@ public class AreaFragment extends Fragment { | |||
//get saved areas | |||
allAreas = loadAreasFromPreferences(); | |||
for (int i = 0; i < allAreas.size(); i++) | |||
{ | |||
allAreas.get(i).setPathFile(areaReferences.get(i).getPath()); | |||
} | |||
instantiateAreasList(); | |||
PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE); | |||
@@ -144,13 +158,14 @@ public class AreaFragment extends Fragment { | |||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); | |||
newArea = new OwnArea(); | |||
newPositions = new ArrayList<>(); | |||
final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.area_input, (ViewGroup) getView(), false); | |||
builder.setView(viewInflated); | |||
final Button startTracking = viewInflated.findViewById(R.id.areaStartTracking); | |||
final Button stopTracking = viewInflated.findViewById(R.id.areaStopTracking); | |||
final Button addLocation = viewInflated.findViewById(R.id.areaAddGPSPoint); | |||
startTracking.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
@@ -161,6 +176,7 @@ public class AreaFragment extends Fragment { | |||
startTracking.setVisibility(View.INVISIBLE); | |||
stopTracking.setVisibility(View.VISIBLE); | |||
addLocation.setVisibility(View.INVISIBLE); | |||
} | |||
}); | |||
@@ -169,21 +185,35 @@ public class AreaFragment extends Fragment { | |||
public void onClick(View view) { | |||
//stop tracking | |||
newPositions = gps.getPositions(); | |||
List<LatLng> positionsToAdd = new ArrayList<>(); | |||
positionsToAdd = gps.getPositions(); | |||
for (LatLng pos: positionsToAdd) | |||
{ | |||
newPositions.add(pos); | |||
} | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "Received locations: " + newPositions.size()); | |||
} | |||
newArea.setLocations(newPositions); | |||
wakeLock.release(); | |||
startTracking.setVisibility(View.VISIBLE); | |||
stopTracking.setVisibility(View.INVISIBLE); | |||
addLocation.setVisibility(View.VISIBLE); | |||
} | |||
}); | |||
addLocation.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
//get last known location | |||
getDeviceLocation(); | |||
}}); | |||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
@@ -200,6 +230,8 @@ public class AreaFragment extends Fragment { | |||
//save user input | |||
newArea.setTitle(String.valueOf(titleView.getText())); | |||
newArea.setNotice(String.valueOf(noticeView.getText())); | |||
newArea.setLocations(newPositions); | |||
newArea.calculateArea(); | |||
boolean result = allAreas.add(newArea); | |||
@@ -209,9 +241,10 @@ public class AreaFragment extends Fragment { | |||
Log.d(TAG, "add new task result: " + result); | |||
} | |||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||
newArea.writeToExternalStorage(getContext()); | |||
areaReferences.add(new AreaReference(newArea.getId(), newArea.getPathFile())); | |||
areaReferences.add(new AreaReference(newArea.getId(), writeAreaToExternalStorage(newArea))); | |||
emptyPreferencesAndSaveAreaReferencesToPreferences(); | |||
//actuate list | |||
instantiateAreasList(); | |||
@@ -245,7 +278,12 @@ public class AreaFragment extends Fragment { | |||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
public void onClick(DialogInterface dialog, int which) | |||
{ | |||
//reset variables | |||
newArea = new OwnArea(); | |||
newPositions = new ArrayList<>(); | |||
dialog.cancel(); | |||
} | |||
}); | |||
@@ -262,6 +300,39 @@ public class AreaFragment extends Fragment { | |||
public void instantiateAreasList() | |||
{ | |||
final AreaAdapter adapter = new AreaAdapter(getActivity().getApplicationContext(), allAreas); | |||
adapter.registerDataSetObserver(new DataSetObserver() { | |||
@Override | |||
public void onChanged() { | |||
super.onChanged(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "onChanged"); | |||
} | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "dataset size: " + areaList.getAdapter().getCount()); | |||
} | |||
if (areaList.getAdapter().getCount() > 0) | |||
{ | |||
allAreas = new ArrayList<>(); | |||
areaReferences =new ArrayList<>(); | |||
for (int i = 0; i < areaList.getAdapter().getCount(); i++) | |||
{ | |||
allAreas.add((OwnArea) areaList.getAdapter().getItem(i)); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "dataset added: " + allAreas.get(i).toString()); | |||
} | |||
areaReferences.add(new AreaReference(allAreas.get(i).getId(), allAreas.get(i).getPathFile())); | |||
} | |||
} | |||
} | |||
}); | |||
areaList.setAdapter(adapter); | |||
//initialise onClickListeners | |||
@@ -319,55 +390,6 @@ public class AreaFragment extends Fragment { | |||
return areas; | |||
} | |||
/** | |||
* Save OwnArea object in textfile on external storage. | |||
* | |||
* @param newArea OwnArea object to write to file. | |||
* @return | |||
*/ | |||
private String writeAreaToExternalStorage(OwnArea newArea){ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "writeAreaToExternalStorage()"); | |||
} | |||
// Find the root of the external storage. | |||
File root = android.os.Environment.getExternalStorageDirectory(); | |||
//create file if it does not exist | |||
File path = new File (getContext().getFilesDir(), "meinWald" + File.pathSeparator + "areas"); | |||
if(!path.exists()){ | |||
path.mkdirs(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "Create new text file: " + path); | |||
} | |||
} | |||
File file = new File(path, newArea.getId() + ".txt"); | |||
//open file and write to it | |||
try { | |||
FileOutputStream f = new FileOutputStream(file); | |||
PrintWriter pw = new PrintWriter(f); | |||
pw.print(areaToString(newArea)); | |||
pw.close(); | |||
f.close(); | |||
} catch (FileNotFoundException e) { | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||
} | |||
} catch (IOException e) { | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.e(TAG, "Failed write to external storage: " + e.toString()); | |||
} | |||
} | |||
return file.getPath(); | |||
} | |||
/** | |||
* Read OwnArea from file in external storage and return as a string. | |||
* | |||
@@ -393,6 +415,10 @@ public class AreaFragment extends Fragment { | |||
while ((line = br.readLine()) != null) { | |||
text.append(line); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "Line: " + line); | |||
} | |||
} | |||
br.close(); | |||
} | |||
@@ -438,8 +464,19 @@ public class AreaFragment extends Fragment { | |||
String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error"); | |||
if(!"error".equalsIgnoreCase(jsonString)) { | |||
JSONArray jsonObjects = new JSONArray(jsonString); | |||
for (int i = 0; i<jsonObjects.length();i++) { | |||
for (int i = 0; i<jsonObjects.length();i++) | |||
{ | |||
areas.add(new AreaReference(jsonObjects.getJSONObject(i))); | |||
// Find the root of the external storage. | |||
File root = android.os.Environment.getExternalStorageDirectory(); | |||
//delete reference if file does not exist | |||
File file = new File(getContext().getFilesDir(), "meinWald" + File.pathSeparator + "areas" + File.pathSeparator + areas.get(i).getId() + ".txt"); | |||
if(file.exists()) | |||
{ | |||
areas.remove(i); | |||
} | |||
} | |||
} | |||
else | |||
@@ -468,7 +505,7 @@ public class AreaFragment extends Fragment { | |||
} | |||
/** | |||
* Saves epicolors to preferences | |||
* Saves areas to preferences | |||
*/ | |||
private void emptyPreferencesAndSaveAreaReferencesToPreferences() | |||
{ | |||
@@ -562,6 +599,49 @@ public class AreaFragment extends Fragment { | |||
} | |||
/** | |||
* Get the best and most recent location of the device, which may be null in rare | |||
* cases when a location is not available. | |||
* | |||
*/ | |||
private void getDeviceLocation() { | |||
try { | |||
if (mLocationPermissionGranted) { | |||
Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation(); | |||
locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() { | |||
@Override | |||
public void onComplete(@NonNull Task<Location> task) { | |||
if (task.isSuccessful()) | |||
{ | |||
// Set the last known position to the current location of the device and add to tracking stack | |||
mLastKnownLocation = task.getResult(); | |||
newPositions.add(new LatLng(mLastKnownLocation.getLatitude(),mLastKnownLocation.getLongitude())); | |||
if (BuildConfig.DEBUG) { | |||
if (task.getResult() != null) | |||
{ | |||
Log.d(TAG, "getDeviceLocation: " + task.getResult().toString()); | |||
Log.d(TAG, "Size: " + newPositions.size()); | |||
} | |||
} | |||
} else { | |||
if (BuildConfig.DEBUG) { | |||
Log.d(TAG, "Current location is null. Using defaults."); | |||
Log.e(TAG, "Exception: %s", task.getException()); | |||
} | |||
} | |||
} | |||
}); | |||
} | |||
} catch (SecurityException e) { | |||
if (BuildConfig.DEBUG) { | |||
Log.e(TAG, "Exception occurred: "); | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
public void startLocationTracking(){ | |||
final Runnable runnable= new Runnable() { |
@@ -53,7 +53,7 @@ public class LocationService extends Service implements LocationListener { | |||
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 5 meters | |||
// The minimum time between updates in milliseconds | |||
private static final long MIN_TIME_BW_UPDATES = 1000 * 5 * 1; // 5 seconds | |||
private static final long MIN_TIME_BW_UPDATES = 1000 * 1 * 1; // 5 seconds | |||
// Declaring a Location Manager | |||
protected LocationManager mLocationManager; | |||
@@ -268,7 +268,7 @@ public class LocationService extends Service implements LocationListener { | |||
Log.d(TAG, "onLocationChanged(), new location: " + location.toString()); | |||
} | |||
positions.add(new LatLng(location.getLatitude(), getLongitude())); | |||
positions.add(new LatLng(location.getLatitude(), location.getLongitude())); | |||
} | |||
@Override |
@@ -1,18 +1,25 @@ | |||
package com.example.meinwald.ui.area; | |||
import android.content.Context; | |||
import android.graphics.Bitmap; | |||
import android.location.Location; | |||
import android.util.Log; | |||
import com.example.meinwald.BuildConfig; | |||
import com.google.android.gms.maps.model.LatLng; | |||
import com.google.maps.android.SphericalUtil; | |||
import org.json.JSONArray; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import java.sql.Time; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.PrintWriter; | |||
import java.text.SimpleDateFormat; | |||
import java.util.ArrayList; | |||
import java.util.Calendar; | |||
import java.util.Date; | |||
import java.util.List; | |||
@@ -23,8 +30,10 @@ public class OwnArea { | |||
private List<LatLng> locations; | |||
private Bitmap image; | |||
private String pathImage; | |||
private String pathLocations; | |||
private String pathFile; | |||
private String id; | |||
private List<Date> checkHistory; | |||
private Double area; | |||
public void setImage(Bitmap image) { | |||
this.image = image; | |||
@@ -47,8 +56,21 @@ public class OwnArea { | |||
this.pathImage = pathImage; | |||
} | |||
public void setPathLocations(String pathLocations) { | |||
this.pathLocations = pathLocations; | |||
public void setPathFile(String pathFile) { | |||
this.pathFile = pathFile; | |||
} | |||
public Double getArea() { | |||
return area; | |||
} | |||
public void setArea(Double area) { | |||
this.area = area; | |||
} | |||
public void calculateArea() | |||
{ | |||
this.area = SphericalUtil.computeArea(this.locations); | |||
} | |||
public String getNotice() { | |||
@@ -75,16 +97,49 @@ public class OwnArea { | |||
return pathImage; | |||
} | |||
public String getPathLocations() { | |||
return pathLocations; | |||
public String getPathFile() { | |||
return pathFile; | |||
} | |||
public OwnArea() | |||
public List<Date> getCheckHistory() { | |||
return checkHistory; | |||
} | |||
public void setCheckHistory(List<Date> checkHistory) { | |||
this.checkHistory = checkHistory; | |||
} | |||
public void addCheckDate(Date newDate) | |||
{ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "add DATE"); | |||
} | |||
if(this.checkHistory == null) | |||
{ | |||
this.checkHistory = new ArrayList<>(); | |||
} | |||
this.checkHistory.add(newDate); | |||
} | |||
public OwnArea() | |||
{ | |||
this.title = null; | |||
this.id = null; | |||
this.notice = null; | |||
this.pathFile = null; | |||
this.image = null; | |||
this.pathImage = null; | |||
this.locations = new ArrayList<>(); | |||
this.checkHistory = new ArrayList<>(); | |||
} | |||
public OwnArea(String jsonString){ | |||
public OwnArea(String jsonString) | |||
{ | |||
this.checkHistory = new ArrayList<>(); | |||
this.locations = new ArrayList<>(); | |||
try { | |||
JSONObject areaObject = new JSONObject(jsonString); | |||
this.title = areaObject.getString("title"); | |||
@@ -104,6 +159,24 @@ public class OwnArea { | |||
} | |||
} | |||
String historyString = areaObject.getString("history"); | |||
JSONArray history = new JSONArray(historyString); | |||
this.checkHistory = new ArrayList<>(); | |||
for (int i = 0; i<history.length();i++) { | |||
this.checkHistory.add(new Date(history.getJSONObject(i).getLong("date"))); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "read location: " + this.checkHistory.get(i).toString()); | |||
} | |||
} | |||
if (this.locations != null && this.locations.size()>2) | |||
{ | |||
calculateArea(); | |||
} | |||
} catch (JSONException e) { | |||
if (BuildConfig.DEBUG) { | |||
Log.e(this.getClass().getSimpleName(), "area json: " + jsonString); | |||
@@ -124,6 +197,85 @@ public class OwnArea { | |||
return id; | |||
} | |||
/** | |||
* Save OwnArea object in textfile on external storage. | |||
* | |||
* @return | |||
*/ | |||
public void writeToExternalStorage(Context context){ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "writeAreaToExternalStorage()"); | |||
} | |||
// Find the root of the external storage. | |||
File root = android.os.Environment.getExternalStorageDirectory(); | |||
//create file if it does not exist | |||
File path = new File (context.getFilesDir(), "meinWald" + File.pathSeparator + "areas"); | |||
if(!path.exists()){ | |||
path.mkdirs(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "Create new text file: " + path); | |||
} | |||
} | |||
File file = new File(path, this.getId() + ".txt"); | |||
//open file and write to it | |||
try { | |||
FileOutputStream f = new FileOutputStream(file); | |||
PrintWriter pw = new PrintWriter(f); | |||
pw.print(this.toJSONObject()); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "Json to write in file: " + this.toJSONObject().toString()); | |||
} | |||
pw.close(); | |||
f.close(); | |||
} catch (FileNotFoundException e) { | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.e(getClass().getSimpleName(), "Failed write to external storage: " + e.toString()); | |||
} | |||
} catch (IOException e) { | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.e(getClass().getSimpleName(), "Failed write to external storage: " + e.toString()); | |||
} | |||
} | |||
this.pathFile = file.getPath(); | |||
} | |||
/** | |||
* Delete OwnArea object textfile from external storage. | |||
*/ | |||
public void deleteFromExternalStorage(Context context) | |||
{ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "deleteFromExternalStorage()"); | |||
} | |||
// Find the root of the external storage. | |||
File root = android.os.Environment.getExternalStorageDirectory(); | |||
//delete file if exists | |||
File file = new File(context.getFilesDir(), "meinWald" + File.pathSeparator + "areas" + File.pathSeparator + this.getId() + ".txt"); | |||
if(!file.exists()){ | |||
file.delete(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "Delete text file: " + file.getPath()); | |||
} | |||
} | |||
} | |||
/** | |||
* Returns OwnArea as JSONObject. | |||
@@ -140,27 +292,71 @@ public class OwnArea { | |||
//convert all locations | |||
JSONArray writeObjects = new JSONArray(); | |||
for (LatLng location: this.locations) { | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "Save locations, locations size: " + locations.size()); | |||
} | |||
JSONObject singleLocationObject = new JSONObject(); | |||
singleLocationObject.put("Lat", location.latitude); | |||
singleLocationObject.put("Lng", location.longitude); | |||
if (this.locations != null && this.locations.size() > 0) | |||
{ | |||
for (LatLng location: this.locations) { | |||
writeObjects.put(singleLocationObject); | |||
JSONObject singleLocationObject = new JSONObject(); | |||
singleLocationObject.put("Lat", location.latitude); | |||
singleLocationObject.put("Lng", location.longitude); | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "added location object: " + singleLocationObject.toString()); | |||
writeObjects.put(singleLocationObject); | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "added location object: " + singleLocationObject.toString()); | |||
} | |||
} | |||
} | |||
object.put("locations", writeObjects.toString()); | |||
//convert all locations | |||
writeObjects = new JSONArray(); | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "Save history, history size: " + checkHistory.size()); | |||
} | |||
if (this.checkHistory != null && this.checkHistory.size() > 0) | |||
{ | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "history not empty"); | |||
} | |||
for (Date date : this.checkHistory) { | |||
JSONObject singleHistoryObject = new JSONObject(); | |||
singleHistoryObject.put("date", date.getTime()); | |||
writeObjects.put(singleHistoryObject); | |||
if (BuildConfig.DEBUG) { | |||
Log.d("OwnArea", "added history object: " + singleHistoryObject.toString()); | |||
} | |||
} | |||
} | |||
object.put("history", writeObjects.toString()); | |||
if (area!=null) | |||
{ | |||
object.put("area",this.area); | |||
} | |||
else | |||
{ | |||
object.put("area", null); | |||
} | |||
return object; | |||
} catch (JSONException e) { | |||
if (BuildConfig.DEBUG) { | |||
Log.e(this.getClass().getSimpleName(), | |||
String.format("Error while parsing epiColorDto to JSONObject. Values of epiColorDto: %s", this.toString())); | |||
String.format("Error while parsing OwnArea to JSONObject. Values of OwnArea: %s", this.toString())); | |||
} | |||
return null; | |||
} | |||
@@ -172,8 +368,41 @@ public class OwnArea { | |||
"title='" + title + '\'' + | |||
", notice='" + notice + '\'' + | |||
", pathImage='" + pathImage + '\'' + | |||
", pathLocations='" + pathLocations + '\'' + | |||
", pathLocations='" + pathFile + '\'' + | |||
", id='" + id + '\'' + | |||
", dates='" + checkHistory.size() + '\'' + | |||
'}'; | |||
} | |||
/** | |||
* Parses last check update from milliseconds to string and formats it to "dd.MM.yyyy hh:mm". | |||
* | |||
* @return date parsed and mapped as string representation | |||
*/ | |||
public String parseAndFormatLastCheckUpdate() { | |||
SimpleDateFormat formatter = new SimpleDateFormat( "dd.MM.yyyy kk:mm"); | |||
Calendar calendar = Calendar.getInstance(); | |||
if (checkHistory != null && checkHistory.size()> 0) | |||
{ | |||
calendar.setTimeInMillis(this.checkHistory.get(this.checkHistory.size()-1).getTime()); | |||
} | |||
else | |||
{ | |||
return "Keine Kontrolle vorhanden!"; | |||
} | |||
return formatter.format(calendar.getTime()); | |||
} | |||
public Long getLastChecked() | |||
{ | |||
if (checkHistory != null && checkHistory.size()> 0) | |||
{ | |||
return this.checkHistory.get(this.checkHistory.size()-1).getTime(); | |||
} | |||
else | |||
{ | |||
return (long) -1; | |||
} | |||
} | |||
} |
@@ -4,6 +4,7 @@ import android.Manifest; | |||
import android.content.pm.PackageManager; | |||
import android.graphics.Bitmap; | |||
import android.graphics.BitmapFactory; | |||
import android.graphics.Color; | |||
import android.location.Location; | |||
import android.os.Bundle; | |||
import android.os.IBinder; | |||
@@ -13,12 +14,14 @@ import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.view.ViewGroup; | |||
import android.widget.ListView; | |||
import android.widget.Toast; | |||
import com.example.meinwald.BuildConfig; | |||
import com.example.meinwald.R; | |||
import com.example.meinwald.ui.area.AreaReference; | |||
import com.example.meinwald.ui.area.OwnArea; | |||
import com.example.meinwald.ui.task.OwnTask; | |||
import com.google.android.gms.common.util.Hex; | |||
import com.google.android.gms.dynamic.IObjectWrapper; | |||
import com.google.android.gms.location.FusedLocationProviderClient; | |||
import com.google.android.gms.location.LocationServices; | |||
@@ -29,11 +32,15 @@ import com.google.android.gms.maps.SupportMapFragment; | |||
import com.google.android.gms.maps.model.BitmapDescriptor; | |||
import com.google.android.gms.maps.model.CameraPosition; | |||
import com.google.android.gms.maps.model.LatLng; | |||
import com.google.android.gms.maps.model.Marker; | |||
import com.google.android.gms.maps.model.MarkerOptions; | |||
import com.google.android.gms.maps.model.Polygon; | |||
import com.google.android.gms.maps.model.PolygonOptions; | |||
import com.google.android.gms.maps.model.Polyline; | |||
import com.google.android.gms.maps.model.PolylineOptions; | |||
import com.google.android.gms.tasks.OnCompleteListener; | |||
import com.google.android.gms.tasks.Task; | |||
import com.google.maps.android.SphericalUtil; | |||
import org.json.JSONArray; | |||
import org.json.JSONException; | |||
@@ -43,6 +50,7 @@ import java.io.File; | |||
import java.io.FileReader; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Date; | |||
import java.util.List; | |||
import androidx.annotation.NonNull; | |||
@@ -152,13 +160,31 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { | |||
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity()); | |||
//wait for map is ready | |||
mapFragment.getMapAsync(new OnMapReadyCallback() { | |||
mapFragment.getMapAsync(new OnMapReadyCallback() | |||
{ | |||
@Override | |||
public void onMapReady(GoogleMap googleMap) { | |||
//save map instance locally | |||
mMap = googleMap; | |||
//set max zoom level | |||
mMap.setMaxZoomPreference(MAX_ZOOM); | |||
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); | |||
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { | |||
@Override | |||
public boolean onMarkerClick(Marker marker) { | |||
if (mMap.getCameraPosition().zoom < 17.5) | |||
{ | |||
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),(float)17.5)); | |||
} | |||
else | |||
{ | |||
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),mMap.getCameraPosition().zoom)); | |||
} | |||
return false; | |||
} | |||
}); | |||
//retrieve saved instance state | |||
mCameraPosition = parseCameraPosition(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_CAMERA_POSITION, new CameraPosition(new LatLng(45.0,11.0), (float) 1.0, (float) 0.0,(float) 0.0).toString())); | |||
@@ -198,21 +224,33 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { | |||
{ | |||
for (OwnArea area: allAreas) | |||
{ | |||
PolylineOptions options = new PolylineOptions().clickable(true); | |||
for (LatLng location: area.getLocations()) | |||
if (area.getLocations() != null && area.getLocations().size()>0) | |||
{ | |||
options.add(location); | |||
PolygonOptions options = new PolygonOptions().clickable(true); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "Position: " + location.toString()); | |||
Log.d(TAG, "Color: " + getAreaColor(area.getLastChecked())); | |||
Log.d(TAG, "Color: " + String.valueOf(getAreaColor(area.getLastChecked() & 0x00FFFFFF) | 0x60000000)); | |||
Log.d(TAG, "Area: " + SphericalUtil.computeArea(area.getLocations())); | |||
} | |||
options.strokeColor(getAreaColor(area.getLastChecked())); | |||
options.fillColor((options.getStrokeColor() & 0x00FFFFFF) | 0x60000000); | |||
for (LatLng location: area.getLocations()) | |||
{ | |||
options.add(location); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "Position: " + location.toString()); | |||
} | |||
} | |||
} | |||
Polyline polyline1 = mMap.addPolyline(options); | |||
options.add(area.getLocations().get(0)); | |||
mMap.addPolygon(options); | |||
} | |||
} | |||
} | |||
@@ -503,6 +541,55 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback { | |||
drawAreas(); | |||
} | |||
/** | |||
* Decides color of area based on the time passed since last ckeck update. | |||
* | |||
* @param time difference in milliseconds between last check and now | |||
* @return color number | |||
*/ | |||
private int getAreaColor(long time) { | |||
//set transparency related to time difference | |||
if(time > -1) | |||
{ | |||
long timeDiff = new Date().getTime() - time; | |||
//less than a week | |||
if (timeDiff < 7*24*60*60*1000L) | |||
{ | |||
return Color.parseColor("#57a639"); | |||
} | |||
//less than two weeks | |||
else if (timeDiff < 14*24*60*60*1000L) | |||
{ | |||
return Color.parseColor("#819b45"); | |||
} | |||
//less than three weeks | |||
else if (timeDiff < 21*24*60*60*1000L) | |||
{ | |||
return Color.parseColor("#d3d30c"); | |||
} | |||
//less than four weeks | |||
else if (timeDiff < 28*24*60*60*1000L) | |||
{ | |||
return Color.parseColor("#df9600"); | |||
} | |||
//less than 6 weeks | |||
else if (timeDiff < 42*24*60*60*1000L) | |||
{ | |||
return Color.parseColor("#df3d00"); | |||
} | |||
//longer than four weeks | |||
else | |||
{ | |||
return Color.parseColor("#f70000"); | |||
} | |||
} | |||
else | |||
{ | |||
return Color.parseColor("#f70000"); | |||
} | |||
} | |||
/** | |||
* Request read external storage permission, so that we can get saved images from external storage. | |||
* The result of the permission request is handled by a callback, |
@@ -1,5 +1,6 @@ | |||
package com.example.meinwald.ui.task; | |||
import android.content.Context; | |||
import android.graphics.Bitmap; | |||
import android.location.Location; | |||
import android.media.Image; | |||
@@ -11,6 +12,10 @@ import com.google.android.gms.maps.model.LatLng; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import java.io.File; | |||
import java.io.FileNotFoundException; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.util.Date; | |||
public class OwnTask | |||
@@ -129,6 +134,63 @@ public class OwnTask | |||
public void setPathImage(String pathImage) { this.pathImage = pathImage; } | |||
public String saveImageToExternalStorage(Context context){ | |||
File path = null; | |||
try { | |||
path = new File(context.getFilesDir(), "meinWald" + File.separator + "Images"); | |||
if(!path.exists()){ | |||
path.mkdirs(); | |||
} | |||
if (BuildConfig.DEBUG) { | |||
Log.d(this.getClass().getSimpleName(), "Image file path: " + path); | |||
} | |||
File outFile = new File(path, this.id + ".jpeg"); | |||
if (!outFile.exists()) | |||
{ | |||
FileOutputStream outputStream = new FileOutputStream(outFile); | |||
this.image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); | |||
outputStream.close(); | |||
} | |||
} catch (FileNotFoundException e) { | |||
Log.e(this.getClass().getSimpleName(), "Saving received message failed with", e); | |||
} catch (IOException e) { | |||
Log.e(this.getClass().getSimpleName(), "Saving received message failed with", e); | |||
} | |||
return path.toString(); | |||
} | |||
/** | |||
* Delete OwnArea object textfile from external storage. | |||
*/ | |||
public void deleteFromExternalStorage(Context context) | |||
{ | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "deleteFromExternalStorage()"); | |||
} | |||
// Find the root of the external storage. | |||
File root = android.os.Environment.getExternalStorageDirectory(); | |||
//delete file if exists | |||
File file = new File(context.getFilesDir(), "meinWald" + File.pathSeparator + "Images" + File.pathSeparator + this.getId() + ".txt"); | |||
if(!file.exists()){ | |||
file.delete(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(getClass().getSimpleName(), "Delete image file: " + file.getPath()); | |||
} | |||
} | |||
} | |||
@Override | |||
public String toString() { | |||
return "OwnTask{" + |
@@ -4,6 +4,7 @@ import android.app.AlertDialog; | |||
import android.content.Context; | |||
import android.content.DialogInterface; | |||
import android.graphics.Rect; | |||
import android.os.Build; | |||
import android.util.Log; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
@@ -14,12 +15,14 @@ import android.widget.TextView; | |||
import com.example.meinwald.BuildConfig; | |||
import com.example.meinwald.R; | |||
import com.example.meinwald.ui.area.AreaAdapter; | |||
import com.example.meinwald.ui.area.OwnArea; | |||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import androidx.annotation.RequiresApi; | |||
import androidx.appcompat.widget.AlertDialogLayout; | |||
import androidx.appcompat.widget.LinearLayoutCompat; | |||
import androidx.constraintlayout.widget.ConstraintLayout; | |||
@@ -28,6 +31,8 @@ import static java.security.AccessController.getContext; | |||
public class TaskAdapter extends BaseAdapter | |||
{ | |||
private final static String TAG = TaskAdapter.class.getSimpleName(); | |||
List<OwnTask> taskList; | |||
LayoutInflater inflater; | |||
Context context; | |||
@@ -56,6 +61,7 @@ public class TaskAdapter extends BaseAdapter | |||
final TextView title = (TextView) view.findViewById(R.id.taskInfoTitle); | |||
final TextView notice = (TextView) view.findViewById(R.id.taskInfoNotice); | |||
final ImageView icon = (ImageView) view.findViewById(R.id.taskIcon); | |||
final ImageView manageTask = (ImageView) view.findViewById(R.id.taskManageTask); | |||
context = view.getContext(); | |||
@@ -89,6 +95,147 @@ public class TaskAdapter extends BaseAdapter | |||
} | |||
}); | |||
manageTask.setOnClickListener(new View.OnClickListener() { | |||
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) | |||
@Override | |||
public void onClick(View v) | |||
{ | |||
final AlertDialog.Builder builder = new AlertDialog.Builder(v.getRootView().getContext()); | |||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management, viewGroup, false); | |||
builder.setView(viewInflated); | |||
//get elements | |||
TextView title = viewInflated.findViewById(R.id.areaManageTitle); | |||
final TextView notice = viewInflated.findViewById(R.id.areaManageNotice); | |||
TextView gps = viewInflated.findViewById(R.id.areaManageGPSPoints); | |||
ImageView image = (ImageView) viewInflated.findViewById(R.id.areaManageImage); | |||
ImageView newNotice = (ImageView) viewInflated.findViewById(R.id.areaManageNewDescription); | |||
ImageView newGPS = (ImageView) viewInflated.findViewById(R.id.areaManageNewGPS); | |||
ImageView newImage = (ImageView) viewInflated.findViewById(R.id.areaManageNewImage); | |||
ImageView deleteArea = (ImageView) viewInflated.findViewById(R.id.areaManageDeleteArea); | |||
//set current vlues | |||
title.setText(taskList.get(i).getTitle()); | |||
notice.setText(taskList.get(i).getNotice()); | |||
if (taskList.get(i).getLocation() != null) | |||
{ | |||
gps.setText(String.valueOf(taskList.get(i).getLocation())); | |||
} | |||
else | |||
{ | |||
gps.setText("Kein Standort gespeichert!"); | |||
} | |||
if (taskList.get(i).getImage() != null) | |||
{ | |||
image.setImageBitmap(taskList.get(i).getImage()); | |||
} | |||
newNotice.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) | |||
{ | |||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||
final View viewInflated = LayoutInflater.from(v.getRootView().getContext()).inflate(R.layout.area_management_notice, viewGroup, false); | |||
newbuilder.setView(viewInflated); | |||
final TextView noticeView = viewInflated.findViewById(R.id.areaManagementNoticeUserInput); | |||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
taskList.get(i).setNotice(noticeView.getText().toString()); | |||
notice.setText(taskList.get(i).getNotice()); | |||
dialog.dismiss(); | |||
} | |||
}); | |||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
newbuilder.show(); | |||
}}); | |||
deleteArea.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
final AlertDialog.Builder newbuilder = new AlertDialog.Builder(v.getRootView().getContext()); | |||
newbuilder.setTitle("Das Grundstück wirklich löschen?"); | |||
newbuilder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
taskList.get(i).deleteFromExternalStorage(context); | |||
taskList.remove(i); | |||
notifyDataSetChanged(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
for (OwnTask task: taskList) | |||
{ | |||
Log.d(TAG, "areaList item: " + task.toString()); | |||
} | |||
} | |||
dialog.dismiss(); | |||
} | |||
}); | |||
newbuilder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
newbuilder.show(); | |||
}}); | |||
builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
if (taskList.size()-1 > i && taskList.get(i) != null) | |||
{ | |||
taskList.get(i).deleteFromExternalStorage(context); | |||
taskList.get(i).saveImageToExternalStorage(context); | |||
} | |||
if (BuildConfig.DEBUG) | |||
{ | |||
for (OwnTask task: taskList) | |||
{ | |||
Log.d(TAG, "areaList item: " + task.toString()); | |||
} | |||
} | |||
dialog.dismiss(); | |||
} | |||
}); | |||
builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
builder.show(); | |||
} | |||
}); | |||
icon.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) | |||
@@ -104,8 +251,12 @@ public class TaskAdapter extends BaseAdapter | |||
final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout); | |||
final ImageView imageView = viewInflated.findViewById(R.id.taskLargeImage); | |||
//ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(taskList.get(i).getImage().getWidth(),5 * taskList.get(i).getImage().getHeight()); | |||
//imageViewLayout.setLayoutParams(layoutParams); | |||
Log.d("TaskAdapter", String.valueOf(taskList.get(i).getImage().getHeight())); | |||
//ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(taskList.get(i).getImage().getWidth(), taskList.get(i).getImage().getHeight()); | |||
//layoutParams.width = taskList.get(i).getImage().getWidth(); | |||
//layoutParams.height = taskList.get(i).getImage().getHeight(); | |||
//imageView.setLayoutParams(layoutParams); | |||
imageView.setImageBitmap(taskList.get(i).getImage()); | |||
builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() { |
@@ -6,6 +6,7 @@ import android.app.AlertDialog; | |||
import android.content.DialogInterface; | |||
import android.content.Intent; | |||
import android.content.pm.PackageManager; | |||
import android.database.DataSetObserver; | |||
import android.graphics.Bitmap; | |||
import android.graphics.BitmapFactory; | |||
import android.graphics.Color; | |||
@@ -38,6 +39,8 @@ import androidx.lifecycle.ViewModelProviders; | |||
import com.example.meinwald.BuildConfig; | |||
import com.example.meinwald.R; | |||
import com.example.meinwald.ui.area.AreaReference; | |||
import com.example.meinwald.ui.area.OwnArea; | |||
import com.google.android.gms.location.FusedLocationProviderClient; | |||
import com.google.android.gms.location.LocationServices; | |||
import com.google.android.gms.maps.CameraUpdateFactory; | |||
@@ -175,7 +178,7 @@ public class TasksFragment extends Fragment { | |||
//save and display location | |||
newTask.setLocation(mLastKnownLocation); | |||
locationText.setText("Lat: " +String.valueOf(mLastKnownLocation.getLatitude()) + " Lng: " + String.valueOf(mLastKnownLocation.getLongitude())); | |||
locationText.setText("Auf " + newTask.getLocation().getAccuracy() + " Meter genau!"); | |||
} | |||
}); | |||
@@ -226,7 +229,7 @@ public class TasksFragment extends Fragment { | |||
//save user input | |||
newTask.setTitle(String.valueOf(titleView.getText())); | |||
newTask.setNotice(String.valueOf(noticeView.getText())); | |||
newTask.setPathImage(newTask.saveImageToExternalStorage(getContext())); | |||
boolean result = allTasks.add(newTask); | |||
@@ -234,15 +237,6 @@ public class TasksFragment extends Fragment { | |||
{ | |||
Log.d(TAG, "new Task: " + newTask.toString()); | |||
Log.d(TAG, "add new task result: " + result); | |||
/** | |||
for (OwnTask task: allTasks) | |||
{ | |||
if (BuildConfig.DEBUG) { | |||
Log.d(TAG, task.toString()); | |||
} | |||
} | |||
**/ | |||
} | |||
instantiateTaskList(); | |||
@@ -336,7 +330,7 @@ public class TasksFragment extends Fragment { | |||
{ | |||
//save image to external storage and save path | |||
String path = saveReceivedImage(task.getImage(), task.getId()); | |||
String path = task.saveImageToExternalStorage(getContext()); | |||
task.setPathImage(path); | |||
if (BuildConfig.DEBUG) { | |||
@@ -357,37 +351,6 @@ public class TasksFragment extends Fragment { | |||
} | |||
} | |||
private String saveReceivedImage(Bitmap bitmap, String imageName){ | |||
File path = null; | |||
try { | |||
path = new File(getContext().getFilesDir(), "meinWald" + File.separator + "Images"); | |||
if(!path.exists()){ | |||
path.mkdirs(); | |||
} | |||
if (BuildConfig.DEBUG) { | |||
Log.d(TAG, "Image file path: " + path); | |||
} | |||
File outFile = new File(path, imageName + ".jpeg"); | |||
if (!outFile.exists()) | |||
{ | |||
FileOutputStream outputStream = new FileOutputStream(outFile); | |||
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); | |||
outputStream.close(); | |||
} | |||
} catch (FileNotFoundException e) { | |||
Log.e(TAG, "Saving received message failed with", e); | |||
} catch (IOException e) { | |||
Log.e(TAG, "Saving received message failed with", e); | |||
} | |||
return path.toString(); | |||
} | |||
/** | |||
* Reads tasks saved in preferences as jsonStrings | |||
* | |||
@@ -431,6 +394,33 @@ public class TasksFragment extends Fragment { | |||
public void instantiateTaskList() | |||
{ | |||
final TaskAdapter adapter = new TaskAdapter(getActivity().getApplicationContext(),allTasks); | |||
adapter.registerDataSetObserver(new DataSetObserver() { | |||
@Override | |||
public void onChanged() { | |||
super.onChanged(); | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "onChanged"); | |||
} | |||
if (BuildConfig.DEBUG) | |||
{ | |||
Log.d(TAG, "dataset size: " + taskList.getAdapter().getCount()); | |||
} | |||
if (taskList.getAdapter().getCount() > 0) | |||
{ | |||
allTasks = new ArrayList<>(); | |||
for (int i = 0; i < taskList.getAdapter().getCount(); i++) | |||
{ | |||
allTasks.add((OwnTask) taskList.getAdapter().getItem(i)); | |||
} | |||
} | |||
} | |||
}); | |||
taskList.setAdapter(adapter); | |||
//initialise onClickListeners | |||
@@ -574,7 +564,6 @@ public class TasksFragment extends Fragment { | |||
{ | |||
Bitmap photo = (Bitmap) data.getExtras().get("data"); | |||
newTask.setImage(photo); | |||
newTask.setPathImage(saveReceivedImage(photo,newTask.getId())); | |||
if (imageToAdd != null && photo != null) | |||
{ |
@@ -25,6 +25,7 @@ | |||
android:focusable="false" | |||
android:textColor="@android:color/primary_text_light" | |||
android:textSize="22sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
@@ -87,18 +88,56 @@ | |||
<TextView | |||
android:id="@+id/areaInfoNotice" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_height="0dp" | |||
android:layout_gravity="left" | |||
android:clickable="false" | |||
android:duplicateParentState="true" | |||
android:focusable="false" | |||
android:focusableInTouchMode="false" | |||
android:textColor="@android:color/primary_text_light" | |||
android:textSize="12sp" | |||
android:visibility="visible" | |||
app:layout_constraintEnd_toStartOf="@+id/taskIcon" | |||
app:layout_constraintBottom_toTopOf="@+id/areaInfoArea" | |||
app:layout_constraintEnd_toStartOf="@+id/areaIcon" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
android:duplicateParentState="true"/> | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<TextView | |||
android:id="@+id/areaInfoAreatv" | |||
android:layout_width="0dp" | |||
android:layout_height="20dp" | |||
android:layout_gravity="left" | |||
android:layout_marginBottom="5dp" | |||
android:clickable="false" | |||
android:duplicateParentState="true" | |||
android:focusable="false" | |||
android:focusableInTouchMode="false" | |||
android:text="Fläche:" | |||
android:textColor="@android:color/primary_text_light" | |||
android:textSize="14sp" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" /> | |||
<TextView | |||
android:id="@+id/areaInfoArea" | |||
android:layout_width="0dp" | |||
android:layout_height="0dp" | |||
android:layout_gravity="left" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginBottom="5dp" | |||
android:clickable="false" | |||
android:duplicateParentState="true" | |||
android:focusable="false" | |||
android:focusableInTouchMode="false" | |||
android:textColor="@android:color/primary_text_light" | |||
android:textSize="14sp" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toStartOf="@+id/areaIcon" | |||
app:layout_constraintStart_toEndOf="@+id/areaInfoAreatv" | |||
app:layout_constraintTop_toTopOf="@+id/areaInfoAreatv" /> | |||
</androidx.constraintlayout.widget.ConstraintLayout> | |||
@@ -1,6 +1,7 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" | |||
android:id="@+id/layout_area_root" | |||
android:layout_width="fill_parent" | |||
android:layout_height="fill_parent" | |||
@@ -11,14 +12,26 @@ | |||
android:id="@+id/areaTitle" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="5dp" | |||
android:text="Grundstück" | |||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||
android:textAppearance="?android:attr/textAppearanceLarge" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<EditText | |||
android:id="@+id/areaTitleUserInput" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:hint="Titel eingeben!"> | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:hint="Titel eingeben!" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaTitle"> | |||
<requestFocus /> | |||
@@ -28,28 +41,72 @@ | |||
android:id="@+id/areaManagementNotice" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:text="Beschreibung" | |||
android:textAppearance="?android:attr/textAppearanceLarge" /> | |||
android:textAppearance="?android:attr/textAppearanceLarge" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaTitleUserInput" /> | |||
<EditText | |||
android:id="@+id/areaManagementNoticeUserInput" | |||
android:layout_width="match_parent" | |||
android:layout_height="150dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:cursorVisible="true" | |||
android:hint="Beschreibung eingeben!" | |||
android:isScrollContainer="true"> | |||
<requestFocus /> | |||
android:isScrollContainer="true" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNotice"> | |||
</EditText> | |||
<Button | |||
android:id="@+id/areaStartTracking" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:text="Grundstücksaufnahme Starten!" /> | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:text="Grundstücksaufnahme Starten!" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNoticeUserInput" /> | |||
<Button | |||
android:id="@+id/areaStopTracking" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:text="Grundstücksaufnahme Beenden!" | |||
android:visibility="invisible"/> | |||
android:visibility="invisible" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaManagementNoticeUserInput" /> | |||
<Button | |||
android:id="@+id/areaAddGPSPoint" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:text="Grenzpunkt hinzufügen" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaStartTracking" /> | |||
</LinearLayout> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -66,7 +66,7 @@ | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:text="Bild" | |||
android:text="Zuletzt überprüft" | |||
android:textSize="18sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
@@ -85,6 +85,30 @@ | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView4" /> | |||
<TextView | |||
android:id="@+id/textView7" | |||
android:layout_width="250dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:text="Bild" | |||
android:textSize="18sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/areaManagementLastChecked" /> | |||
<TextView | |||
android:id="@+id/areaManagementLastChecked" | |||
android:layout_width="0dp" | |||
android:layout_height="30dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:textSize="12sp" | |||
app:layout_constraintEnd_toStartOf="@+id/areaManageNewDate" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView6" /> | |||
<ImageView | |||
android:id="@+id/areaManageImage" | |||
android:layout_width="match_parent" | |||
@@ -93,11 +117,12 @@ | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:src="@android:drawable/ic_menu_gallery" | |||
android:visibility="visible" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="1.0" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView6" | |||
android:src="@android:drawable/ic_menu_gallery" | |||
android:visibility="visible"/> | |||
app:layout_constraintTop_toBottomOf="@+id/textView7" /> | |||
<ImageView | |||
android:id="@+id/areaManageNewDescription" | |||
@@ -119,6 +144,16 @@ | |||
app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | |||
android:src="@android:drawable/ic_popup_sync" /> | |||
<ImageView | |||
android:id="@+id/areaManageNewDate" | |||
android:layout_width="30dp" | |||
android:layout_height="30dp" | |||
android:src="@android:drawable/ic_popup_sync" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="@+id/areaManagementLastChecked" | |||
app:layout_constraintEnd_toEndOf="@+id/areaManageGPSPoints" | |||
app:tint="#1B5E20" /> | |||
<ImageView | |||
android:id="@+id/areaManageNewImage" | |||
android:layout_width="30dp" | |||
@@ -141,5 +176,5 @@ | |||
android:visibility="visible" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
/> | |||
/> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -12,8 +12,13 @@ | |||
<ImageView | |||
android:id="@+id/taskLargeImage" | |||
android:layout_width="match_parent" | |||
android:layout_height="575dp" | |||
android:layout_width="0dp" | |||
android:layout_height="500dp" | |||
android:layout_marginStart="40dp" | |||
android:layout_marginLeft="40dp" | |||
android:layout_marginTop="60dp" | |||
android:layout_marginEnd="40dp" | |||
android:layout_marginRight="40dp" | |||
android:scaleType="fitXY" | |||
app:layout_constraintBottom_toBottomOf="parent" | |||
app:layout_constraintEnd_toEndOf="parent" |
@@ -13,23 +13,39 @@ | |||
<TextView | |||
android:id="@+id/taskInfoTitle" | |||
android:layout_width="match_parent" | |||
android:layout_height="30dp" | |||
android:layout_width="0dp" | |||
android:layout_height="32dp" | |||
android:layout_gravity="left" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:clickable="false" | |||
android:focusable="false" | |||
android:textColor="@android:color/primary_text_light" | |||
android:textSize="22sp" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintEnd_toStartOf="@+id/taskManageTask" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<ImageView | |||
android:id="@+id/taskManageTask" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginTop="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:clickable="true" | |||
android:duplicateParentState="true" | |||
android:focusable="false" | |||
android:focusableInTouchMode="false" | |||
android:src="@android:drawable/ic_menu_manage" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toTopOf="@+id/areaInfoView" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintHorizontal_bias="0.0" | |||
app:layout_constraintStart_toEndOf="@+id/areaInfoTitle" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<androidx.constraintlayout.widget.ConstraintLayout | |||
android:id="@+id/taskInfoView" | |||
android:layout_width="0dp" |
@@ -38,8 +38,6 @@ | |||
android:hint="Beschreibung eingeben!" | |||
android:isScrollContainer="true"> | |||
<requestFocus /> | |||
</EditText> | |||
<Button |
@@ -0,0 +1,144 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
xmlns:app="http://schemas.android.com/apk/res-auto"> | |||
<TextView | |||
android:id="@+id/taskManageTitle" | |||
android:layout_width="wrap_content" | |||
android:layout_height="50dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="5dp" | |||
android:text="TextView" | |||
android:textSize="36sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" /> | |||
<TextView | |||
android:id="@+id/textView2" | |||
android:layout_width="250dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="5dp" | |||
android:text="Beschreibung" | |||
android:textSize="18sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/taskManageTitle" /> | |||
<TextView | |||
android:id="@+id/taskManageNotice" | |||
android:layout_width="0dp" | |||
android:layout_height="75dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:isScrollContainer="true" | |||
android:textSize="12sp" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView2" /> | |||
<TextView | |||
android:id="@+id/textView4" | |||
android:layout_width="250dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:text="Standort" | |||
android:textSize="18sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/taskManageNotice" /> | |||
<TextView | |||
android:id="@+id/textView6" | |||
android:layout_width="250dp" | |||
android:layout_height="wrap_content" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginTop="15dp" | |||
android:text="Bild" | |||
android:textSize="18sp" | |||
android:textStyle="bold" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/taskManageGPSPoint" /> | |||
<TextView | |||
android:id="@+id/taskManageGPSPoint" | |||
android:layout_width="match_parent" | |||
android:layout_height="30dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:textSize="12sp" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView4" /> | |||
<ImageView | |||
android:id="@+id/taskManageImage" | |||
android:layout_width="match_parent" | |||
android:layout_height="200dp" | |||
android:layout_marginStart="5dp" | |||
android:layout_marginLeft="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintStart_toStartOf="parent" | |||
app:layout_constraintTop_toBottomOf="@+id/textView6" | |||
android:src="@android:drawable/ic_menu_gallery" | |||
android:visibility="visible"/> | |||
<ImageView | |||
android:id="@+id/taskManageNewDescription" | |||
android:layout_width="30dp" | |||
android:layout_height="30dp" | |||
app:tint="#1B5E20" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="@+id/taskManageNotice" | |||
app:layout_constraintEnd_toEndOf="@+id/taskManageNotice" | |||
android:src="@android:drawable/ic_popup_sync" /> | |||
<ImageView | |||
android:id="@+id/taskManageNewGPS" | |||
android:layout_width="30dp" | |||
android:layout_height="30dp" | |||
app:tint="#1B5E20" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="@+id/taskManageGPSPoint" | |||
app:layout_constraintEnd_toEndOf="@+id/taskManageGPSPoint" | |||
android:src="@android:drawable/ic_popup_sync" /> | |||
<ImageView | |||
android:id="@+id/taskManageNewImage" | |||
android:layout_width="30dp" | |||
android:layout_height="30dp" | |||
app:tint="#1B5E20" | |||
android:visibility="visible" | |||
app:layout_constraintBottom_toBottomOf="@+id/taskManageImage" | |||
app:layout_constraintEnd_toEndOf="@+id/taskManageImage" | |||
android:src="@android:drawable/ic_menu_camera" /> | |||
<ImageView | |||
android:id="@+id/taskManageDeleteTask" | |||
android:layout_width="50dp" | |||
android:layout_height="50dp" | |||
android:layout_marginTop="5dp" | |||
android:layout_marginEnd="5dp" | |||
android:layout_marginRight="5dp" | |||
android:src="@android:drawable/ic_menu_delete" | |||
app:tint="#B71C1C" | |||
android:visibility="visible" | |||
app:layout_constraintEnd_toEndOf="parent" | |||
app:layout_constraintTop_toTopOf="parent" | |||
/> | |||
</androidx.constraintlayout.widget.ConstraintLayout> |
@@ -1,7 +1,12 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<resources> | |||
<color name="colorPrimary">#1B5E20</color> | |||
<color name="colorPrimaryDark">#3700B3</color> | |||
<color name="colorPrimaryDark">#1B5E20</color> | |||
<color name="colorAccent">#03DAC5</color> | |||
<color name="selectionBackground">#c0edc3</color> | |||
<color name="colorArea1">#57a639</color> | |||
<color name="colorArea2">#819b45</color> | |||
<color name="colorArea3">#d3d30c</color> | |||
<color name="colorArea4">#df9600</color> | |||
<color name="colorArea5">#df3d00</color> | |||
</resources> |