request permission to use the step counter

This commit is contained in:
y20k 2021-05-17 15:44:11 +02:00
parent 583be6d95e
commit 940aa2209b
No known key found for this signature in database
GPG key ID: 824D4259F41FAFF6
7 changed files with 78 additions and 22 deletions

View file

@ -58,6 +58,7 @@ dependencies {
// AndroidX
def navigationVersion = "2.3.5"
implementation "androidx.activity:activity-ktx:1.2.3"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.core:core-ktx:1.3.2'

View file

@ -16,6 +16,7 @@
<!-- DANGEROUS PERMISSIONS, must request -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<application
android:name=".Trackbook"

View file

@ -116,7 +116,9 @@ 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_FOREGROUND = 42
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

View file

@ -92,9 +92,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
trackerService.clearTrack()
}
layout.resumeButton.setOnClickListener {
// start service via intent so that it keeps running after unbind
startTrackerService()
trackerService.resumeTracking()
resumeTracking()
}
return layout.rootView
@ -106,7 +104,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_FOREGROUND)
this.requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), Keys.REQUEST_CODE_LOCATION)
}
// bind to TrackerService
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
@ -147,11 +145,11 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
Keys.REQUEST_CODE_FOREGROUND -> {
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)
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
@ -160,6 +158,30 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
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
}
}
}
@ -191,6 +213,34 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
}
/* Start recording waypoints */
private fun startTracking() {
// 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)
} else {
// start service via intent so that it keeps running after unbind
startTrackerService()
trackerService.startTracking()
}
}
/* Resume recording waypoints */
private fun resumeTracking() {
// 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)
} else {
// start service via intent so that it keeps running after unbind
startTrackerService()
trackerService.resumeTracking()
}
}
/* Start tracker service */
private fun startTrackerService() {
val intent = Intent(activity, TrackerService::class.java)
@ -219,11 +269,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlayHelpe
when (trackingState) {
Keys.STATE_TRACKING_STOPPED -> layout.toggleRecordingButtonSubMenu()
Keys.STATE_TRACKING_ACTIVE -> trackerService.stopTracking()
Keys.STATE_TRACKING_NOT -> {
// start service via intent so that it keeps running after unbind
startTrackerService()
trackerService.startTracking()
}
Keys.STATE_TRACKING_NOT -> startTracking()
}
}

View file

@ -449,11 +449,7 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener {
/* Registers a step counter listener */
private fun startStepCounter() {
val stepCounterAvailable = sensorManager.registerListener(
this, sensorManager.getDefaultSensor(
Sensor.TYPE_STEP_COUNTER
), SensorManager.SENSOR_DELAY_UI
)
val stepCounterAvailable = sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI)
if (!stepCounterAvailable) {
LogHelper.w(TAG, "Pedometer sensor not available.")
track.stepCount = -1f

View file

@ -77,6 +77,7 @@ data class TrackFragmentLayoutHolder(private var context: Context, private var m
private val statisticsSheet: NestedScrollView
private val statisticsView: View
private val distanceView: MaterialTextView
private val stepsTitleView: MaterialTextView
private val stepsView: MaterialTextView
private val waypointsView: MaterialTextView
private val durationView: MaterialTextView
@ -118,6 +119,7 @@ data class TrackFragmentLayoutHolder(private var context: Context, private var m
statisticsSheet = rootView.findViewById(R.id.statistics_sheet)
statisticsView = rootView.findViewById(R.id.statistics_view)
distanceView = rootView.findViewById(R.id.statistics_data_distance)
stepsTitleView = rootView.findViewById(R.id.statistics_p_steps)
stepsView = rootView.findViewById(R.id.statistics_data_steps)
waypointsView = rootView.findViewById(R.id.statistics_data_waypoints)
durationView = rootView.findViewById(R.id.statistics_data_duration)
@ -202,10 +204,18 @@ data class TrackFragmentLayoutHolder(private var context: Context, private var m
/* Sets up the statistics sheet */
private fun setupStatisticsViews() {
// get step count string
// get step count string - hide step count if not available
val steps: String
if (track.stepCount == -1f) steps = context.getString(R.string.statistics_sheet_p_steps_no_pedometer)
else steps = track.stepCount.roundToInt().toString()
if (track.stepCount == -1f) {
steps = context.getString(R.string.statistics_sheet_p_steps_no_pedometer)
stepsTitleView.isGone = true
stepsView.isGone = true
}
else {
steps = track.stepCount.roundToInt().toString()
stepsTitleView.isVisible = true
stepsView.isVisible = true
}
// populate views
trackNameView.text = track.name

View file

@ -2,7 +2,7 @@
buildscript {
ext {
kotlin_version = '1.4.32'
kotlin_version = '1.5.0'
navigation_version = '2.3.3'
}
repositories {
@ -10,7 +10,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigation_version"