ANDROID中在应用程序未运行时,屏幕开/关的广播接收器

6

我希望对屏幕关闭和打开事件进行检测,因此我创建了BroadcastReceiver。只有当应用程序在运行时才能正常工作,当我从任务管理器中删除应用程序时,它就不能正常工作。

活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try{
        BroadcastReceiver myrcver  = new BootReceiver();
        IntentFilter screenStateFilter = new IntentFilter();
        screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
        screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(myrcver, screenStateFilter);
    }
    catch (Exception e){
        e.fillInStackTrace();
    }
}

清单文件:

<receiver
        android:name=".BootReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.SCREEN_OFF" />
            <action android:name="android.intent.action.SCREEN_ON" />
        </intent-filter>
    </receiver>

广播接收器:

public class BootReceiver extends BroadcastReceiver {
boolean screenOff;
@Override
public void onReceive(Context context, Intent intent) {
    try {
        if ("android.intent.action.SCREEN_ON".equals(intent.getAction())) {
            if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                screenOff = true;
            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                screenOff = false;
            }
            Intent i = new Intent(context, UpdateService.class);
            i.putExtra("screen_state", screenOff);
            context.startService(i);
        }
    }
    catch (Exception e){
        e.fillInStackTrace();
    }
}

感谢您的帮助。

提前感谢您的帮助。


1
"只有当应用程序正在运行时才能正常工作,当我从任务管理器中删除应用程序时,它就无法工作" -- 正确的。这些广播只会传递给使用 registerReceiver() 的正在运行的进程。 - CommonsWare
3个回答

7
如果你想让应用程序在后台运行即使应用程序没有运行,你需要创建一个服务。 在服务类中,你需要将其注册到你的接收器中。
public class ScreenOnOffService extends Service {

    private ScreenOnOffReceiver mScreenReceiver;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        registerScreenStatusReceiver();
    }

    @Override
    public void onDestroy() {
        unregisterScreenStatusReceiver();
    }

    private void registerScreenStatusReceiver() {
        mScreenReceiver = new ScreenOnOffReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(Intent.ACTION_SCREEN_ON);
        registerReceiver(mScreenReceiver, filter);
    }

    private void unregisterScreenStatusReceiver() {
        try {
            if (mScreenReceiver != null) {
                unregisterReceiver(mScreenReceiver);
            }
        } catch (IllegalArgumentException e) {}
    }
}

创建服务类后,不要忘记将你的服务添加到清单文件中:
<service android:name="com.myapp.services.ScreenOnOffService" />

然后,在您的主活动中可以编写以下内容以启动服务:

Intent intent = new Intent(this, ScreenOnOffService.class);
startService(intent);

针对广播课程:

public class ScreenOnOffReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.d("StackOverflow", "Screen Off");

        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Log.d("StackOverflow", "Screen On");
        }
    }
}

注意: 对于我来说,在清单文件中设置 screen offscreen on无效的,只有在运行时才有效。


感谢您的帮助,但我已经尝试过这个方法了。当应用程序关闭时,它不起作用。 - Sanat Chandravanshi
你记得在AndroidManifest中注册服务了吗? <service android:name="com.myapp.services.ScreenOnOffService" /> - CookieMonster
是的,我已经注册了它。 - Sanat Chandravanshi
我已经在我的回答中添加了更多细节。我不确定为什么它对你不起作用,但我在这里写的代码可以正常运行。请确保你的服务正在运行。此外,像你所做的那样在清单文件中创建接收器并不能让我成功。只有当我通过编程方式添加意图过滤器时,才能接收到广播。 - CookieMonster

4
有点晚了,但可能会对某人有帮助。按照上面 @CookieMonster 的提及操作,然后在启动你的服务 ScreenOnOffService 时,像这样做:
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(new Intent(this, ScreenOnOffService.class));
    } else {
        startService(new Intent(this, ScreenOnOffService.class));
    }

在您的ScreenOnOffService的onCreate() 方法中,粘贴以下代码。
if (Build.VERSION.SDK_INT >= 26) {
        String CHANNEL_ID = "your_channel_id";
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                "Notification Channel Title",
                NotificationManager.IMPORTANCE_DEFAULT);

        ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("")
                .setContentText("").build();

        startForeground(1, notification);
    }

现在运行您的应用程序。它将按预期工作。

谢谢,这对于支持 Android Oreo 之后的版本非常重要。 - Abdulrahman Abdelkader

-2

如果您在清单文件中添加了" wake.lock "权限,则广播接收器可以在应用程序未运行时运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接