diff --git a/Code Android/meinWald/app/build.gradle b/Code Android/meinWald/app/build.gradle index b395896..41be745 100644 --- a/Code Android/meinWald/app/build.gradle +++ b/Code Android/meinWald/app/build.gradle @@ -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' } \ No newline at end of file diff --git a/Code Android/meinWald/app/src/main/AndroidManifest.xml b/Code Android/meinWald/app/src/main/AndroidManifest.xml index 0fdc19c..0a0a2f7 100644 --- a/Code Android/meinWald/app/src/main/AndroidManifest.xml +++ b/Code Android/meinWald/app/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ package="com.example.meinwald"> diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/MyApplication.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/MyApplication.java deleted file mode 100644 index ee89c96..0000000 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/MyApplication.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaAdapter.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaAdapter.java index 6129de5..99d1362 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaAdapter.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaAdapter.java @@ -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 areaList; LayoutInflater inflater; Context context; + boolean deleted = false; + Integer deletedPosition = null; public AreaAdapter(Context applicationContext, List 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 diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaFragment.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaFragment.java index 7156e30..5bec141 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaFragment.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaFragment.java @@ -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 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 locationResult = mFusedLocationProviderClient.getLastLocation(); + locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task 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() { diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/LocationService.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/LocationService.java index 483151b..8132b7c 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/LocationService.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/LocationService.java @@ -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 diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/OwnArea.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/OwnArea.java index 0977ce4..dbb45db 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/OwnArea.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/OwnArea.java @@ -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 locations; private Bitmap image; private String pathImage; - private String pathLocations; + private String pathFile; private String id; + private List 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 List getCheckHistory() { + return checkHistory; + } + + public void setCheckHistory(List 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; i2) + { + 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; + } + } } diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/map/MapsFragment.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/map/MapsFragment.java index c5e1d0b..b2d754f 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/map/MapsFragment.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/map/MapsFragment.java @@ -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()); + } + } + + options.add(area.getLocations().get(0)); + + mMap.addPolygon(options); } - - Polyline polyline1 = mMap.addPolyline(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, diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/OwnTask.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/OwnTask.java index a4b3c93..bf62f63 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/OwnTask.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/OwnTask.java @@ -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{" + diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TaskAdapter.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TaskAdapter.java index 3564ec1..2f52f2b 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TaskAdapter.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TaskAdapter.java @@ -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 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() { diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TasksFragment.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TasksFragment.java index b29405a..62424bf 100644 --- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TasksFragment.java +++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/task/TasksFragment.java @@ -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) { diff --git a/Code Android/meinWald/app/src/main/res/layout/area_element.xml b/Code Android/meinWald/app/src/main/res/layout/area_element.xml index be34a05..4dbd2bb 100644 --- a/Code Android/meinWald/app/src/main/res/layout/area_element.xml +++ b/Code Android/meinWald/app/src/main/res/layout/area_element.xml @@ -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 @@ + app:layout_constraintTop_toTopOf="parent" /> + + + + diff --git a/Code Android/meinWald/app/src/main/res/layout/area_input.xml b/Code Android/meinWald/app/src/main/res/layout/area_input.xml index e8df1b5..b8ce660 100644 --- a/Code Android/meinWald/app/src/main/res/layout/area_input.xml +++ b/Code Android/meinWald/app/src/main/res/layout/area_input.xml @@ -1,6 +1,7 @@ - + android:textAppearance="?android:attr/textAppearanceLarge" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + 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"> @@ -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" /> - + android:isScrollContainer="true" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/areaManagementNotice"> +