Fix:Sleep timer shake to wake up to work when screen is locked

This commit is contained in:
advplyr
2021-11-27 13:35:21 -06:00
parent a7de535123
commit dc8b57f8cf
4 changed files with 82 additions and 54 deletions
+2 -2
View File
@@ -13,8 +13,8 @@ android {
applicationId "com.audiobookshelf.app" applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 48 versionCode 49
versionName "0.9.29-beta" versionName "0.9.30-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
@@ -1,16 +1,9 @@
package com.audiobookshelf.app package com.audiobookshelf.app
import android.Manifest
import android.app.DownloadManager import android.app.DownloadManager
import android.app.SearchManager
import android.content.* import android.content.*
import android.content.pm.PackageManager
import android.hardware.Sensor
import android.hardware.SensorManager
import android.os.* import android.os.*
import android.util.Log import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import com.anggrayudi.storage.SimpleStorage import com.anggrayudi.storage.SimpleStorage
import com.anggrayudi.storage.SimpleStorageHelper import com.anggrayudi.storage.SimpleStorageHelper
import com.getcapacitor.BridgeActivity import com.getcapacitor.BridgeActivity
@@ -29,11 +22,6 @@ class MainActivity : BridgeActivity() {
val storageHelper = SimpleStorageHelper(this) val storageHelper = SimpleStorageHelper(this)
val storage = SimpleStorage(this) val storage = SimpleStorage(this)
// The following are used for the shake detection
private var mSensorManager: SensorManager? = null
private var mAccelerometer: Sensor? = null
private var mShakeDetector: ShakeDetector? = null
val broadcastReceiver = object: BroadcastReceiver() { val broadcastReceiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) { when (intent?.action) {
@@ -61,24 +49,6 @@ class MainActivity : BridgeActivity() {
addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED) addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED)
} }
registerReceiver(broadcastReceiver, filter) registerReceiver(broadcastReceiver, filter)
initSensor()
}
override fun onResume() {
super.onResume()
Log.d(tag, "onResume Register sensor listener")
mSensorManager!!.registerListener(
mShakeDetector,
mAccelerometer,
SensorManager.SENSOR_DELAY_UI
)
}
override fun onPause() {
mSensorManager!!.unregisterListener(mShakeDetector)
super.onPause()
} }
override fun onDestroy() { override fun onDestroy() {
@@ -153,19 +123,6 @@ class MainActivity : BridgeActivity() {
storageHelper.onRequestPermissionsResult(requestCode, permissions, grantResults) storageHelper.onRequestPermissionsResult(requestCode, permissions, grantResults)
} }
private fun initSensor() {
// ShakeDetector initialization
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mShakeDetector = ShakeDetector()
mShakeDetector!!.setOnShakeListener(object : ShakeDetector.OnShakeListener {
override fun onShake(count: Int) {
Log.d(tag, "PHONE SHAKE! $count")
foregroundService.handleShake()
}
})
}
// override fun onUserInteraction() { // override fun onUserInteraction() {
// super.onUserInteraction() // super.onUserInteraction()
// Log.d(tag, "USER INTERACTION") // Log.d(tag, "USER INTERACTION")
@@ -6,6 +6,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.hardware.Sensor
import android.hardware.SensorManager
import android.net.Uri import android.net.Uri
import android.os.* import android.os.*
import android.support.v4.media.MediaBrowserCompat import android.support.v4.media.MediaBrowserCompat
@@ -54,6 +56,7 @@ import kotlin.math.roundToInt
const val NOTIFICATION_LARGE_ICON_SIZE = 144 // px const val NOTIFICATION_LARGE_ICON_SIZE = 144 // px
const val SLEEP_EXTENSION_TIME = 900000L // 15m const val SLEEP_EXTENSION_TIME = 900000L // 15m
const val SLEEP_TIMER_WAKE_UP_EXPIRATION = 120000L // 2m
class PlayerNotificationService : MediaBrowserServiceCompat() { class PlayerNotificationService : MediaBrowserServiceCompat() {
@@ -103,10 +106,17 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
private var onSeekBack: Boolean = false private var onSeekBack: Boolean = false
private var sleepTimerTask:TimerTask? = null private var sleepTimerTask:TimerTask? = null
private var shakeSensorUnregisterTask:TimerTask? = null
private var sleepTimerRunning:Boolean = false private var sleepTimerRunning:Boolean = false
private var sleepTimerEndTime:Long = 0L private var sleepTimerEndTime:Long = 0L
private var sleepTimerExtensionTime:Long = 0L private var sleepTimerExtensionTime:Long = 0L
private var sleepTimerFinishedAt:Long = 0L private var sleepTimerFinishedAt:Long = 0L
private var isShakeSensorRegistered:Boolean = false
// The following are used for the shake detection
private var mSensorManager: SensorManager? = null
private var mAccelerometer: Sensor? = null
private var mShakeDetector: ShakeDetector? = null
private lateinit var audiobookManager:AudiobookManager private lateinit var audiobookManager:AudiobookManager
private var newConnectionListener:SessionListener? = null private var newConnectionListener:SessionListener? = null
@@ -123,7 +133,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
Log.d(tag, "onBind") Log.d(tag, "onBind")
// Android Auto Media Browser Service // Android Auto Media Browser Service
if (SERVICE_INTERFACE.equals(intent.getAction())) { if (SERVICE_INTERFACE == intent.action) {
Log.d(tag, "Is Media Browser Service") Log.d(tag, "Is Media Browser Service")
return super.onBind(intent); return super.onBind(intent);
} }
@@ -149,6 +159,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
override fun onStart(intent: Intent?, startId: Int) { override fun onStart(intent: Intent?, startId: Int) {
Log.d(tag, "onStart $startId") Log.d(tag, "onStart $startId")
} }
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
@@ -256,6 +267,10 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
ctx = this ctx = this
Log.d(tag, "onCreate Register sensor listener ${mAccelerometer?.isWakeUpSensor}")
initSensor()
var client: OkHttpClient = OkHttpClient() var client: OkHttpClient = OkHttpClient()
audiobookManager = AudiobookManager(ctx, client) audiobookManager = AudiobookManager(ctx, client)
audiobookManager.init() audiobookManager.init()
@@ -479,6 +494,19 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
}) })
} }
private fun initSensor() {
// ShakeDetector initialization
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mShakeDetector = ShakeDetector()
mShakeDetector!!.setOnShakeListener(object : ShakeDetector.OnShakeListener {
override fun onShake(count: Int) {
Log.d(tag, "PHONE SHAKE! $count")
handleShake()
}
})
}
fun handleCallMediaButton(intent: Intent): Boolean { fun handleCallMediaButton(intent: Intent): Boolean {
if(Intent.ACTION_MEDIA_BUTTON == intent.getAction()) { if(Intent.ACTION_MEDIA_BUTTON == intent.getAction()) {
@@ -1004,12 +1032,19 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
return ((sleepTimeRemaining / 1000).toDouble()).roundToInt() return ((sleepTimeRemaining / 1000).toDouble()).roundToInt()
} }
fun getIsSleepTimerRunning():Boolean {
return sleepTimerRunning
}
fun setSleepTimer(time: Long, isChapterTime: Boolean) : Boolean { fun setSleepTimer(time: Long, isChapterTime: Boolean) : Boolean {
Log.d(tag, "Setting Sleep Timer for $time is chapter time $isChapterTime") Log.d(tag, "Setting Sleep Timer for $time is chapter time $isChapterTime")
sleepTimerTask?.cancel() sleepTimerTask?.cancel()
sleepTimerRunning = false sleepTimerRunning = false
sleepTimerFinishedAt = 0L sleepTimerFinishedAt = 0L
// Register shake sensor
registerSensor()
var currentTime = getCurrentTime() var currentTime = getCurrentTime()
if (isChapterTime) { if (isChapterTime) {
if (currentTime > time) { if (currentTime > time) {
@@ -1041,8 +1076,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
currentPlayer.pause() currentPlayer.pause()
listener?.onSleepTimerEnded(currentPlayer.currentPosition) listener?.onSleepTimerEnded(currentPlayer.currentPosition)
sleepTimerTask?.cancel() clearSleepTimer()
sleepTimerRunning = false
sleepTimerFinishedAt = System.currentTimeMillis() sleepTimerFinishedAt = System.currentTimeMillis()
} else if (sleepTimeSecondsRemaining <= 30) { } else if (sleepTimeSecondsRemaining <= 30) {
// Start fading out audio // Start fading out audio
@@ -1056,16 +1090,29 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
return true return true
} }
fun clearSleepTimer() {
sleepTimerTask?.cancel()
sleepTimerTask = null
sleepTimerEndTime = 0
sleepTimerRunning = false
// Unregister shake sensor after wake up expiration
shakeSensorUnregisterTask?.cancel()
shakeSensorUnregisterTask = Timer("ShakeUnregisterTimer", false).schedule(SLEEP_TIMER_WAKE_UP_EXPIRATION) {
Handler(Looper.getMainLooper()).post() {
Log.d(tag, "wake time expired: Unregistering shake sensor")
unregisterSensor()
}
}
}
fun getSleepTimerTime():Long? { fun getSleepTimerTime():Long? {
return sleepTimerEndTime return sleepTimerEndTime
} }
fun cancelSleepTimer() { fun cancelSleepTimer() {
Log.d(tag, "Canceling Sleep Timer") Log.d(tag, "Canceling Sleep Timer")
sleepTimerTask?.cancel() clearSleepTimer()
sleepTimerTask = null
sleepTimerEndTime = 0
sleepTimerRunning = false
listener?.onSleepTimerSet(0) listener?.onSleepTimerSet(0)
} }
@@ -1080,7 +1127,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
private fun checkShouldExtendSleepTimer() { private fun checkShouldExtendSleepTimer() {
if (!sleepTimerRunning) { if (!sleepTimerRunning) {
var finishedAtDistance = System.currentTimeMillis() - sleepTimerFinishedAt var finishedAtDistance = System.currentTimeMillis() - sleepTimerFinishedAt
if (finishedAtDistance > 120000) // 2 minutes if (finishedAtDistance > SLEEP_TIMER_WAKE_UP_EXPIRATION) // 2 minutes
{ {
Log.d(tag, "Sleep timer finished over 2 mins ago, clearing it") Log.d(tag, "Sleep timer finished over 2 mins ago, clearing it")
sleepTimerFinishedAt = 0L sleepTimerFinishedAt = 0L
@@ -1129,6 +1176,30 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
listener?.onSleepTimerSet(sleepTimerEndTime) listener?.onSleepTimerSet(sleepTimerEndTime)
} }
// Shake sensor used for sleep timer
private fun registerSensor() {
if (isShakeSensorRegistered) {
Log.w(tag, "Shake sensor already registered")
return
}
shakeSensorUnregisterTask?.cancel()
Log.d(tag, "Registering shake SENSOR ${mAccelerometer?.isWakeUpSensor}")
var success = mSensorManager!!.registerListener(
mShakeDetector,
mAccelerometer,
SensorManager.SENSOR_DELAY_UI
)
if (success) isShakeSensorRegistered = true
}
private fun unregisterSensor() {
if (!isShakeSensorRegistered) return
Log.d(tag, "Unregistering shake sensor")
mSensorManager!!.unregisterListener(mShakeDetector)
isShakeSensorRegistered = false
}
/* /*
CAST STUFF CAST STUFF
*/ */
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "audiobookshelf-app", "name": "audiobookshelf-app",
"version": "v0.9.29-beta", "version": "v0.9.30-beta",
"author": "advplyr", "author": "advplyr",
"scripts": { "scripts": {
"dev": "nuxt --hostname localhost --port 1337", "dev": "nuxt --hostname localhost --port 1337",