Android - как получить трансляцию намерений 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
устанавливается просто плюнуть foo в журналы. Ничего не делает. Любые предложения, пожалуйста? Нужно ли назначать какие-либо разрешения, чтобы поймать намерение?
6 ответов
Я считаю, что эти действия могут быть получены только получателями, зарегистрированными в коде Java (через registerReceiver()
), а не через получателей, зарегистрированных в манифесте.
В качестве альтернативы вы можете использовать менеджер питания для обнаружения блокировки экрана.
@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...
}
}
"android.intent.action.HEADSET_PLUG"
"android.intent.action.ACTION_SCREEN_ON"
"android.intent.action.ACTION_SCREEN_OFF"
Три из них выше, они не могут зарегистрироваться с помощью манифеста. Ядро Android добавило к ним "Intent.FLAG_RECEIVER_R определ_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;
}
}
Я реализовал это путем регистрации получателя в моей основной деятельности в 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);
А потом на Дестрой ():
unregisterReceiver(lockScreenReceiver);
В приемнике вы должны поймать следующие случаи:
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
}
}
}
}
Новая клавиша действия обновлена!
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
</intent-filter>
Вот котлинская версия @cmcromance (спасибо за ваш ответ. Пожалуйста, не забудьте проголосовать за исходный ответ)
private var mPowerKeyReceiver: BroadcastReceiver? = null
private fun registBroadcastReceiver() {
val theFilter = IntentFilter()
/** System Defined Broadcast */
theFilter.addAction(Intent.ACTION_SCREEN_ON)
theFilter.addAction(Intent.ACTION_SCREEN_OFF)
mPowerKeyReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.e("onReceive", "onReceive called")
val strAction = intent!!.action
// if (strAction == Intent.ACTION_SCREEN_OFF || strAction == Intent.ACTION_SCREEN_ON) {
if (strAction == Intent.ACTION_SCREEN_ON) {
// > Your playground~!
Log.e("strAction", strAction)
val intent = Intent(context, SplashScreenMainAppActivity::class.java)
startActivity(intent)
}
}
}
applicationContext.registerReceiver(mPowerKeyReceiver, theFilter)
}
private fun unregisterReceiver() {
val apiLevel = Build.VERSION.SDK_INT
if (apiLevel >= 7) {
try {
applicationContext.unregisterReceiver(mPowerKeyReceiver)
} catch (e: IllegalArgumentException) {
mPowerKeyReceiver = null
}
} else {
applicationContext.unregisterReceiver(mPowerKeyReceiver)
mPowerKeyReceiver = null
}
}