mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-09 05:18:40 +02:00
Fix:Sleep timer shake to wake up to work when screen is locked
This commit is contained in:
@@ -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
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user