diff --git a/Code Android/meinWald/app/src/main/AndroidManifest.xml b/Code Android/meinWald/app/src/main/AndroidManifest.xml
index 38ae097..0fdc19c 100644
--- a/Code Android/meinWald/app/src/main/AndroidManifest.xml
+++ b/Code Android/meinWald/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.example.meinwald">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/MainActivity.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/MainActivity.java
index cd02c23..50aea1a 100644
--- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/MainActivity.java
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/MainActivity.java
@@ -1,5 +1,6 @@
package com.example.meinwald;
+import android.content.Context;
import android.os.Bundle;
import com.google.android.material.bottomnavigation.BottomNavigationView;
@@ -12,9 +13,14 @@ import androidx.navigation.ui.NavigationUI;
public class MainActivity extends AppCompatActivity {
+ private static Context context;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ context = getApplicationContext();
+
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
@@ -27,4 +33,8 @@ public class MainActivity extends AppCompatActivity {
NavigationUI.setupWithNavController(navView, navController);
}
+ public static Context getAppContext() {
+ return context;
+ }
+
}
\ No newline at end of file
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
new file mode 100644
index 0000000..ee89c96
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/MyApplication.java
@@ -0,0 +1,18 @@
+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
new file mode 100644
index 0000000..c68c8c3
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaAdapter.java
@@ -0,0 +1,143 @@
+package com.example.meinwald.ui.area;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+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.List;
+
+import androidx.appcompat.widget.AlertDialogLayout;
+import androidx.appcompat.widget.LinearLayoutCompat;
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import static java.security.AccessController.getContext;
+
+public class AreaAdapter extends BaseAdapter
+{
+ List areaList;
+ LayoutInflater inflater;
+ Context context;
+
+ public AreaAdapter(Context applicationContext, List areaList)
+ {
+ this.areaList = new ArrayList<>();
+ this.areaList = areaList;
+ this.context = applicationContext;
+
+ inflater = LayoutInflater.from(applicationContext);
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d("AreaAdapter","size: " + areaList.size());
+ }
+ }
+
+ @Override
+ public View getView(final int i, View view, final ViewGroup viewGroup) {
+
+ view = inflater.inflate(R.layout.area_element, null);
+ final ConstraintLayout elementView = view.findViewById(R.id.areaInfoView);
+ 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);
+ 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());
+ }
+
+ title.setText(areaList.get(i).getTitle());
+ notice.setText(areaList.get(i).getNotice());
+ icon.setImageBitmap(areaList.get(i).getImage());
+
+ title.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v)
+ {
+
+
+ }
+ });
+
+ notice.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v)
+ {
+
+
+ }
+ });
+
+ icon.setOnClickListener(new View.OnClickListener() {
+ @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.image_large, viewGroup, false);
+
+ builder.setView(viewInflated);
+
+ final ConstraintLayout imageViewLayout = viewInflated.findViewById(R.id.taskLargeImageLayout);
+ final ImageView imageView = viewInflated.findViewById(R.id.taskLargeImage);
+
+ imageView.setImageBitmap(areaList.get(i).getImage());
+
+ builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ builder.show();
+ }
+ });
+
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public int getCount() {
+ return areaList.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return areaList.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+}
+
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 e97e8ae..52967ae 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
@@ -1,39 +1,570 @@
package com.example.meinwald.ui.area;
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.location.Location;
import android.os.Bundle;
+import android.os.IBinder;
+import android.os.PowerManager;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.ListView;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
-import androidx.lifecycle.ViewModelProviders;
+import com.example.meinwald.BuildConfig;
import com.example.meinwald.R;
+import com.example.meinwald.ui.task.TaskAdapter;
+import com.example.meinwald.ui.task.TasksFragment;
+import com.google.android.gms.location.FusedLocationProviderClient;
+import com.google.android.gms.location.LocationServices;
+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;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONStringer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.content.Context.POWER_SERVICE;
+
public class AreaFragment extends Fragment {
- private DashboardViewModel dashboardViewModel;
+ private static final String TAG = TasksFragment.class.getSimpleName();
+
+ /**
+ * ______________________________________________________________________________________________
+ * AREA
+ */
+ private OwnArea newArea = new OwnArea();
+ private List allAreas;
+ private ListView areaList;
+ private static final String KEY_AREA_REFERENCES = "areaReferences";
+ private List areaReferences;
+
+ /**
+ * ______________________________________________________________________________________________
+ * LOCATION
+ */
+ private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
+ /**
+ * The entry point to the Fused Location Provider.
+ */
+ private FusedLocationProviderClient mFusedLocationProviderClient;
+ private boolean mLocationPermissionGranted;
+ /**
+ * The geographical locations which were received from location tracking.
+ */
+ private List newPositions;
+
+ /**
+ * ______________________________________________________________________________________________
+ * CAMERA
+ */
+ private static final int MY_CAMERA_PERMISSION_CODE = 100;
+ private boolean mCameraPermissionGranted;
+ private static final int CAMERA_REQUEST = 1888;
+
+ /**
+ * ______________________________________________________________________________________________
+ * STORAGE
+ */
+ private static final int READ_EXTERNAL_STORAGE_CODE = 200;
+ private static final int WRITE_EXTERNAL_STORAGE_CODE = 201;
+ private boolean mReadStorageGranted;
+ private boolean mWriteStorageGranted;
+
+ PowerManager.WakeLock wakeLock;
+ LocationService gps;
+
+
+ @SuppressLint("InvalidWakeLockTag")
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- public View onCreateView(@NonNull LayoutInflater inflater,
- ViewGroup container, Bundle savedInstanceState) {
- dashboardViewModel =
- ViewModelProviders.of(this).get(DashboardViewModel.class);
View root = inflater.inflate(R.layout.fragment_areas, container, false);
- final TextView textView = root.findViewById(R.id.text_areas);
- dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer() {
- @Override
- public void onChanged(@Nullable String s) {
- textView.setText(s);
- }
- });
- FloatingActionButton fab = root.findViewById(R.id.fab_areas);
+ //construct a FusedLocationProviderClient.
+ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
+
+ //get permissions
+ getLocationPermission();
+ getReadStoragePermission();
+
+ //instantiate area lists
+ areaList = (ListView) root.findViewById(R.id.areaListView);
+ allAreas = new ArrayList<>();
+ areaReferences = new ArrayList<>();
+
+ PowerManager powerManager = (PowerManager) getContext().getSystemService(POWER_SERVICE);
+ wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");
+ gps = new LocationService(getContext());
+
+ //instantiate add button
+ final FloatingActionButton fab = root.findViewById(R.id.fab_areas);
+
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //permissions
+ getLocationPermission();
+ getWriteStoragePPermission();
+
+ //get saved areas
+ areaReferences = readAreaReferencesFromPreferences();
+ allAreas = loadAreasFromPreferences();
+ instantiateAreasList();
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+
+ newArea = new OwnArea();
+
+ 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);
+
+
+ startTracking.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //start tracking
+ startLocationTracking();
+
+ startTracking.setVisibility(View.INVISIBLE);
+ stopTracking.setVisibility(View.VISIBLE);
+ }
+ });
+
+ stopTracking.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ //stop tracking
+ newPositions = gps.getPositions();
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "Received locations: " + newPositions.size());
+ }
+
+ newArea.setLocations(newPositions);
+ wakeLock.release();
+
+ startTracking.setVisibility(View.VISIBLE);
+ stopTracking.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ final TextView titleView = viewInflated.findViewById(R.id.areaTitleUserInput);
+ final TextView noticeView = viewInflated.findViewById(R.id.areaNoticeUserInput);
+
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "new title: " + titleView.getText());
+ }
+
+ if (titleView.getText().length()>0)
+ {
+ //save user input
+ newArea.setTitle(String.valueOf(titleView.getText()));
+ newArea.setNotice(String.valueOf(noticeView.getText()));
+
+ boolean result = allAreas.add(newArea);
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "new Task: " + newArea.toString());
+ Log.d(TAG, "add new task result: " + result);
+ }
+
+ //stop tracking
+ //wakeLock.release();
+
+ //save new area
+ allAreas.add(newArea);
+ writeAreaToExternalStorage(newArea);
+
+ //actuate list
+ instantiateAreasList();
+
+ dialog.dismiss();
+
+ //confirm added task
+ Toast toast = Toast.makeText(getActivity(), "Grundstück hinzugefügt!", Toast.LENGTH_SHORT);
+ TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
+ if( v != null)
+ {
+ //text align center
+ v.setGravity(Gravity.CENTER);
+ }
+ toast.show();
+ }
+ else
+ {
+ //title needed
+ Toast toast = Toast.makeText(getActivity(), "Grundstückstitel fehlt!", Toast.LENGTH_SHORT);
+ TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
+ if( v != null)
+ {
+ //text align center
+ v.setGravity(Gravity.CENTER);
+ }
+ toast.show();
+ }
+ }
+ });
+
+ builder.setNegativeButton("Abbrechen", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ builder.show();
+ }});
return root;
}
+
+ /**
+ * Get all stored areas and save them temporary.
+ */
+ public void instantiateAreasList()
+ {
+ final AreaAdapter adapter = new AreaAdapter(getActivity().getApplicationContext(), allAreas);
+ areaList.setAdapter(adapter);
+
+ //initialise onClickListeners
+ areaList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
+
+ //for (int j = 0; j < adapterView.getChildCount(); j++)
+ //adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
+
+ // change the background color of the selected element
+ //view.setBackgroundColor(Color.LTGRAY);
+ //adapterView.setSelection(i);
+ }});
+ }
+
+
+ @Override
+ public void onPause() {
+
+ //save area references to shared preferences
+ emptyPreferencesAndSaveEpiColorsToPreferences();
+
+ super.onPause();
+ }
+
+ /**
+ * Get OwnAreas from a JSONString.
+ * @return
+ */
+ private List loadAreasFromPreferences()
+ {
+ List areas = new ArrayList<>();
+
+ for (AreaReference reference: areaReferences)
+ {
+ String jsonString = readAreaFromExternalStorage(reference.getPath());
+
+ areas.add(new OwnArea(jsonString));
+ }
+
+ return areas;
+ }
+
+ /**
+ * Save OwnArea object in textfile on external storage.
+ *
+ * @param newArea OwnArea object to write to file.
+ * @return
+ */
+ private String writeAreaToExternalStorage(OwnArea newArea){
+
+ // Find the root of the external storage.
+ File root = android.os.Environment.getExternalStorageDirectory();
+
+ //create file if it does not exist
+ File path = new File (root.getAbsolutePath() + "meinWald" + File.pathSeparator + "areas");
+ if(!path.exists()){
+ path.mkdirs();
+ }
+ 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) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return file.getPath();
+ }
+
+ /**
+ * Read OwnArea from file in external storage and return as a string.
+ *
+ * @param path File path where the OwnArea is saved.
+ * @return
+ */
+ private String readAreaFromExternalStorage(String path)
+ {
+ //Get the text file
+ File file = new File(path);
+
+ //Read text from file
+ StringBuilder text = new StringBuilder();
+
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(file));
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ text.append(line);
+ }
+ br.close();
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return text.toString();
+}
+
+ /**
+ * Converts an OwnArea object into a JSONString object.
+ *
+ * @param area Area to convert into JSONString
+ * @return
+ */
+
+ public String areaToString(OwnArea area)
+ {
+ JSONObject areaObject = newArea.toJSONObject();
+
+ return areaObject.toString();
+ }
+
+ /**
+ * Reads areaReferences saved in preferences as jsonStrings
+ *
+ * @return list of epiColorDtos
+ */
+ private List readAreaReferencesFromPreferences() {
+ List areas = new ArrayList<>();
+
+ try {
+ String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error");
+ if(!"error".equalsIgnoreCase(jsonString)) {
+ JSONArray jsonObjects = new JSONArray(jsonString);
+ for (int i = 0; i 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED)
+ {
+ mLocationPermissionGranted = true;
+ }
+ }
+ case MY_CAMERA_PERMISSION_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mCameraPermissionGranted = true;
+ }
+ }
+ case READ_EXTERNAL_STORAGE_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ }
+ }
+ case WRITE_EXTERNAL_STORAGE_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mWriteStorageGranted = true;
+ }
+ }
+ }
+ }
+
+ public void getLocation(){
+
+ wakeLock.acquire();
+
+ gps = new LocationService(getContext());
+
+ }
+
+ public void startLocationTracking(){
+
+ final Runnable runnable= new Runnable() {
+ public void run() {
+ // do stuff here
+ getLocation();
+ }
+ };
+ runnable.run();
+ }
+
+ /**
+ * Request location permission, so that we can get the location of the device.
+ * The result of the permission request is handled by a callback,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getLocationPermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ android.Manifest.permission.ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED) {
+ mLocationPermissionGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
+ PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
+ }
+ }
+
+ /**
+ * 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,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getReadStoragePermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.READ_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
+ READ_EXTERNAL_STORAGE_CODE);
+ }
+ }
+
+ /**
+ * 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,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getWriteStoragePPermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED) {
+ mWriteStorageGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ WRITE_EXTERNAL_STORAGE_CODE);
+ }
+ }
}
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaReference.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaReference.java
new file mode 100644
index 0000000..0f3fdbd
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/AreaReference.java
@@ -0,0 +1,73 @@
+package com.example.meinwald.ui.area;
+
+import android.util.Log;
+
+import com.example.meinwald.BuildConfig;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class AreaReference
+{
+ private String id;
+ private String path;
+
+ public AreaReference(String id, String path)
+ {
+ this.id = id;
+ this.path = path;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ /**
+ * Creates EpiColorDto from JSON-Representation
+ *
+ * @param jsonRepresentation epiColorDto values as jsonObject
+ */
+ public AreaReference(JSONObject jsonRepresentation) {
+ try {
+ this.id = jsonRepresentation.getString("id");
+ this.path = jsonRepresentation.getString("path");
+ } 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()));
+ }
+ }
+ }
+
+ /**
+ * Returns AreaReference as JSONObject.
+ *
+ * @return the mapped object or null, if parsing fails
+ */
+ public JSONObject toJSONObject() {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("id",this.id);
+ object.put("path",this.path);
+ 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()));
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "AreaReference{" +
+ "id='" + id + '\'' +
+ ", path='" + path + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/DashboardViewModel.java b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/DashboardViewModel.java
deleted file mode 100644
index 53536ba..0000000
--- a/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/DashboardViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.example.meinwald.ui.area;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class DashboardViewModel extends ViewModel {
-
- private MutableLiveData mText;
-
- public DashboardViewModel() {
- mText = new MutableLiveData<>();
- mText.setValue("This is dashboard fragment");
- }
-
- public LiveData getText() {
- return mText;
- }
-}
\ No newline at end of file
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
new file mode 100644
index 0000000..483151b
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/LocationService.java
@@ -0,0 +1,290 @@
+package com.example.meinwald.ui.area;
+
+
+import android.Manifest;
+import android.app.AlertDialog;
+import android.app.Service;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.provider.Settings;
+import android.util.Log;
+
+import com.example.meinwald.BuildConfig;
+import com.google.android.gms.maps.model.LatLng;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+//import static com.name.name.MapsActivity.NOTIFICATION_ID;
+
+public class LocationService extends Service implements LocationListener {
+
+ private static final String TAG = "LocationService";
+
+ private final Context mContext;
+
+ // flag for GPS status
+ boolean isGPSEnabled = false;
+
+ // flag for network status
+ boolean isNetworkEnabled = false;
+
+ // flag for GPS status
+ boolean canGetLocation = false;
+ private boolean mLocationPermissionGranted;
+
+ Location location; // location
+ double latitude; // latitude
+ double longitude; // longitude
+
+ private List positions;
+
+ // The minimum distance to change Updates in meters
+ 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
+
+ // Declaring a Location Manager
+ protected LocationManager mLocationManager;
+
+ public LocationService(Context context) {
+
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "LocationService(Context context)");
+ }
+
+ this.mContext = context;
+ this.positions = new ArrayList<>();
+ this.mLocationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
+
+ getLocationPermission();
+
+ try {
+ // getting GPS status
+ isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
+
+ if (!isGPSEnabled && !isNetworkEnabled) {
+ // no network provider is enabled
+
+ Log.d(TAG,"No permission to get location from any provider!");
+
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+
+
+ }
+
+ }
+ else
+ {
+ Log.d(TAG,"Permission to get location from any provider!");
+
+ this.canGetLocation = true;
+ // First get location from Network Provider
+ if (isNetworkEnabled) {
+ if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+
+ Log.d(TAG,"No permission to get location from network provider!");
+ }
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "getLocation() requestLocationUpdates() from GPS");
+ }
+
+ mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ if (mLocationManager != null) {
+ location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+
+ if (location != null) {
+ positions.add(new LatLng(location.getLatitude(), location.getLongitude()));
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "getLocation() new location added");
+ }
+ }
+ }
+ }
+
+ // if GPS Enabled get lat/long using GPS Services
+ if (isGPSEnabled && mLocationPermissionGranted) {
+ if (location == null) {
+ if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+
+ Log.d(TAG,"No permission to get location from gps provider!");
+ }
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "getLocation() requestLocationUpdates() from GPS");
+ }
+
+ mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
+
+ if (mLocationManager != null) {
+ location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (location != null) {
+ positions.add(new LatLng(location.getLatitude(), location.getLongitude()));
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "getLocation() new location added");
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public void getLocation() {
+
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "getLocation()");
+ }
+
+ }
+
+ /**
+ * Stop using GPS listener
+ * Calling this function will stop using GPS in your app
+ * */
+ public void stopUsingGPS(){
+ if(mLocationManager != null){
+ mLocationManager.removeUpdates(LocationService.this);
+ }
+ }
+
+ /**
+ * Function to get latitude
+ * */
+ public double getLatitude(){
+ if(location != null){
+ latitude = location.getLatitude();
+ }
+
+ // return latitude
+ return latitude;
+ }
+
+ public List getPositions()
+ {
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "getPositions() count: " + this.positions.size());
+ }
+
+ return this.positions;
+ }
+
+ /**
+ * Function to get longitude
+ * */
+ public double getLongitude(){
+ if(location != null){
+ longitude = location.getLongitude();
+ }
+
+ // return longitude
+ return longitude;
+ }
+
+ /**
+ * Function to check GPS/wifi enabled
+ * @return boolean
+ * */
+ public boolean canGetLocation() {
+ return this.canGetLocation;
+ }
+
+ /**
+ * Function to show settings alert dialog
+ * On pressing Settings button will lauch Settings Options
+ * */
+ public void showSettingsAlert(){
+ AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
+
+ // Setting Dialog Title
+ alertDialog.setTitle("GPS is settings");
+
+ // Setting Dialog Message
+ alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
+
+ // On pressing Settings button
+ alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,int which) {
+ Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+ mContext.startActivity(intent);
+ }
+ });
+
+ // on pressing cancel button
+ alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ // Showing Alert Message
+ alertDialog.show();
+ }
+
+ /**
+ * Request location permission, so that we can get the location of the device.
+ * The result of the permission request is handled by a callback,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getLocationPermission() {
+ if (ContextCompat.checkSelfPermission(mContext,
+ android.Manifest.permission.ACCESS_FINE_LOCATION)
+ == PackageManager.PERMISSION_GRANTED) {
+ mLocationPermissionGranted = true;
+ }
+ else
+ {
+ mLocationPermissionGranted = false;
+ }
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "onLocationChanged(), new location: " + location.toString());
+ }
+
+ positions.add(new LatLng(location.getLatitude(), getLongitude()));
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..f40bd2a
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/java/com/example/meinwald/ui/area/OwnArea.java
@@ -0,0 +1,170 @@
+package com.example.meinwald.ui.area;
+
+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 org.json.JSONException;
+import org.json.JSONObject;
+
+import java.sql.Time;
+import java.util.Date;
+import java.util.List;
+
+public class OwnArea {
+
+ private String title;
+ private String notice;
+ private List locations;
+ private Bitmap image;
+ private String pathImage;
+ private String pathLocations;
+ private String id;
+ private Date time;
+
+ public void setImage(Bitmap image) {
+ this.image = image;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ this.id = generateAreaID(title);
+ }
+
+ public void setNotice(String notice) {
+ this.notice = notice;
+ }
+
+ public void setLocations(List locations) {
+ this.locations = locations;
+ }
+
+ public void setPathImage(String pathImage) {
+ this.pathImage = pathImage;
+ }
+
+ public void setPathLocations(String pathLocations) {
+ this.pathLocations = pathLocations;
+ }
+
+ public String getNotice() {
+ return notice;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Bitmap getImage() {
+ return image;
+ }
+
+ public List getLocations() {
+ return locations;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getPathImage() {
+ return pathImage;
+ }
+
+ public String getPathLocations() {
+ return pathLocations;
+ }
+
+ public OwnArea()
+ {
+
+ }
+
+ public OwnArea(String jsonString){
+ try {
+ JSONObject areaObject = new JSONObject(jsonString);
+ this.title = areaObject.getString("title");
+ this.notice = areaObject.getString("description");
+ this.id = areaObject.getString("id");
+ this.time = new Date(areaObject.getString("time"));
+
+ } catch (JSONException e) {
+ if (BuildConfig.DEBUG) {
+ Log.e(this.getClass().getSimpleName(), "earthquakeJSON " + jsonString);
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private String generateAreaID(String title)
+ {
+ String id = title.replaceAll(" ", "_") + "_" + new Date().getTime();
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(getClass().getSimpleName(), "new ID: " + id);
+ }
+ return id;
+ }
+
+
+ /**
+ * Returns OwnArea as JSONObject.
+ *
+ * @return the mapped object or null, if parsing fails
+ */
+ public JSONObject toJSONObject() {
+ JSONObject object = new JSONObject();
+ try {
+ object.put("title",this.title);
+ object.put("description",this.notice);
+ object.put("id",this.id);
+
+ if (this.time != null)
+ {
+ object.put("time", this.time);
+ }
+ else
+ {
+ object.put("time", new Date().getTime());
+ }
+
+
+ JSONObject locations = new JSONObject();
+ Long count = Long.valueOf(0);
+
+ //convert all locations
+ for (LatLng location: this.locations)
+ {
+ JSONObject locationObject = new JSONObject();
+ locationObject.put("Lat", location.latitude);
+ locationObject.put("Lng", location.longitude);
+ locations.put("location"+count, locationObject.toString());
+ }
+ object.put("locations", locations.toString());
+
+ 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()));
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "OwnArea{" +
+ "title='" + title + '\'' +
+ ", notice='" + notice + '\'' +
+ ", pathImage='" + pathImage + '\'' +
+ ", pathLocations='" + pathLocations + '\'' +
+ ", id='" + id + '\'' +
+ '}';
+ }
+}
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 7547331..6fb5c6c 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
@@ -1,27 +1,43 @@
package com.example.meinwald.ui.main.map;
+import android.Manifest;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.location.Location;
import android.os.Bundle;
+import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ListView;
import com.example.meinwald.BuildConfig;
import com.example.meinwald.R;
+import com.example.meinwald.ui.task.OwnTask;
+import com.google.android.gms.dynamic.IObjectWrapper;
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.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
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.MarkerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
+import org.json.JSONArray;
+import org.json.JSONException;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
@@ -62,6 +78,22 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback {
*/
private Location mLastKnownLocation;
+ /**
+ * ______________________________________________________________________________________________
+ * TASKS
+ */
+ private List allTasks;
+ private static final String KEY_ALL_TASKS = "allTasks";
+
+ /**
+ * ______________________________________________________________________________________________
+ * STORAGEE
+ */
+ private static final int READ_EXTERNAL_STORAGE_CODE = 200;
+ private static final int WRITE_EXTERNAL_STORAGE_CODE = 201;
+ private boolean mReadStorageGranted;
+ private boolean mWriteStorageGranted;
+
/**
* Is called when the MapsFragment view is created. Initializes all service connections, the location client and map itself.
* @param inflater Calling LayoutInflater
@@ -74,6 +106,12 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback {
//get view to inflate
View root = inflater.inflate(fragment_map, container, false);
+ //get storage permission
+ getReadStoragePermission();
+
+ //get tasks
+ allTasks = readTasksFromPreferences();
+
//display map fragment
SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
@@ -187,6 +225,13 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback {
mLocationPermissionGranted = true;
}
}
+ case READ_EXTERNAL_STORAGE_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ }
+ }
}
}
@@ -274,6 +319,72 @@ public class MapsFragment extends Fragment implements OnMapReadyCallback {
e.printStackTrace();
}
}
+
+ for (OwnTask task: allTasks)
+ {
+ MarkerOptions marker = new MarkerOptions();
+
+ //set options
+ marker.position(new LatLng(task.getLocation().getLatitude(), task.getLocation().getLongitude()));
+ marker.title(task.getTitle());
+
+ mMap.addMarker(marker);
+ }
+ }
+
+ /**
+ * 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,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getReadStoragePermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.READ_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
+ READ_EXTERNAL_STORAGE_CODE);
+ }
+ }
+
+ /**
+ * Reads tasks saved in preferences as jsonStrings
+ *
+ * @return list of OwnTask
+ */
+ private List readTasksFromPreferences() {
+ List tasks = new ArrayList<>();
+
+ try {
+ String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_ALL_TASKS, "error");
+ if(!"error".equalsIgnoreCase(jsonString)) {
+ JSONArray jsonObjects = new JSONArray(jsonString);
+
+ for (int i = 0; i taskList;
+ LayoutInflater inflater;
+ Context context;
+
+ public TaskAdapter(Context applicationContext, List taskList)
+ {
+ this.taskList = new ArrayList<>();
+ this.taskList = taskList;
+ this.context = applicationContext;
+
+ inflater = LayoutInflater.from(applicationContext);
+
+ if (BuildConfig.DEBUG)
+ {
+ //Log.d("TaskAdapter",taskList.get(0).toString());
+ Log.d("TaskAdapter","size: " + taskList.size());
+ }
+ }
+
+ @Override
+ public View getView(final int i, View view, final ViewGroup viewGroup) {
+
+ view = inflater.inflate(R.layout.task_element, null);
+ final ConstraintLayout elementView = view.findViewById(R.id.taskInfoView);
+ final ConstraintLayout infovView = view.findViewById(R.id.taskInfoView);
+ 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);
+ context = view.getContext();
+
+
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d("TaskAdapter",taskList.get(i).toString());
+ Log.d("TaskAdapter",taskList.get(i).getTitle());
+ Log.d("TaskAdapter",taskList.get(i).getNotice());
+ }
+
+ title.setText(taskList.get(i).getTitle());
+ notice.setText(taskList.get(i).getNotice());
+ icon.setImageBitmap(taskList.get(i).getImage());
+
+ title.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v)
+ {
+
+
+ }
+ });
+
+ notice.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v)
+ {
+
+
+ }
+ });
+
+ icon.setOnClickListener(new View.OnClickListener() {
+ @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.image_large, viewGroup, false);
+
+ //viewInflated.setLayoutParams(new AlertDialogLayout.LayoutParams(taskList.get(i).getImage().getWidth(),5 * taskList.get(i).getImage().getHeight()));
+
+ builder.setView(viewInflated);
+
+ 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);
+ imageView.setImageBitmap(taskList.get(i).getImage());
+
+ builder.setNegativeButton("Zurück", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ builder.show();
+ }
+ });
+
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ // TODO Auto-generated method stub
+ return true;
+ }
+ });
+
+ return view;
+ }
+
+ @Override
+ public int getCount() {
+ return taskList.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return taskList.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+}
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 ee63c60..18f52ff 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
@@ -1,23 +1,35 @@
package com.example.meinwald.ui.task;
+import android.Manifest;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
+import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
import android.location.Location;
import android.media.Image;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AdapterView;
import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
@@ -34,19 +46,32 @@ import com.google.android.gms.tasks.Task;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
+import org.json.JSONArray;
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.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
public class TasksFragment extends Fragment {
private static final String TAG = TasksFragment.class.getSimpleName();
+ private View root;
+ private LayoutInflater layoutInflater;
+ private ImageView imageToAdd;
/**
* ______________________________________________________________________________________________
* LOCATION
*/
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
- private static final String KEY_LOCATION = "location";
/**
* The entry point to the Fused Location Provider.
*/
@@ -58,85 +83,51 @@ public class TasksFragment extends Fragment {
*/
private Location mLastKnownLocation;
- private NotificationsViewModel notificationsViewModel;
+ /**
+ * ______________________________________________________________________________________________
+ * TASKS
+ */
+ private OwnTask newTask = new OwnTask();
+ private List allTasks;
+ private ListView taskList;
+ private static final String KEY_ALL_TASKS = "allTasks";
- public class OwnTask
- {
- private String title;
- private String notice;
- private Location location;
- private Image image;
+ /**
+ * ______________________________________________________________________________________________
+ * CAMERA
+ */
+ private static final int MY_CAMERA_PERMISSION_CODE = 100;
+ private boolean mCameraPermissionGranted;
+ private static final int CAMERA_REQUEST = 1888;
- public OwnTask()
- {
- this.title = null;
- this.notice = null;
- this.location = null;
- this.image = null;
- }
-
- public OwnTask(String title, String notice, Location location, Image image)
- {
- this.title = title;
- this.notice = notice;
- this.location = location;
- this.image = image;
- }
-
- public String getTitle() {
- return title;
- }
-
- public String getNotice() {
- return notice;
- }
-
- public Location getLocation() {
- return location;
- }
-
- public Image getImage() {
- return image;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public void setNotice(String notice) {
- this.notice = notice;
- }
-
- public void setLocation(Location location) {
- this.location = location;
- }
-
- public void setImage(Image image) {
- this.image = image;
- }
-
- @Override
- public String toString() {
- return "OwnTask{" +
- "title='" + title + '\'' +
- ", notice='" + notice + '\'' +
- ", location=" + location +
- '}';
- }
- }
-
- OwnTask newTask = new OwnTask();
+ /**
+ * ______________________________________________________________________________________________
+ * STORAGE
+ */
+ private static final int READ_EXTERNAL_STORAGE_CODE = 200;
+ private static final int WRITE_EXTERNAL_STORAGE_CODE = 201;
+ private boolean mReadStorageGranted;
+ private boolean mWriteStorageGranted;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View root = inflater.inflate(R.layout.fragment_tasks, container, false);
+ layoutInflater = inflater;
+ root = inflater.inflate(R.layout.fragment_tasks, container, false);
- //instance add button
+ taskList = (ListView) root.findViewById(R.id.taskListView);
+
+ //instantiate add button
FloatingActionButton fab = root.findViewById(R.id.fab_tasks);
+ allTasks = readTasksFromPreferences();
+ instantiateTaskList();
+
//construct a FusedLocationProviderClient.
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
+ //get read storage permission
+ getReadStoragePermission();
+
//get location permission
getLocationPermission();
@@ -145,11 +136,18 @@ public class TasksFragment extends Fragment {
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+ newTask = new OwnTask();
+
+ //check permissions
getDeviceLocation();
+ getCameraPPermission();
+ getWriteStoragePPermission();
final View viewInflated = LayoutInflater.from(getContext()).inflate(R.layout.task_input, (ViewGroup) getView(), false);
builder.setView(viewInflated);
+ imageToAdd = viewInflated.findViewById(R.id.taskImage);
+
//set location
final Button buttonSetLocation = viewInflated.findViewById(R.id.taskSetLocation);
final TextView locationText = viewInflated.findViewById(R.id.taskLocation);
@@ -157,6 +155,11 @@ public class TasksFragment extends Fragment {
buttonSetLocation.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "add Location!");
+ }
+
getLocationPermission();
getDeviceLocation();
@@ -181,7 +184,29 @@ public class TasksFragment extends Fragment {
buttonAddPicture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- // Code here executes on main thread after user presses button
+
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "add Picture!");
+ }
+
+ if (!mCameraPermissionGranted)
+ {
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "Camera permission not granted!");
+ }
+ getCameraPPermission();
+ }
+ else
+ {
+ if (BuildConfig.DEBUG)
+ {
+ Log.d(TAG, "Camera permission granted!");
+ }
+ Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
+ startActivityForResult(cameraIntent, CAMERA_REQUEST);
+ }
}
});
@@ -192,17 +217,35 @@ public class TasksFragment extends Fragment {
final TextView titleView = viewInflated.findViewById(R.id.taskTitleUserInput);
final TextView noticeView = viewInflated.findViewById(R.id.taskNoticeUserInput);
- if (titleView.getText()!=null)
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "new title: " + titleView.getText());
+ }
+
+ if (titleView.getText().length()>0)
{
//save user input
newTask.setTitle(String.valueOf(titleView.getText()));
newTask.setNotice(String.valueOf(noticeView.getText()));
+
+ boolean result = allTasks.add(newTask);
+
if (BuildConfig.DEBUG)
{
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();
dialog.dismiss();
//confirm added task
@@ -244,6 +287,160 @@ public class TasksFragment extends Fragment {
return root;
}
+ @Override
+ public void onPause()
+ {
+ super.onPause();
+
+ emptyPreferencesAndSaveTasksToPreferences();
+ }
+
+ /**
+ * Saves tasks to preferences
+ */
+ private void emptyPreferencesAndSaveTasksToPreferences() {
+ if (!allTasks.isEmpty()) {
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "allTasks not empty!");
+ for (OwnTask task: allTasks)
+ {
+ Log.d(TAG, task.toString());
+ }
+ }
+
+ PreferenceManager.getDefaultSharedPreferences(getContext()).edit().remove(KEY_ALL_TASKS).commit();
+
+ JSONArray writeObjects = new JSONArray();
+
+ for (OwnTask task: allTasks)
+ {
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, task.toString());
+ }
+ }
+
+
+ for (OwnTask task: allTasks)
+ {
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "save task: " + task.toString());
+ }
+
+ if (task.getImage() != null)
+ {
+
+ //save image to external storage and save path
+ String path = saveReceivedImage(task.getImage(), task.getId());
+ task.setPathImage(path);
+
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "saved image with path: " + task.getPathImage());
+ }
+ }
+
+
+ JSONObject object = task.toJSONObject();
+ writeObjects.put(object);
+
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, object.toString());
+ }
+ }
+
+ PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_ALL_TASKS, writeObjects.toString()).commit();
+ }
+ }
+
+ 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
+ *
+ * @return list of OwnTask
+ */
+ private List readTasksFromPreferences() {
+ List tasks = new ArrayList<>();
+
+ try {
+ String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_ALL_TASKS, "error");
+ if(!"error".equalsIgnoreCase(jsonString)) {
+ JSONArray jsonObjects = new JSONArray(jsonString);
+
+ for (int i = 0; i adapterView, View view, int i, long l) {
+
+ //for (int j = 0; j < adapterView.getChildCount(); j++)
+ //adapterView.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
+
+ // change the background color of the selected element
+ //view.setBackgroundColor(Color.LTGRAY);
+ //adapterView.setSelection(i);
+ }});
+ }
+
/**
* Request location permission, so that we can get the location of the device.
* The result of the permission request is handled by a callback,
@@ -262,6 +459,60 @@ public class TasksFragment extends Fragment {
}
}
+ /**
+ * Request camera permission, so that we can get an image from the camera.
+ * The result of the permission request is handled by a callback,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getCameraPPermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.CAMERA)
+ == PackageManager.PERMISSION_GRANTED) {
+ mCameraPermissionGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.CAMERA},
+ MY_CAMERA_PERMISSION_CODE);
+ }
+ }
+
+ /**
+ * 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,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getReadStoragePermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.READ_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
+ READ_EXTERNAL_STORAGE_CODE);
+ }
+ }
+
+ /**
+ * 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,
+ * onRequestPermissionsResult.
+ *
+ */
+ private void getWriteStoragePPermission() {
+ if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
+ Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ == PackageManager.PERMISSION_GRANTED) {
+ mWriteStorageGranted = true;
+ } else {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ WRITE_EXTERNAL_STORAGE_CODE);
+ }
+ }
+
/**
* DOCU ME!
* TOOD: What are grant results etc for?
@@ -272,6 +523,9 @@ public class TasksFragment extends Fragment {
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
{
+ if (BuildConfig.DEBUG) {
+ Log.d(TAG, "onRequestPermissionResult Code: " + requestCode);
+ }
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
@@ -282,6 +536,44 @@ public class TasksFragment extends Fragment {
mLocationPermissionGranted = true;
}
}
+ case MY_CAMERA_PERMISSION_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mCameraPermissionGranted = true;
+ }
+ }
+ case READ_EXTERNAL_STORAGE_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mReadStorageGranted = true;
+ }
+ }
+ case WRITE_EXTERNAL_STORAGE_CODE: {
+
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ mWriteStorageGranted = true;
+ }
+ }
+ }
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK)
+ {
+ Bitmap photo = (Bitmap) data.getExtras().get("data");
+ newTask.setImage(photo);
+ newTask.setPathImage(saveReceivedImage(photo,newTask.getId()));
+
+ if (imageToAdd != null && photo != null)
+ {
+ imageToAdd.setImageBitmap(photo);
+ }
}
}
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
new file mode 100644
index 0000000..28a9423
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/res/layout/area_element.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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
new file mode 100644
index 0000000..e0a10eb
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/res/layout/area_input.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/layout/fragment_areas.xml b/Code Android/meinWald/app/src/main/res/layout/fragment_areas.xml
index 2ee4756..143a4fc 100644
--- a/Code Android/meinWald/app/src/main/res/layout/fragment_areas.xml
+++ b/Code Android/meinWald/app/src/main/res/layout/fragment_areas.xml
@@ -6,20 +6,20 @@
android:layout_height="match_parent"
tools:context=".ui.area.AreaFragment">
-
+ app:layout_constraintTop_toTopOf="parent" />
-
-
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/layout/image_large.xml b/Code Android/meinWald/app/src/main/res/layout/image_large.xml
new file mode 100644
index 0000000..dbfb71c
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/res/layout/image_large.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/layout/task_element.xml b/Code Android/meinWald/app/src/main/res/layout/task_element.xml
new file mode 100644
index 0000000..bfd5e01
--- /dev/null
+++ b/Code Android/meinWald/app/src/main/res/layout/task_element.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/layout/task_input.xml b/Code Android/meinWald/app/src/main/res/layout/task_input.xml
index af27ab6..be355d8 100644
--- a/Code Android/meinWald/app/src/main/res/layout/task_input.xml
+++ b/Code Android/meinWald/app/src/main/res/layout/task_input.xml
@@ -61,13 +61,38 @@
android:layout_height="wrap_content"
android:text="Bild hinzufügen!" />
-
+
+
+
+
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/values/colors.xml b/Code Android/meinWald/app/src/main/res/values/colors.xml
index df99000..2634349 100644
--- a/Code Android/meinWald/app/src/main/res/values/colors.xml
+++ b/Code Android/meinWald/app/src/main/res/values/colors.xml
@@ -3,4 +3,5 @@
#1B5E20
#3700B3
#03DAC5
+ #c0edc3
\ No newline at end of file
diff --git a/Code Android/meinWald/app/src/main/res/values/styles.xml b/Code Android/meinWald/app/src/main/res/values/styles.xml
index fac9291..0af7d1d 100644
--- a/Code Android/meinWald/app/src/main/res/values/styles.xml
+++ b/Code Android/meinWald/app/src/main/res/values/styles.xml
@@ -7,4 +7,17 @@
- @color/colorAccent
+
+
\ No newline at end of file