diff --git a/app/src/main/java/org/y20k/trackbook/Keys.kt b/app/src/main/java/org/y20k/trackbook/Keys.kt index 8a4a4ad..b9397ac 100644 --- a/app/src/main/java/org/y20k/trackbook/Keys.kt +++ b/app/src/main/java/org/y20k/trackbook/Keys.kt @@ -116,12 +116,6 @@ object Keys { const val MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 5 const val MAX_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 20 const val ALTITUDE_MEASUREMENT_ERROR_THRESHOLD = 10 // altitude changes of 10 meter or more (per 15 seconds) are being discarded - const val REQUEST_CODE_LOCATION = 42 - const val REQUEST_CODE_ACTIVITY_START = 23 - const val REQUEST_CODE_ACTIVITY_RESUME = 5 - - // requests - const val REQUEST_SAVE_GPX: Int = 23 // notification const val TRACKER_SERVICE_NOTIFICATION_ID: Int = 1 diff --git a/app/src/main/java/org/y20k/trackbook/MapFragment.kt b/app/src/main/java/org/y20k/trackbook/MapFragment.kt index 6716613..29cd30e 100644 --- a/app/src/main/java/org/y20k/trackbook/MapFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/MapFragment.kt @@ -29,6 +29,7 @@ import android.os.IBinder import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.result.contract.ActivityResultContracts.RequestPermission import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController @@ -106,7 +107,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe super.onStart() // request location permission if denied if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { - this.requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), Keys.REQUEST_CODE_LOCATION) + requestLocationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) } // bind to TrackerService activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) @@ -142,51 +143,44 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe handleServiceUnbind() } - - /* Overrides onRequestPermissionsResult from Fragment */ - override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - when (requestCode) { - Keys.REQUEST_CODE_LOCATION -> { - if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - // permission was granted - re-bind service - activity?.unbindService(connection) - activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) - LogHelper.i(TAG, "Request result: Location permission has been granted.") - } else { - // permission denied - unbind service - activity?.unbindService(connection) - } - layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive) - return - } - Keys.REQUEST_CODE_ACTIVITY_START -> { - LogHelper.e(TAG, "permissions => ${grantResults.isEmpty()} ${permissions[0]}") // todo remove - if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.") - } else { - LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.") - } - // start service via intent so that it keeps running after unbind - startTrackerService() - trackerService.startTracking() - return - } - Keys.REQUEST_CODE_ACTIVITY_RESUME -> { - LogHelper.e(TAG, "permissions => ${grantResults.isEmpty()} ${permissions[0]}") // todo remove - if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.") - } else { - LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.") - } - // start service via intent so that it keeps running after unbind - startTrackerService() - trackerService.resumeTracking() - return - } + /* Register the permission launcher for requesting location */ + private val requestLocationPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> + if (isGranted) { + // permission was granted - re-bind service + activity?.unbindService(connection) + activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) + LogHelper.i(TAG, "Request result: Location permission has been granted.") + } else { + // permission denied - unbind service + activity?.unbindService(connection) } + layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive) } + /* Register the permission launcher for starting the tracking service */ + private val startTrackingPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> + logPermissionRequestResult(isGranted) + // start service via intent so that it keeps running after unbind + startTrackerService() + trackerService.startTracking() + } + + /* Register the permission launcher for resuming the tracking service */ + private val resumeTrackingPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> + logPermissionRequestResult(isGranted) + // start service via intent so that it keeps running after unbind + startTrackerService() + trackerService.resumeTracking() + } + + /* Logs the request result of the Activity Recognition permission launcher */ + private fun logPermissionRequestResult(isGranted: Boolean) { + if (isGranted) { + LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.") + } else { + LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.") + } + } /* Overrides onYesNoDialog from YesNoDialogListener */ override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { @@ -220,7 +214,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe // request activity recognition permission on Android Q+ if denied if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED) { LogHelper.e(TAG, "permissions resume DING") // todo remove - this.requestPermissions(arrayOf(Manifest.permission.ACTIVITY_RECOGNITION), Keys.REQUEST_CODE_ACTIVITY_START) + startTrackingPermissionLauncher.launch(Manifest.permission.ACTIVITY_RECOGNITION) } else { // start service via intent so that it keeps running after unbind startTrackerService() @@ -234,7 +228,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe // request activity recognition permission on Android Q+ if denied if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_DENIED) { LogHelper.e(TAG, "permissions resume DING") // todo remove - this.requestPermissions(arrayOf(Manifest.permission.ACTIVITY_RECOGNITION), Keys.REQUEST_CODE_ACTIVITY_RESUME) + resumeTrackingPermissionLauncher.launch(Manifest.permission.ACTIVITY_RECOGNITION) } else { // start service via intent so that it keeps running after unbind startTrackerService() diff --git a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt index 0e5d40c..87a7c3a 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt @@ -29,6 +29,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast +import androidx.activity.result.ActivityResult +import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult import androidx.core.content.FileProvider import androidx.core.net.toFile import androidx.core.os.bundleOf @@ -112,24 +114,23 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi layout.saveViewStateToTrack() } + /* Register the ActivityResultLauncher for saving GPX */ + private val requestSaveGpxLauncher = + registerForActivityResult(StartActivityForResult(), this::requestSaveGpxResult) - /* Overrides onActivityResult from Fragment */ - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - when (requestCode) { - // save GPX file to result file location - Keys.REQUEST_SAVE_GPX -> { - if (resultCode == Activity.RESULT_OK && data != null) { - val sourceUri: Uri = Uri.parse(track.gpxUriString) - val targetUri: Uri? = data.data - if (targetUri != null) { - // copy file async (= fire & forget - no return value needed) - CoroutineScope(Dispatchers.IO).launch { FileHelper.saveCopyOfFileSuspended( activity as Context, originalFileUri = sourceUri, targetFileUri = targetUri) } - Toast.makeText(activity as Context, R.string.toast_message_save_gpx, Toast.LENGTH_LONG).show() - } + /* Pass the activity result */ + private fun requestSaveGpxResult(result: ActivityResult) { + // save GPX file to result file location + if (result.resultCode == Activity.RESULT_OK && result.data != null) { + val sourceUri: Uri = Uri.parse(track.gpxUriString) + val targetUri: Uri? = result.data?.data + if (targetUri != null) { + // copy file async (= fire & forget - no return value needed) + CoroutineScope(Dispatchers.IO).launch { + FileHelper.saveCopyOfFileSuspended(activity as Context, originalFileUri = sourceUri, targetFileUri = targetUri) } + Toast.makeText(activity as Context, R.string.toast_message_save_gpx, Toast.LENGTH_LONG).show() } - // let activity handle result - else -> super.onActivityResult(requestCode, resultCode, data) } } @@ -179,9 +180,9 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi type = Keys.MIME_TYPE_GPX putExtra(Intent.EXTRA_TITLE, FileHelper.getGpxFileName(track)) } - // file gets saved in onActivityResult + // file gets saved in the ActivityResult try { - startActivityForResult(intent, Keys.REQUEST_SAVE_GPX) + requestSaveGpxLauncher.launch(intent) } catch (e: Exception) { LogHelper.e(TAG, "Unable to save GPX.") Toast.makeText(activity as Context, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG).show()