【问题标题】:BroadcastReceiver stopped working from time to time in my service, why?BroadcastReceiver 在我的服务中不时停止工作,为什么?
【发布时间】:2011-04-21 16:56:35
【问题描述】:

我现在正在为 Android 编写电池小部件。但问题来了,我在服务中注册了两个 BroadcastReceiver。我在 AppWidgetProvider 的 onEnable() 方法上启动我的服务,然后在 onDisable() 中停止它。该服务旨在侦听电池状态更新和方向更改,并通过将我的自定义 Intent 发送到我的 AppWidgetProvider 来通知小部件进行自我更新。因为普通的 AppWidgetProvider 都无法接收到广播(battery_state_changed 和 configuration_changed),而 AppWidgetProvider 本身也无法注册 BroadcastReceivers。

在一两天内一切正常。但有时,当电池状态发生变化时,小部件没有自行更新,似乎我的服务中的接收器没有工作,或者自定义 Intent 突然停止成功到达我的 AppWidgetProvider。

知道为什么会这样吗?

package com.carllee.widgets.kittenbatterywidget;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

public class BatteryStateMoniterService extends Service {
    private static final String TAG = "BatteryStateMoniterService";
    private BatteryStateReceiver batteryStateReceiver;
    private OrientationChangeReceiver orientationChangeReceiver;

    @Override
    public void onCreate() {
        super.onCreate();
        Logger.log(TAG, "onCreate");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (batteryStateReceiver == null) {
            this.unregisterReceiver(batteryStateReceiver);
        }
        if (orientationChangeReceiver == null) {
            this.unregisterReceiver(orientationChangeReceiver);
        }
        Logger.log(TAG, "onDestroy");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (batteryStateReceiver == null) {
            registerBatteryStateReceiver();
        }

        if (orientationChangeReceiver == null) {
            registerOrientationChangeReceiver();
        }
        Logger.log(TAG, "onStartCommand");
        return START_STICKY;
    }

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

    private void registerBatteryStateReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        filter.addAction(Intent.ACTION_BATTERY_LOW);
        filter.addAction(Intent.ACTION_BATTERY_OKAY);
        batteryStateReceiver = new BatteryStateReceiver();
        this.registerReceiver(batteryStateReceiver, filter);
    }

    private void registerOrientationChangeReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        orientationChangeReceiver = new OrientationChangeReceiver();
        this.registerReceiver(orientationChangeReceiver, filter);
    }

}

【问题讨论】:

    标签: android service android-widget broadcastreceiver


    【解决方案1】:

    好吧,首先,声明:

        if (batteryStateReceiver == null) {
            this.unregisterReceiver(batteryStateReceiver);
        }
        if (orientationChangeReceiver == null) {
            this.unregisterReceiver(orientationChangeReceiver);
        }
    

    没有任何意义。您每次都会收到NullPointerException。将== 更改为!= ;)

    另外,请参阅my post about keeping background services alive.

    在后台长时间运行(非必要)调用startForeground() 的复杂服务示例。但是,它仍然可以被系统或用户杀死。

    【讨论】:

    • 是的,谢谢,但是 startForeground() 需要一个 Notification 作为参数,这将在状态栏中发出通知(如果我没记错的话),应用小部件没有意义每次将其添加到启动器时都会发出通知。有没有更好的解决方案来阻止我的服务被杀死?还是我应该将 null 传递给 startForeground()?或者有什么方法可以阻止通知显示在状态栏中?
    • 您好,我找到了一个解决方案,似乎可行,不确定是否可行,我仍在测试中。解决方案是调用“setForeground(true);” ,这会将服务设置为前台,而​​不会在状态栏中显示任何消息。
    猜你喜欢
    • 1970-01-01
    • 2015-01-17
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2021-11-23
    相关资源
    最近更新 更多