Android: Sleep and wake device with Alarm Manager

Viewed 16

I have installed my application as a system app on an android TV box. My goal is to be able to put the device to sleep and wake, or reboot, at specific times

I am currently using two alarms - one that puts the device to sleep, while the other should be waking or rebooting the device.

I am having no problem individually powering the device off using powerManager.reboot(reason: "quiescent") or rebooting the device using powerManager.reboot(reason: null) (even after powering the device off using the remote).

My problem is when rebooting the device once is has been put to sleep using the reboot "quiescent" method. Below is my approach.

Registering Receivers

registerReceiver(sleepAlarmReceiver, IntentFilter("intent_sleep_alarm"))

registerReceiver(wakeAlarmReceiver, IntentFilter("intent_wake_alarm"))

Creating Alarms Using 1 & 3 minutes elapsed time for testing

    private fun createSleepTimer() {
        // our receiver to put the device to sleep.
        val sleepIntent = Intent("intent_sleep_alarm")
        val sleepId = 123;

        sleepAlarmIntent = PendingIntent.getBroadcast(this, sleepId, sleepIntent, PendingIntent.FLAG_UPDATE_CURRENT)

        // put our device to sleep in 1 minutes
        alarmMgr?.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime()+60*1000*1, sleepAlarmIntent)

    }

    private fun createWakeTimer() {
        // our receiver to boot up the device
        val wakeId = 456;
        val wakeIntent = Intent("intent_wake_alarm")
        wakeAlarmIntent = PendingIntent.getBroadcast(this, wakeId, wakeIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        // set an alert to wake up the device in 3 minutes
        alarmMgr?.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime()+60*1000*3, wakeAlarmIntent)

    }

Creating Wake Locks

        val powerManager = getSystemService(POWER_SERVICE) as PowerManager
        partialWakeLock = powerManager.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "SLEEP: PARTIAL WAKE LOCK"
        )
        fullWakeLock = powerManager.newWakeLock(
            PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.FULL_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
            "SLEEP: FULL WAKE LOCK"
        )
    }

Partial wake lock on pause

override fun onPause() {
        super.onPause()
        partialWakeLock.acquire()
    }

Receivers

    private val wakeAlarmReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
           fullWakeLock.acquire()
            val pManager = getSystemService(POWER_SERVICE) as PowerManager
            try {
                // passing null as a reason reboots the device      
                pManager.reboot(null)
            } catch (e: IllegalAccessException) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show()
                e.printStackTrace()
            } catch (e: InvocationTargetException) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show();
                e.printStackTrace()
            } catch (e: NoSuchMethodError) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show();
                e.printStackTrace()
            }
        }
    }

    private val sleepAlarmReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val pManager = getSystemService(POWER_SERVICE) as PowerManager
            try {
                // passing 'quiescent' as a reason turns powers the device off       
                pManager.reboot("quiescent")
            } catch (e: IllegalAccessException) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show()
                e.printStackTrace()
            } catch (e: InvocationTargetException) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show();
                e.printStackTrace()
            } catch (e: NoSuchMethodError) {
                val toast = Toast.makeText(applicationContext, e.cause.toString(), Toast.LENGTH_LONG)
                toast.show();
                e.printStackTrace()
            }
        }
    }
1 Answers

why don't you use workmanager?

https://developer.android.com/topic/libraries/architecture/workmanager

WorkManager is the recommended solution for persistent work. Work is persistent when it remains scheduled through app restarts and system reboots. Because most background processing is best accomplished through persistent work, WorkManager is the primary recommended API for background processing.

Related