2012-03-18 67 views
2

我有一個執行後臺更新的服務。禁用電池百分比更新

我想讓用戶在電池電量達到一定水平時禁用更新。

從我的研究,我會在我的服務類的onCreate方法使用一個接收器,例如:

public class MainService extends Service 
{ 
    @Override 
    public void onCreate() 
    {  
     this.registerReceiver(this.BatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 
    } 

    private BroadcastReceiver BatInfoReceiver = new BroadcastReceiver(){ 
     @Override 
     public void onReceive(Context arg0, Intent intent) { 
      int level = intent.getIntExtra("level", 0); 
    } 
    }; 
} 

我假設,最好的做法是離開服務運行,請檢查服務中的電池電量,而不是根據百分比執行CPU密集型代碼?

我實際上並不需要停止服務本身,並根據電池的百分比重新啓動服務?

UPDATE:

這似乎是一個更好的解決方案,但不是100%肯定。我在AndroidManifest註冊的BroadcastReceiver

<receiver android:name="BatteryReceiver" /> 

然後創建一個BroadcastReceiver:

public class BatteryReceiver extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive(final Context context, final Intent intent) 
    {  
     final int currentBatteryPercent = intent.getIntExtra("level", 0); 
     final int disableBatteryPercent = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString("batteryPercent", 0); 

     //AlarmReceiver is the service that performs the background updates 
     final ComponentName component = new ComponentName(context, AlarmReceiver.class); 

     if (currentBatteryPercent < disableBatteryPercent) 
     { 
      context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED , PackageManager.DONT_KILL_APP); 
     } 
     else 
     { 
      context.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED , PackageManager.DONT_KILL_APP); 
     } 
     } 
} 

回答

2

這是正確的。你通常會做的是安排一些廣播意圖的更新(也許通過一個AlarmManager)。當您收到電池電量不足的通知時,您可以將其存放在您的服務中,然後在更新之前檢查以確保電池電量不會太低。 here是觀看電池電量的好教程。在處理這個意圖時,你不應該做太多的事情,只要把電池水平放在某個地方,並且(在進行更新之前)確保它已經適當地「充滿」了。

您的更新是一個真正的不好的停止應用程序的方法。一般來說,要求軟件包管理器停止你的組件比解決方案更具破壞性。相反,您應該將一些代碼移到實際進行更新的組件中,並在那裏存儲/更新電池信息的信息。在進行更新之前,請檢查電池電量,並且不要繼續操作,除非它處於適合更新應用程序的水平。使用廣播接收器是好的,但您需要將該級別存儲在某處(可能是sharedprefs)。相反,這就是爲什麼將接收器放在您進行更新的服務中可能是最好的。

+0

謝謝,只是需要一些驗證。 – 2012-03-18 17:49:59

+0

我提出包管理器的唯一原因是基於這個問題,這是由Android Framework工程師之一回答的:http://stackoverflow.com/questions/2782448/android-how-to-start-a -service-at-boot-based-on-user-settings/3465986雖然這可能不是一回事,因爲這個問題是關於在啓動時禁用服務,而不是在某個電池級別? – 2012-03-18 18:48:45

+0

是的,你不應該真的使用上下文來阻止你的應用程序中的組件,這讓我覺得非常糟糕的做法和哈克。 (殺掉東西,即使它不殺死應用程序,總是很可怕,並導致一些粘性行爲)。一個更清潔的解決方案是將該級別存儲在AlarmManager中的某個地方,這實際上是進行更新的地方,這是(在我看來)迄今爲止最乾淨的方式。 – 2012-03-18 18:53:46

1

是否有可能使用broadcastReceiver管理此需求,而不是連續運行服務?

public void onReceive(final Context context, final Intent intent) { 

      if(intent != null && intent.getAction() != null) { 
        String action = intent.getAction(); 

        if(action.equals(Intent.ACTION_BOOT_COMPLETED)) { 
          // Set alarm 
        } 
        else if(action.equals(Intent.ACTION_BATTERY_LOW)) { 
          setLocationAlarmReceiverEnabled(context, false); 
        } 
        else if(action.equals(Intent.ACTION_BATTERY_OKAY)) { 
          setLocationAlarmReceiverEnabled(context, true); 
        } 
      } 
    } 
+0

除非您持有喚醒鎖,否則您不應該擔心服務「持續」運行,因此它們之間的調度和對CPU的影響應該沒有什麼區別。 – 2012-03-18 17:59:14

+0

感謝您的信息kristopher。 – Pavandroid 2012-03-18 18:13:03

+0

其實,這似乎比運行該服務更清潔。 – 2012-03-18 18:13:18