Android - 如何接收广播意图ACTION_SCREEN_ON/OFF?

ohn*_*oes 63 android broadcast

    <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>
Run Code Online (Sandbox Code Playgroud)

MyBroadcastReceiver设置只是为了向日志吐出foo.什么也没做.有什么建议吗?我是否需要分配任何权限来捕获意图?

Com*_*are 68

我相信这些行为只能由在Java代码(via registerReceiver())中注册的接收者接收,而不是通过清单中注册的接收者接收.

  • 对于他们真的不想启动新进程的情况,Android似乎不支持清单注册的接收器.例如,您将看到与电池信息操作相同的效果(例如,BATTERY_LOW).除此之外,我没有太多理由 - 我没有写它.:-) (20认同)
  • @CommonsWare 那么当按下电源按钮时我如何注册Receiver()? (2认同)

Rob*_*ert 28

或者,您可以使用电源管理器来检测屏幕锁定.

@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...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 只是想补充一点,虽然这对于99%的情况很有效,但在特定情况下这实际上可能会失败.在可以非常快速地打开和关闭屏幕的设备(例如Galaxy S4)中,您可以通过将其与proximityLock结合来检查此行为是否失败.如果触发锁定以关闭屏幕并快速重新打开,isScreenOn将在onPause()中实际返回true. (3认同)
  • 使用“PowerManager”方法+1 如果有人不想使用“BroadcastReceiver”,则非常好 (2认同)

cmc*_*nce 26

"android.intent.action.HEADSET_PLUG"
"android.intent.action.ACTION_SCREEN_ON"
"android.intent.action.ACTION_SCREEN_OFF"
Run Code Online (Sandbox Code Playgroud)

其中三个,他们无法使用Manifest注册.Android核心向他们添加了"Intent.FLAG_RECEIVER_REGISTERED_ONLY"(也许..我只检查了代码"HEADSET_PLUG").

所以,我们应该使用"动态寄存器".如下......

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;
    }
}
Run Code Online (Sandbox Code Playgroud)


box*_*box 6

我实现这个的方法是在onCreate()的主要活动中注册接收器,只需事先在某处定义接收器:

    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);
Run Code Online (Sandbox Code Playgroud)

然后onDestroy():

    unregisterReceiver(lockScreenReceiver);
Run Code Online (Sandbox Code Playgroud)

在接收器中,您必须捕获以下情况:

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)