2013-06-17 2 views
0

В настоящее время я работаю над самодельным виджэном для моего устройства Android. Его просто и ImageView и TextView отображают уровень заряда батареи в процентах.Широковещательный приемник внутри службы перестает работать через некоторое время

Все работает нормально, за исключением того, что через некоторое время (например, 1 час, возможно, 2) передатчик, использующий для прослушивания изменений батареи, перестает работать, и мой пользовательский интерфейс больше не обновляется с правильным процентным уровнем. Что может быть причиной этого?

Кроме того, я узнал, что даже когда приемник прекращает прием, и пользовательский интерфейс больше не обновляется, служба все еще работает.

Вот мой класс виджета:

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(); 
    } 

} 
} 

И мой класс batterycontroller, который имеет BroadcastReceiver и обновляет пользовательский интерфейс 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" /> 
+0

Я считаю, что в документации говорится, что если ваш цикл обновления составляет менее 30 минут, вам нужно использовать AlarmManager –

+0

Это действительно так, но мне не нужен цикл обновления. Мне просто нужно, чтобы onUpdate вызывается один раз. Где-то я читал, что это может быть достигнуто путем установки updatePeriodMillis на 0. –

+0

Я столкнулся с этой проблемой прямо сейчас, вы решили это? – SalutonMondo

ответ

-2

Извините, но у меня есть только попробовать, попробуйте сделать свой сервисный план так, чтобы t шляпа система не будет убивать его и справиться с ней всё время прекрасно здесь, код, чтобы установить его на переднем плане:

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); 

не забудьте зарегистрировать свою службу и ваш приемник в манифесте ,,, надеюсь, что я помог, если не так, простите меня.

Смежные вопросы