web-dev-qa-db-fra.com

Android - comment recevoir des intentions de diffusion ACTION_SCREEN_ON / OFF?

    <application>
         <receiver Android:name=".MyBroadcastReceiver" Android:enabled="true">
                <intent-filter>
                      <action Android:name="Android.intent.action.ACTION_SCREEN_ON"></action>
                      <action Android:name="Android.intent.action.ACTION_SCREEN_OFF"></action>
                </intent-filter>
         </receiver>
...
    </application>

MyBroadcastReceiver est défini juste pour cracher foo aux journaux. Ne fait rien. Des suggestions s'il vous plait? Dois-je attribuer des autorisations pour saisir l'intention?

62
ohnoes

Je crois que ces actions ne peuvent être reçues que par des récepteurs enregistrés dans Java (via registerReceiver()) plutôt que via des récepteurs enregistrés dans le manifeste.

68
CommonsWare

Vous pouvez également utiliser le gestionnaire d'alimentation pour détecter le verrouillage de l'écran.

@Override
protected void onPause()
{
    super.onPause();

    // If the screen is off then the device has been locked
    PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
    boolean isScreenOn;
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat_WATCH) {
        isScreenOn = powerManager.isInteractive();
    } else {
        isScreenOn = powerManager.isScreenOn();
    }

    if (!isScreenOn) {

        // The screen has been locked 
        // do stuff...
    }
}
28
Robert
"Android.intent.action.HEADSET_PLUG"
"Android.intent.action.ACTION_SCREEN_ON"
"Android.intent.action.ACTION_SCREEN_OFF"

Trois d'entre eux ci-dessus, ils ne peuvent pas s'inscrire en utilisant le manifeste. Android core a ajouté "Intent.FLAG_RECEIVER_REGISTERED_ONLY" à eux (peut-être .. J'ai vérifié les codes uniquement dans le cas de "HEADSET_PLUG").

Donc, nous devons utiliser "registre dynamique". Comme ci-dessous ...

private BroadcastReceiver mPowerKeyReceiver = null;

private void registBroadcastReceiver() {
    final IntentFilter theFilter = new IntentFilter();
    /** System Defined Broadcast */
    theFilter.addAction(Intent.ACTION_SCREEN_ON);
    theFilter.addAction(Intent.ACTION_SCREEN_OFF);

    mPowerKeyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String strAction = intent.getAction();

            if (strAction.equals(Intent.ACTION_SCREEN_OFF) || strAction.equals(Intent.ACTION_SCREEN_ON)) {
                // > Your playground~!
            }
        }
    };

    getApplicationContext().registerReceiver(mPowerKeyReceiver, theFilter);
}

private void unregisterReceiver() {
    int apiLevel = Build.VERSION.SDK_INT;

    if (apiLevel >= 7) {
        try {
            getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
        }
        catch (IllegalArgumentException e) {
            mPowerKeyReceiver = null;
        }
    }
    else {
        getApplicationContext().unregisterReceiver(mPowerKeyReceiver);
        mPowerKeyReceiver = null;
    }
}
27
cmcromance

La façon dont j'ai implémenté cela est en enregistrant le récepteur dans mon activité principale dans onCreate (), il suffit de définir le récepteur quelque part à l'avance:

    lockScreenReceiver = new LockScreenReceiver();
    IntentFilter lockFilter = new IntentFilter();
    lockFilter.addAction(Intent.ACTION_SCREEN_ON);
    lockFilter.addAction(Intent.ACTION_SCREEN_OFF);
    lockFilter.addAction(Intent.ACTION_USER_PRESENT);
    registerReceiver(lockScreenReceiver, lockFilter);

Et puis onDestroy ():

    unregisterReceiver(lockScreenReceiver);

Dans le récepteur, vous devez attraper les cas suivants:

public class LockScreenReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if (intent != null && intent.getAction() != null)
        {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON))
            {
                // Screen is on but not unlocked (if any locking mechanism present)
            }
            else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF))
            {
                // Screen is locked
            }
            else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT))
            {
                // Screen is unlocked
            }
        }
    }
}
6
box