2011-06-28 30 views
7

我可以在我的活動中聽取Intent 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> 

,但它沒有工作,我讀了在這裏說,它必須以編程定義一個職位。我不想在我的活動中註冊接收者,而是希望在服務中實現此目的,以便持續監控。我已經成功實現了這一目標,並且工作正常,但我想檢查我的工作,看看它是否是正確的方法。

我開始通過延長廣播接收器:

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

@Darshan!你能否在答案中加上你的答案,而不是問題,因爲現在它很混亂。 –

+0

@ShajeelAfzal我不明白。這是我的答案。我的回答是,在一些失誤之後,Bear提出的方法在問題中提出的方法確實是一種類似於我在生產中使用了七年的方法。 –