12

さて、バッテリー レベルをチェックして TextView に表示する AppWidget に取り組んでいます。私のコードは次のようになります。

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

そして、ウィジェットをホーム画面にドロップするとすぐに、ACTION_BATTERY_CHANGED を受信して​​いると言って、1 秒間に約 100 のログ呼び出しを開始するので、私は心配しています。これって、減るごとに放送するだけじゃないの?実際、ランチャー全体が遅くなったため、アンインストールする必要がありました。それは正しくありません。

4

2 に答える 2

24

私のコードは次のようになります。

BroadcastReceiver別の から を登録して、BroadcastReceiver信頼できる結果を得ることはできません。Android は何も実行されていないと判断するため、プロセスを終了します。willをリッスンする唯一の方法ACTION_BATTERY_CHANGEDは、アクティビティまたはサービスからそのレシーバーを登録することです。

これは減るごとに放送されるだけじゃないの?

それはどこで文書化されていますか?私の知るACTION_BATTERY_CHANGED限り、ハードウェアが気に入ったときはいつでも放送されます。Intentまた、温度など、その中で他のデータが変更されることに注意してください。

このアプリ ウィジェットを実装する場合は、そのまま登録しないでACTION_BATTERY_CHANGEDください。その代わり:

  • ユーザーがポーリング期間を選択できるようにしますSharedPreference(例: 1 分に 1 回、15 分に 1 回)。
  • AlarmManagerを介してそのポーリング期間を制御するために使用しますgetBroadcast() PendingIntent
  • その中で、 for をBroadcastReceiver呼び出しますが、BroadcastReceiverを使用します。これは、そのアクションに対して最後にブロードキャストされたものを返すためです (注: これには引き続き使用する必要があります) 。registerReceiver()ACTION_BATTERY_CHANGED nullIntentgetApplicationContext()
  • AppWidgetManager前の手順で取得したバッテリー レベルでアプリ ウィジェット インスタンスを更新するために使用しますIntent(注: すべてを同じに設定する場合は、ID を反復処理する必要はありません。updateAppWidget()aComponentNameをパラメーターとして)

これにはいくつかの利点があります。

  1. ACTION_BATTERY_CHANGEDどのくらいの頻度で放送されるかは気にしません
  2. ユーザーは、これらのチェックを行うことで消費するバッテリーの量を制御できます (ポーリング期間を 1 分以上に保つ場合は無視できるはずです)。
  3. ポーリングの合間にプロセスを安全に終了できるため、ユーザーがタスク キラーで攻撃してアプリを半永久的に台無しにする可能性が低くなります。
于 2011-10-02T12:25:45.750 に答える