Neat new feature: Quick Settings tile for starting / stopping a recording

master
y20k 2020-01-27 18:22:44 +01:00
parent 4351926415
commit 97b64dfd59
No known key found for this signature in database
GPG Key ID: 824D4259F41FAFF6
4 changed files with 199 additions and 7 deletions

View File

@ -27,6 +27,7 @@
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning">
<!-- MAIN ACTIVITY -->
<activity android:name=".MainActivity"> <activity android:name=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
@ -46,7 +47,18 @@
</intent-filter> </intent-filter>
</service> </service>
<!-- TRACKING TOGGLE SERVICE SYSTEM QUICK SETTINGS -->
<service
android:name=".TrackingToggleTileService"
android:label="@string/quick_settings_tile_title_default"
android:icon="@drawable/ic_notification_icon_small_24dp"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<!-- FILE PROVIDER GPX -->
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider" android:authorities="${applicationId}.provider"
@ -60,6 +72,4 @@
</application> </application>
</manifest> </manifest>

View File

@ -19,10 +19,7 @@ package org.y20k.trackbook
import YesNoDialog import YesNoDialog
import android.Manifest import android.Manifest
import android.content.ComponentName import android.content.*
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.Location import android.location.Location
import android.os.Build import android.os.Build
@ -35,6 +32,7 @@ import android.view.ViewGroup
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
import androidx.preference.PreferenceManager
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.y20k.trackbook.core.Track 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() * Defines callbacks for service binding, passed to bindService()
*/ */
@ -244,12 +258,16 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener {
val binder = service as TrackerService.LocalBinder val binder = service as TrackerService.LocalBinder
trackerService = binder.service trackerService = binder.service
bound = true bound = true
// register listener for changes in shared preferences
PreferenceManager.getDefaultSharedPreferences(activity as Context).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
// start listening for location updates // start listening for location updates
handler.removeCallbacks(periodicLocationRequestRunnable) handler.removeCallbacks(periodicLocationRequestRunnable)
handler.postDelayed(periodicLocationRequestRunnable, 0) handler.postDelayed(periodicLocationRequestRunnable, 0)
} }
override fun onServiceDisconnected(arg0: ComponentName) { override fun onServiceDisconnected(arg0: ComponentName) {
bound = false bound = false
// unregister listener for changes in shared preferences
PreferenceManager.getDefaultSharedPreferences(activity as Context).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
// stop receiving location updates // stop receiving location updates
handler.removeCallbacks(periodicLocationRequestRunnable) handler.removeCallbacks(periodicLocationRequestRunnable)
} }

View File

@ -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
*/
}

View File

@ -57,7 +57,10 @@
<string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string> <string name="statistics_sheet_p_min_altitude">Lowest waypoint:</string>
<string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string> <string name="statistics_sheet_p_positive_elevation">Elevation (uphill):</string>
<string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string> <string name="statistics_sheet_p_negative_elevation">Elevation (downhill):</string>
<!-- Menu Actions --> <!-- Recording Quick Settings Tile -->
<string name="quick_settings_tile_title_default">Recording</string>
<string name="quick_settings_tile_title_start">Start Recording</string>
<string name="quick_settings_tile_title_stop">Stop Recording</string>
<!-- Onboarding Layout --> <!-- Onboarding Layout -->
<string name="layout_onboarding_description_app_icon">Trackbook App Icon</string> <string name="layout_onboarding_description_app_icon">Trackbook App Icon</string>
<!-- Track Tab Onboarding --> <!-- Track Tab Onboarding -->
@ -88,6 +91,8 @@
<string name="descr_fab_sub_menu_button_clear">Clear button</string> <string name="descr_fab_sub_menu_button_clear">Clear button</string>
<string name="descr_fab_sub_menu_button_resume">Resume button</string> <string name="descr_fab_sub_menu_button_resume">Resume button</string>
<string name="descr_mark_starred_button">Mark as starred button</string> <string name="descr_mark_starred_button">Mark as starred button</string>
<string name="descr_quick_settings_tile_title_start">Start Recording</string>
<string name="descr_quick_settings_tile_title_stop">Stop Recording</string>
<string name="descr_statistics_sheet_delete_button">Track delete button</string> <string name="descr_statistics_sheet_delete_button">Track delete button</string>
<string name="descr_statistics_sheet_edit_button">Track edit button</string> <string name="descr_statistics_sheet_edit_button">Track edit button</string>
<string name="descr_statistics_sheet_share_button">Share as GPX button</string> <string name="descr_statistics_sheet_share_button">Share as GPX button</string>