0

我目前正在为我的 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" />
4

1 回答 1

-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 中注册您的 Service 和 Receiver,希望我有所帮助,如果不好请原谅我。

于 2013-06-25T22:05:21.090 回答