2

I'm messing around with broadcast receivers. I want to latch onto boot, screen on and screen off. If I set up one for boot up, it works fine:

In AndroidManifest.xml:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<application
    android:name=".MyApp"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" 

    <receiver
        android:name=".receivers.BootCompleteReceiver"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

    <receiver android:name=".receivers.ScreenOnReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_ON" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

    <receiver android:name=".receivers.ScreenOffReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.SCREEN_OFF" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

And the receiver:

class BootCompleteReceiver : BroadcastReceiver() {

    override fun onReceive(p0: Context, p1: Intent?) {
        if (p1?.action.equals(Intent.ACTION_BOOT_COMPLETED, true))
            Log.i(TAG, "Boot Time: %d".format(System.currentTimeMillis()))
    }
}

If I reboot my phone, I can see the boot time information in Logcat. Works as intended.

But, I have two more receivers, on for screen on and one for screen off, which don't behave the same.

The code:

Receivers:

class ScreenOnReceiver: BroadcastReceiver() {

    override fun onReceive(p0: Context, p1: Intent?) {
        if (p1?.action.equals(Intent.ACTION_SCREEN_ON, true))
            Log.i(TAG, "Screen On Time: %d".format(System.currentTimeMillis()))
    }
}

class ScreenOffReceiver: BroadcastReceiver() {

    override fun onReceive(p0: Context, p1: Intent?) {
        if (p1?.action.equals(Intent.ACTION_SCREEN_OFF, true))
            Log.i(TAG, "Screen Off Time: %d".format(System.currentTimeMillis()))
    }
}

MyApp:

private lateinit var screenOnReceiver: ScreenOnReceiver
private lateinit var screenOffReceiver: ScreenOffReceiver

override fun onCreate() {
    super.onCreate()

    val screenOnIntentFilter = IntentFilter(Intent.ACTION_SCREEN_ON)
    screenOnReceiver = ScreenOnReceiver()
    registerReceiver(screenOnReceiver, screenOnIntentFilter)

    val screenOffIntentFilter = IntentFilter(Intent.ACTION_SCREEN_OFF)
    screenOffReceiver = ScreenOffReceiver()
    registerReceiver(screenOffReceiver, screenOffIntentFilter)
}

These two will not log anything UNLESS I bring up the (already running) app (or rather its activity, which does nothing special) into focus once. Then they fire every time. HOW do I make sure the SCREEN_OFF and SCREEN_ON receivers are receiving right after the boot up?

EDIT: I noticed something! First, the declaration for the two screen receivers in AndroidManifest doesn't seem to affect the way the app works, so they can be commented out. Second, the receivers work after boot for as long as a keep flicking the screen on and off if I do it quick, then they... die or go to sleep until I bring the activity back in front.

MPelletier
  • 16,256
  • 15
  • 86
  • 137

0 Answers0