From 97b64dfd598782fce29659e44d44384ce144fcde Mon Sep 17 00:00:00 2001 From: y20k Date: Mon, 27 Jan 2020 18:22:44 +0100 Subject: [PATCH] Neat new feature: Quick Settings tile for starting / stopping a recording --- app/src/main/AndroidManifest.xml | 14 +- .../java/org/y20k/trackbook/MapFragment.kt | 26 ++- .../trackbook/TrackingToggleTileService.kt | 159 ++++++++++++++++++ app/src/main/res/values/strings.xml | 7 +- 4 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1199564..5c7bfd6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,7 @@ android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> + @@ -46,7 +47,18 @@ + + + + + + + - - diff --git a/app/src/main/java/org/y20k/trackbook/MapFragment.kt b/app/src/main/java/org/y20k/trackbook/MapFragment.kt index da1747e..54a7865 100644 --- a/app/src/main/java/org/y20k/trackbook/MapFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/MapFragment.kt @@ -19,10 +19,7 @@ package org.y20k.trackbook import YesNoDialog import android.Manifest -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.content.ServiceConnection +import android.content.* import android.content.pm.PackageManager import android.location.Location import android.os.Build @@ -35,6 +32,7 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.navigation.fragment.findNavController +import androidx.preference.PreferenceManager import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import org.y20k.trackbook.core.Track @@ -235,6 +233,22 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener { } + /* + * Defines the listener for changes in shared preferences + */ + private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> + when (key) { + Keys.PREF_TRACKING_STATE -> { + trackingState = PreferencesHelper.loadTrackingState(activity as Context) + layout.updateRecordingButton(trackingState) + } + } + } + /* + * End of declaration + */ + + /* * Defines callbacks for service binding, passed to bindService() */ @@ -244,12 +258,16 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener { val binder = service as TrackerService.LocalBinder trackerService = binder.service bound = true + // register listener for changes in shared preferences + PreferenceManager.getDefaultSharedPreferences(activity as Context).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) // start listening for location updates handler.removeCallbacks(periodicLocationRequestRunnable) handler.postDelayed(periodicLocationRequestRunnable, 0) } override fun onServiceDisconnected(arg0: ComponentName) { bound = false + // unregister listener for changes in shared preferences + PreferenceManager.getDefaultSharedPreferences(activity as Context).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) // stop receiving location updates handler.removeCallbacks(periodicLocationRequestRunnable) } diff --git a/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt b/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt new file mode 100644 index 0000000..d178f0f --- /dev/null +++ b/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt @@ -0,0 +1,159 @@ +/* + * TrackingToggleTileService.kt + * Implements the TrackingToggleTileService service + * A TrackingToggleTileService toggles the recording state from a quick settings tile + * + * This file is part of + * TRACKBOOK - Movement Recorder for Android + * + * Copyright (c) 2016-20 - Y20K.org + * Licensed under the MIT-License + * http://opensource.org/licenses/MIT + * + * Trackbook uses osmdroid - OpenStreetMap-Tools for Android + * https://github.com/osmdroid/osmdroid + */ + + +package org.y20k.trackbook + +import android.content.* +import android.graphics.drawable.Icon +import android.os.IBinder +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import androidx.preference.PreferenceManager +import org.y20k.trackbook.helpers.LogHelper +import org.y20k.trackbook.helpers.PreferencesHelper + + +/* + * TrackingToggleTileService class + */ +class TrackingToggleTileService(): TileService() { + + /* Define log tag */ + private val TAG: String = LogHelper.makeLogTag(TrackingToggleTileService::class.java) + + + /* Main class variables */ + private var bound: Boolean = false + private var trackingState: Int = Keys.STATE_NOT_TRACKING + private lateinit var trackerService: TrackerService + + + /* Overrides onTileAdded from TileService */ + override fun onTileAdded() { + super.onTileAdded() + // get saved tracking state + trackingState = PreferencesHelper.loadTrackingState(this) + } + + /* Overrides onTileRemoved from TileService */ + override fun onTileRemoved() { + super.onTileRemoved() + } + + + /* Overrides onStartListening from TileService */ + override fun onStartListening() { + super.onStartListening() + // tile becomes visible - bind tracker service + bindService(Intent(this, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) + } + + + /* Overrides onClick from TileService */ + override fun onClick() { + super.onClick() + when (trackingState) { + Keys.STATE_TRACKING_ACTIVE -> { + trackerService.stopTracking() + } + else -> { + trackerService.startTracking(newTrack = false) + } + } + } + + + /* Overrides onStopListening from TileService */ + override fun onStopListening() { + super.onStopListening() + // tile no longer visible - unbind tracker service + unbindService(connection) + } + + + /* Overrides onDestroy from Service */ + override fun onDestroy() { + super.onDestroy() + if (bound) unbindService(connection) + } + + + /* Update quick settings tile */ + private fun updateTile() { + val tile: Tile = qsTile + tile.icon = Icon.createWithResource(this, R.drawable.ic_notification_icon_small_24dp) + when (trackingState) { + Keys.STATE_TRACKING_ACTIVE -> { + tile.label = getString(R.string.quick_settings_tile_title_stop) + tile.contentDescription = getString(R.string.descr_quick_settings_tile_title_stop) + tile.state = Tile.STATE_ACTIVE + } + else -> { + tile.label = getString(R.string.quick_settings_tile_title_start) + tile.contentDescription = getString(R.string.descr_quick_settings_tile_title_start) + tile.state = Tile.STATE_INACTIVE + } + } + tile.updateTile() + } + + + /* + * Defines the listener for changes in shared preferences + */ + private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> + when (key) { + Keys.PREF_TRACKING_STATE -> { + trackingState = PreferencesHelper.loadTrackingState(this) + updateTile() + } + } + } + /* + * End of declaration + */ + + + /* + * Defines callbacks for service binding, passed to bindService() + */ + private val connection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, service: IBinder) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + val binder = service as TrackerService.LocalBinder + trackerService = binder.service + trackingState = trackerService.trackingState + bound = true + // update state of tile + updateTile() + // register listener for changes in shared preferences + PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + + } + override fun onServiceDisconnected(arg0: ComponentName) { + bound = false + // unregister listener for changes in shared preferences + PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + } + } + /* + * End of declaration + */ + + + +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 698f497..1908e1d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -57,7 +57,10 @@ Lowest waypoint: Elevation (uphill): Elevation (downhill): - + + Recording + Start Recording + Stop Recording Trackbook App Icon @@ -88,6 +91,8 @@ Clear button Resume button Mark as starred button + Start Recording + Stop Recording Track delete button Track edit button Share as GPX button