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.database.DataSetObserver; 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; import androidx.lifecycle.Observer; 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; import com.google.android.gms.tasks.OnCompleteListener; 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; /** * The entry point to the Fused Location Provider. */ private FusedLocationProviderClient mFusedLocationProviderClient; private boolean mLocationPermissionGranted; /** * The geographical location where the device is currently located. * That is the last-known location retrieved by the Fused Location Provider. */ private Location mLastKnownLocation; /** * ______________________________________________________________________________________________ * TASKS */ private OwnTask newTask = new OwnTask(); private List allTasks; private ListView taskList; private static final String KEY_ALL_TASKS = "allTasks"; /** * ______________________________________________________________________________________________ * 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; public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { layoutInflater = inflater; root = inflater.inflate(R.layout.fragment_tasks, container, false); 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(); fab.setOnClickListener(new View.OnClickListener() { @Override 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); buttonSetLocation.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (BuildConfig.DEBUG) { Log.d(TAG, "add Location!"); } getLocationPermission(); getDeviceLocation(); do { final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { //wait if there is no known location } }, 100); }while (mLastKnownLocation == null); //save and display location newTask.setLocation(mLastKnownLocation); locationText.setText("Auf " + newTask.getLocation().getAccuracy() + " Meter genau!"); } }); //add picture final Button buttonAddPicture = viewInflated.findViewById(R.id.taskAddPicture); buttonAddPicture.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { 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); } } }); builder.setPositiveButton("Bestätigen", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final TextView titleView = viewInflated.findViewById(R.id.taskTitleUserInput); final TextView noticeView = viewInflated.findViewById(R.id.taskNoticeUserInput); 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())); newTask.setPathImage(newTask.saveImageToExternalStorage(getContext())); boolean result = allTasks.add(newTask); if (BuildConfig.DEBUG) { Log.d(TAG, "new Task: " + newTask.toString()); Log.d(TAG, "add new task result: " + result); } instantiateTaskList(); dialog.dismiss(); //confirm added task Toast toast = Toast.makeText(getActivity(), "Aufgabe 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(), "Aufgabentitel 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; } @Override public void onPause() { super.onPause(); emptyPreferencesAndSaveTasksToPreferences(); } /** * Saves tasks to preferences */ private void emptyPreferencesAndSaveTasksToPreferences() { if (BuildConfig.DEBUG) { Log.d(TAG, "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 = task.saveImageToExternalStorage(getContext()); 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(); } } /** * 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 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 taskList.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); }}); } /** * 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 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? * @param requestCode * @param permissions * @param grantResults */ @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: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 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; } } } } @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); if (imageToAdd != null && photo != null) { imageToAdd.setImageBitmap(photo); } } } /** * Get the best and most recent location of the device, which may be null in rare * cases when a location is not available. * */ private void getDeviceLocation() { try { if (mLocationPermissionGranted) { Task 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. mLastKnownLocation = task.getResult(); if (BuildConfig.DEBUG) { if (task.getResult() != null) { Log.d(TAG, "getDeviceLocation " + task.getResult().toString()); } } } else { if (BuildConfig.DEBUG) { Log.d(TAG, "Current location is null. Using defaults."); Log.e(TAG, "Exception: %s", task.getException()); } if (BuildConfig.DEBUG) { Log.d(TAG, "getDeviceLocation: task not successful"); } } } }); } } catch (SecurityException e) { if (BuildConfig.DEBUG) { Log.e(TAG, "Exception occurred: "); e.printStackTrace(); } } } }