2012-03-18 66 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