Migrate to ActivityResult APIs

This commit is contained in:
TacoTheDank 2021-07-01 15:59:27 -04:00
parent c81105186f
commit 855b0a0249
3 changed files with 57 additions and 68 deletions

View file

@ -116,12 +116,6 @@ object Keys {
const val MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 5 const val MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 5
const val MAX_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 20 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 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 // notification
const val TRACKER_SERVICE_NOTIFICATION_ID: Int = 1 const val TRACKER_SERVICE_NOTIFICATION_ID: Int = 1

View file

@ -29,6 +29,7 @@ import android.os.IBinder
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
@ -107,7 +108,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
super.onStart() super.onStart()
// request location permission if denied // request location permission if denied
if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_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 // bind to TrackerService
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
@ -143,51 +144,44 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
handleServiceUnbind() handleServiceUnbind()
} }
/* Register the permission launcher for requesting location */
/* Overrides onRequestPermissionsResult from Fragment */ private val requestLocationPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean ->
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { if (isGranted) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) // permission was granted - re-bind service
when (requestCode) { activity?.unbindService(connection)
Keys.REQUEST_CODE_LOCATION -> { activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { LogHelper.i(TAG, "Request result: Location permission has been granted.")
// permission was granted - re-bind service } else {
activity?.unbindService(connection) // permission denied - unbind service
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) activity?.unbindService(connection)
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
}
} }
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 */ /* Overrides onYesNoDialog from YesNoDialogListener */
override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) {
@ -221,7 +215,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
// request activity recognition permission on Android Q+ if denied // 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) { 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 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 { } else {
// start service via intent so that it keeps running after unbind // start service via intent so that it keeps running after unbind
startTrackerService() startTrackerService()
@ -235,7 +229,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
// request activity recognition permission on Android Q+ if denied // 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) { 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 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 { } else {
// start service via intent so that it keeps running after unbind // start service via intent so that it keeps running after unbind
startTrackerService() startTrackerService()

View file

@ -29,6 +29,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.net.toFile import androidx.core.net.toFile
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
@ -112,24 +114,23 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
layout.saveViewStateToTrack() layout.saveViewStateToTrack()
} }
/* Register the ActivityResultLauncher for saving GPX */
private val requestSaveGpxLauncher =
registerForActivityResult(StartActivityForResult(), this::requestSaveGpxResult)
/* Overrides onActivityResult from Fragment */ /* Pass the activity result */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private fun requestSaveGpxResult(result: ActivityResult) {
when (requestCode) { // save GPX file to result file location
// save GPX file to result file location if (result.resultCode == Activity.RESULT_OK && result.data != null) {
Keys.REQUEST_SAVE_GPX -> { val sourceUri: Uri = Uri.parse(track.gpxUriString)
if (resultCode == Activity.RESULT_OK && data != null) { val targetUri: Uri? = result.data?.data
val sourceUri: Uri = Uri.parse(track.gpxUriString) if (targetUri != null) {
val targetUri: Uri? = data.data // copy file async (= fire & forget - no return value needed)
if (targetUri != null) { CoroutineScope(Dispatchers.IO).launch {
// copy file async (= fire & forget - no return value needed) FileHelper.saveCopyOfFileSuspended(activity as Context, originalFileUri = sourceUri, targetFileUri = targetUri)
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()
}
} }
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 type = Keys.MIME_TYPE_GPX
putExtra(Intent.EXTRA_TITLE, FileHelper.getGpxFileName(track)) putExtra(Intent.EXTRA_TITLE, FileHelper.getGpxFileName(track))
} }
// file gets saved in onActivityResult // file gets saved in the ActivityResult
try { try {
startActivityForResult(intent, Keys.REQUEST_SAVE_GPX) requestSaveGpxLauncher.launch(intent)
} catch (e: Exception) { } catch (e: Exception) {
LogHelper.e(TAG, "Unable to save GPX.") LogHelper.e(TAG, "Unable to save GPX.")
Toast.makeText(activity as Context, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG).show() Toast.makeText(activity as Context, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG).show()