2011-06-28 14 views
7

私は自分のアクティビティでインテントIntent.ACTION_BATTERY_CHANGEDを聞くことができます。私はそれがプログラムで定義されなければならないことを言って、ここにポストを読んで、Android BroadcastReceiver android.intent.action.BATTERY_CHANGED

<receiver android:name="com.beargreaves.battery.BatteryReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.BATTERY_CHANGED" /> 
    </intent-filter> 
</receiver> 

が、それはうまくいきませんでした:私は、マニフェストに受信機を定義してみました。アクティビティにレシーバを登録するのではなく、サービスでこれを達成して、継続的にモニタするようにしたかったのです。私はこれを成功裏に達成していますが、それが正しいアプローチであるかどうかを確認するために作業を確認したかったのです。

私はBroadcastReceiverを拡張することで開始しました:

public class BatteryReceiver extends BroadcastReceiver{ 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Bundle bundle = intent.getExtras(); 

     if(null == bundle) 
      return; 

     boolean isPresent = intent.getBooleanExtra("present", false); 
     String technology = intent.getStringExtra("technology"); 
     int plugged = intent.getIntExtra("plugged", -1); 
     int scale = intent.getIntExtra("scale", -1); 
     int health = intent.getIntExtra("health", 0); 
     int status = intent.getIntExtra("status", 0); 
     int rawlevel = intent.getIntExtra("level", -1); 
     int level = 0; 

     Log.d("Debug","Battery Receiver OnReceive"); 

     if(isPresent) { 
      if (rawlevel >= 0 && scale > 0) { 
       level = (rawlevel * 100)/scale; 

       Log.d("Debug","BatterReceiver: " + level); 

       Toast.makeText(context,"Battery Receiver: " + level + "\t" + status + "Raw: " + rawlevel,Toast.LENGTH_LONG).show(); 

       if(level <60) { 
        /* 
        * Only invoke the service when level below threshold 
        */ 
        Intent i = new Intent(context, BatteryService.class); 
        i.putExtra("level", level); 
        context.startService(i); 
       } 
      } 
     } 
    } 
} 

そして私は最初onCreate()に受信機を登録してonStart()でイベントを処理するためのサービスを使用しています。レベルがしきい値を下回っている場合、私のBroadcastReceiverはサービスを開始します。

public class BatteryService extends Service { 
    /* 
    * First Call to onStart we don't want to do anything 
    */ 
    boolean avoidFirst = false; 
    private BroadcastReceiver receiver; 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
     receiver = new BatteryReceiver(); 
     registerReceiver(receiver, filter); 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     Log.d("Debug","Battery Service On Start"); 
     int level = intent.getIntExtra("level", -1); 

     if(avoidFirst) { 
      if(level != -1) { 
       Log.d("Debug","Battery Alert Notifying..... " + level); 
       SMSManager.sendSMS(BatteryService.this, "<number redacted>", "Battery Level Aleart: " + level); 
       stopSelf(); 
      } 
     } else { 
      avoidFirst = true; 
     } 
    } 

    @Override 
    public void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
     PreferenceUtil.updatePreference(BatteryService.this, "battery_monitor_on", false); 
     unregisterReceiver(receiver); 
    } 
} 

これは正しい方法ですか?受信者をonCreate()に登録してから、イベントが受信されたときにサービスを開始してください。まずはサービスを使わないようにしてみましたが、マニフェストでは達成できないため、受信機を登録する方法がありません。次に、onReceive()でテキストメッセージを送信しようとしたときに例外がスローされました。私はonReceive()がどのスレッドも開始してはならないと読んでいます。

ありがとうございます。

+0

+1あなたの質問に私の答えを入れて:D –

答えて

2

はい、非常に良いアプローチのようです。それは私のアプリでやっていること(これは長年にわたりうまくいっている)よりもかなり似ています(実際にはいくぶん優れています)。

+0

あなたの答えに多くのありがとう。 – Bear

+1

@ダルシャン!今はかなり混乱しているので、あなたの答えを質問ではなく答えに加えてください。 –

+0

@ShajeelAfzal私は分かりません。これは私の答えです。私の答えは、問題に提示されたアプローチが、実際に私が7年間の生産で使用したアプローチに似た適切なものである、いくつかの誤解を抱えた後にBearが来たというアプローチでした。 –

関連する問題