2011-10-02 29 views
12

好的,所以我正在研究一個AppWidget,它檢查電池電量並將其顯示在TextView上。我的代碼如下所示:ACTION_BATTERY_CHANGED像瘋了似的射擊

public class BattWidget extends AppWidgetProvider { 

private RemoteViews views = new RemoteViews("com.nickavv.cleanwidgets", R.layout.battlayout); 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetIds[]) { 
    final int N = appWidgetIds.length; 
    context.getApplicationContext().registerReceiver(this,new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
    for (int i = 0; i < N; i++) { 
     int appWidgetId = appWidgetIds[i]; 
     appWidgetManager.updateAppWidget(appWidgetId, views); 
    } 
} 

@Override 
public void onReceive(Context context, Intent intent) { 
    super.onReceive(context, intent); 
    Log.d("onReceive", "Received intent " + intent); 
    if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { 
     Integer level = intent.getIntExtra("level", -1); 
     views.setTextViewText(R.id.batteryText, level+"%"); 
     AppWidgetManager myAWM = AppWidgetManager.getInstance(context); 
     ComponentName cn = new ComponentName(context, AirWidget.class); 
     onUpdate(context, myAWM, myAWM.getAppWidgetIds(cn)); 
    } 
} 
} 

而且我越來越感到擔心,因爲只要我把小部件到主屏幕我就開始發射了那些記錄呼叫第二的100,說這是接收ACTION_BATTERY_CHANGED。這不是隻應該爲每降低百分比播放嗎?它實際上導致我的整個啓動器滯後,我不得不卸載它。這是不對的。

+0

不知道什麼關於這個,但它是值得建立一個服務來監視電池,並以預定的時間間隔反饋給widgit? – mAndroid

回答

23

我的代碼如下所示:

不能註冊從另一個BroadcastReceiver一個BroadcastReceiver並獲得可靠的結果。 Android將終止您的流程,因爲它不認爲任何內容正在運行。傾聽ACTION_BATTERY_CHANGED的唯一方法是從活動或服務註冊該接收者。

這是不是隻應該播放每降低百分之?

你在哪裏看到記錄? AFAIK,ACTION_BATTERY_CHANGED只要硬件感覺就會播出。另外,請記住,其他數據在該溫度範圍內發生變化,例如溫度。

如果你想實現這個應用程序的小部件,請不要註冊ACTION_BATTERY_CHANGED你的方式。相反:

  • 允許用戶通過SharedPreference(例如,,一分鐘一次,每次時間爲15分鐘一次)
  • 使用AlarmManager給你上通過getBroadcast()PendingIntent
  • 輪詢週期在這種BroadcastReceiver控制,呼叫registerReceiver()ACTION_BATTERY_CHANGED但有null廣播接收器,因爲這將返回給你的最後一個Intent這是該行動廣播(注:你仍然需要使用getApplicationContext()此)
  • 使用AppWidgetManager與電池電量來更新您的應用程序控件實例拉出Intent你在前面的檢索步驟(注意:如果要設置他們都一樣,你並不需要遍歷的標識 - 使用需要ComponentName作爲參數updateAppWidget()

這有幾個優點:

  1. 你不在乎多久ACTION_BATTERY_CHANGED廣播
  2. 用戶得到控制多少你的電池消耗做這些檢查
  3. (如果保持輪詢週期到一分鐘或更多的應該是可以忽略不計)你過程可以安全地終止因此使得用戶不太可能用任務殺手來攻擊你,並且半永久性地搞亂你的應用程序
+2

這不是最好的方式去做這件事。我發現很多閉源電池小部件會在發生變化時立即更新其信息(BattStatt就是一個很好的例子)。我從來沒有見過一個提供更新間隔的用戶。電池級別小部件應該始終準確。 – Nick

+1

@尼克:「這不是最好的方式去做這件事 - 」你有權發表你的意見。 「我發現很多閉源電池小部件會在發生變化時立即更新信息」 - 他們通過將內存保存在內存中來浪費大量內存。用戶認爲這樣做的開發人員是白癡,爲什麼爲什麼任務殺手如此受歡迎,操作系統必須主動殺掉這些服務。 – CommonsWare

+0

@Nick:「電池電量小部件應該始終準確無誤」 - 由於電池電量不會特別頻繁地變化,因此輪詢體系結構的精度可能遠遠不夠,同時避免了RAM的打擊以及保持周圍服務的固有不可靠性每時每刻。 – CommonsWare

0

那麼,你的onUpdate將它自己的類註冊爲batteryinfo意圖的接收者。這個意圖然後立即觸發第一個信息。你的onReceive再次調用你的onUpdate。我們稱之爲一個循環。因此,每秒100個日誌...