2016-07-15 110 views
2

所有的拳頭我嘗試了所有我發現在stackoverflow和非工作的方法。Android BroadcastReceiver沒有更新Widget

我正在開發一個電池監控應用程序,它包含一些小部件來顯示信息。我使用一個名爲BatteryUpdateReceiver的普通接收器來收聽ACTION_BATTERY_CHANGED事件。我使用這個接收器來更新顯示當前電池電量的小部件。但由於某些原因,它不會更新小部件。我嘗試了很多方法,但無法弄清楚什麼是錯的。我的代碼如下。

BatteryUpdateReceiver.java

public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { 
      Log.i(TAG, "Receiver ACTION_BATTERY_CHANGED fired"); 

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
        R.layout.widget); 

      AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context.getApplicationContext()); 
      ComponentName thisWidget = new ComponentName(context.getApplicationContext(), BatteryWidget.class); 
      int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); 
      for (int i=0; i < allWidgetIds.length; i++) { 
       Log.i(TAG, "WID ID: " + allWidgetIds[i]); 
       appWidgetManager.updateAppWidget(allWidgetIds[i], remoteViews); 
      } 
     } 
    } 

BatteryWidget.java

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     super.onUpdate(context, appWidgetManager, appWidgetIds); 

     Log.i(TAG, "onUpdate: "); 

     int currentLevel = calculateBatteryLevel(context); 
     if (batteryChanged(currentLevel)) { 
      batteryLevel = currentLevel; 
      Log.i(TAG, "onUpdate: Battery level changed"); 
     } 
     updateViews(context); 
    } 

    private boolean batteryChanged(int currentLevelLeft) { 
     return (batteryLevel != currentLevelLeft); 
    } 

    private int calculateBatteryLevel(Context context) { 
     Log.i(TAG, "calculateBatteryLevel: "); 

     Intent batteryIntent = context.getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 

     int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); 
     int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100); 
     return level * 100/scale; 
    } 

    private void updateViews(Context context) { 
     Log.i(TAG, "updateViews: "); 

     RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); 
     views.setTextViewText(R.id.batteryText, batteryLevel + "%"); 

     ComponentName componentName = new ComponentName(context, BatteryWidget.class); 
     AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
     appWidgetManager.updateAppWidget(componentName, views); 
    } 

的AndroidManifest.xml

<receiver android:name=".lib.receivers.BatteryUpdateReceiver" android:enabled="true" /> 

    <receiver android:name=".widget.BatteryWidget" android:label="@string/app_name" > 
     <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
     </intent-filter> 
     <meta-data 
        android:name="android.appwidget.provider" android:resource="@xml/batterywidgetinfo" /> 
    </receiver> 

當設備啓動時,我使用服務註冊BatteryUpdateReceiver。

IntentFilter filterBattery = new IntentFilter(); 
filterBattery.addAction(Intent.ACTION_BATTERY_CHANGED); 
this.mBatteryStatusReceiver = new BatteryUpdateReceiver(); 
getApplicationContext().registerReceiver(this.mBatteryStatusReceiver, filterBattery); 
Log.i(TAG, "Receiver ACTION_BATTERY_CHANGED registered by Service"); 

我可以確認BatteryUpdateReceiver的工作原理是因爲它記錄了窗口小部件ID。另外,如果我將在BatteryWidget內部放置一個接收器,那麼該小部件會更新。有人能告訴我我在這裏錯過了什麼嗎?我知道我可以在BatteryWidget類中覆蓋onReceive()方法。但是,我怎樣才能以這種方式存檔它?

謝謝!

回答

3

您應該從您的接收器發送ACTION_APPWIDGET_UPDATE廣播,而不是直接呼叫updateAppWidget()

事情是這樣的:

@Override 
public void onReceive(Context context, Intent intent) { 
    AppWidgetManager widgetManager = AppWidgetManager.getInstance(getApplicationContext()); 
    int[] appWidgetIds = widgetManager.getAppWidgetIds(new ComponentName(context, BatteryWidget.class)); 

    Intent updateIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, getApplicationContext(), BatteryWidget.class); 
    updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds); 

    sendBroadcast(updateIntent); 
} 
+0

哇噢!它正在工作。保存了我的一天。謝謝!。 –

+0

不客氣:) – earthw0rmjim