服务中的广播接收器在一段时间后停止工作

时间:2013-06-17 22:03:41

标签: android service widget broadcastreceiver broadcast

我目前正在为我的Android设备制作自制电池小部件。 它只是和ImageView以及TextView以百分比显示电池电量。

实际上一切正常但除了不知何故经过一段时间(如1小时,可能是2)后,我用来收听电池更换的广播接收器停止工作,我的UI不再以正确的百分比级别更新。可能是什么原因造成的?

此外,我发现即使接收器停止接收并且UI不再更新,服务仍在运行。

这是我的小部件类:

public class BatteryWidgetHD extends AppWidgetProvider {
private static BatteryController bctrl;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    if(bctrl == null) bctrl = new BatteryController(context, appWidgetManager, appWidgetIds);

    Log.i("BatteryWidgetHD", "OnUpdate... starting service...");

    Intent batteryServiceIntent = new Intent(context.getApplicationContext(), BatteryMonitoringService.class);

    context.getApplicationContext().startService(batteryServiceIntent); 
}

/**
 * service that keeps the broadcastreceiver alive that listens for battery changes
 * @author philipp
 *
 */
public static class BatteryMonitoringService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {    

        if(bctrl != null) bctrl.listenToBatteryStatus();
    }

    @Override
    public void onDestroy() {

        if(bctrl != null) bctrl.stopListeningToBatteryStatus();
    }

}
}

我的电池控制器类,有一个广播接收器并更新用户界面onReceive():

public class BatteryController {

private int status, level;
private boolean isCharging, isUSBPlugged, isACPlugged;

private Context c;

private BatteryStatusReceiver bsr;
private RemoteViews remoteViews;
private AppWidgetManager appWidgetManager;
private ComponentName thisWidget;

/** constructor 
 * @param appWidgetManager */
public BatteryController(Context c, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

    this.c = c;
    this.appWidgetManager = appWidgetManager;

    remoteViews = new RemoteViews(c.getPackageName(), R.layout.battery_widget_layout);
    thisWidget = new ComponentName(c, BatteryWidgetHD.class);

    bsr = new BatteryStatusReceiver();
}

/**
 * start listening to broadcasts concerning the battery
 */
public void listenToBatteryStatus() {

    IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
    c.getApplicationContext().registerReceiver(bsr, ifilter);   

    getStartupBatteryLevel();
}

/**
 * stop listening to battery broadcasts
 */
public void stopListeningToBatteryStatus() {

    c.getApplicationContext().unregisterReceiver(bsr);
}

private void updateUI() {

    remoteViews.setTextViewText(R.id.tvBatteryLevel, "\n" + level + "%");

    appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}

/**
 * this class is responsible for listening to broadcasts concerning the
 * battery status
 */
private class BatteryStatusReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) { 

        status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);

        isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;

        int isPlugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);

        isUSBPlugged = isPlugged == BatteryManager.BATTERY_PLUGGED_USB;
        isACPlugged = isPlugged == BatteryManager.BATTERY_PLUGGED_AC;

        // inform the UI about battery changes
        updateUI();
        Log.i("BatteryController", "BATTERY STATUS CHANGED. Level: " + level + ", Charging: " + isCharging);
       // Toast.makeText(c, "Battery status changed.", Toast.LENGTH_SHORT).show();
    }
}
}

还有widget_provider.xml

    <?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/battery_widget_layout"
    android:minHeight="100dip"
    android:minWidth="60dip"
    android:previewImage="@drawable/battery75"
    android:widgetCategory="keyguard|home_screen"
    android:updatePeriodMillis="0" />

1 个答案:

答案 0 :(得分:-2)

我很抱歉,但我只为您试一试,尝试让您的服务成为前台,以便系统不会杀死它并在此处完美处理它的代码将其设置为前景:

NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    Intent bIntent = new Intent(this, urmainactivity.class);       
    PendingIntent pbIntent = PendingIntent.getActivity(this, 0, bIntent,0);

    NotificationCompat.Builder bBuilder =
            new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("write the title")
                .setContentText("write subtitle")
                .setAutoCancel(true)
                .setOngoing(true)
                .setContentIntent(pbIntent);
    Notification barNotif = bBuilder.build();
    this.startForeground(1, barNotif);

并且接收器尝试使其触发服务,因为当你这样做时,接收器应保持与前台服务一样活跃。并且这样做......:

Intent i = new Intent(context, urService.class);
context.startService(i);

不要忘记在Manifest中注册您的服务和您的Receiver,希望我帮助,如果不能原谅我。

相关问题