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 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 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) { View root = inflater.inflate(R.layout.fragment_areas, container, false); //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); } } }