Migrate to ActivityResult APIs
parent
c81105186f
commit
855b0a0249
|
@ -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
|
||||||
|
|
|
@ -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,13 +144,9 @@ 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)
|
|
||||||
when (requestCode) {
|
|
||||||
Keys.REQUEST_CODE_LOCATION -> {
|
|
||||||
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
|
||||||
// permission was granted - re-bind service
|
// permission was granted - re-bind service
|
||||||
activity?.unbindService(connection)
|
activity?.unbindService(connection)
|
||||||
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
|
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
|
||||||
|
@ -159,35 +156,32 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
|
||||||
activity?.unbindService(connection)
|
activity?.unbindService(connection)
|
||||||
}
|
}
|
||||||
layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive)
|
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.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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
|
// start service via intent so that it keeps running after unbind
|
||||||
startTrackerService()
|
startTrackerService()
|
||||||
trackerService.startTracking()
|
trackerService.startTracking()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
Keys.REQUEST_CODE_ACTIVITY_RESUME -> {
|
|
||||||
LogHelper.e(TAG, "permissions => ${grantResults.isEmpty()} ${permissions[0]}") // todo remove
|
/* Register the permission launcher for resuming the tracking service */
|
||||||
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
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.")
|
LogHelper.i(TAG, "Request result: Activity Recognition permission has been granted.")
|
||||||
} else {
|
} else {
|
||||||
LogHelper.i(TAG, "Request result: Activity Recognition permission has NOT been granted.")
|
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
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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()
|
||||||
|
|
|
@ -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,26 +114,25 @@ 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
|
||||||
Keys.REQUEST_SAVE_GPX -> {
|
if (result.resultCode == Activity.RESULT_OK && result.data != null) {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
|
||||||
val sourceUri: Uri = Uri.parse(track.gpxUriString)
|
val sourceUri: Uri = Uri.parse(track.gpxUriString)
|
||||||
val targetUri: Uri? = data.data
|
val targetUri: Uri? = result.data?.data
|
||||||
if (targetUri != null) {
|
if (targetUri != null) {
|
||||||
// copy file async (= fire & forget - no return value needed)
|
// copy file async (= fire & forget - no return value needed)
|
||||||
CoroutineScope(Dispatchers.IO).launch { 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Overrides onRenameTrackDialog from RenameTrackDialog */
|
/* Overrides onRenameTrackDialog from RenameTrackDialog */
|
||||||
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue