【问题标题】:Get battery level before broadcast receiver responds for Intent.ACTION_BATTERY_CHANGED在广播接收器响应 Intent.ACTION_BATTERY_CHANGED 之前获取电池电量
【发布时间】:2010-09-07 18:21:47
【问题描述】:

我的程序中有一个广播接收器,可以像这样对电池电量做出反应:

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

    registerReceiver(this.mBatInfoReceiver, 
            new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

但是,此代码必须等待电池状态更新,因此如果您有一个需要根据电池电量设置的 GUI 元素,则它必须等待电池事件发生。有没有办法让它工作或简单地运行一些代码来查看上次广播时的电池电量?

【问题讨论】:

    标签: android broadcastreceiver battery


    【解决方案1】:

    这是在不注册接收器的情况下获取电池电量的方法:

    Intent batteryIntent = context.getApplicationContext().registerReceiver(null,
                        new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    int rawlevel = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
    double scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    double level = -1;
    if (rawlevel >= 0 && scale > 0) {
        level = rawlevel / scale;
    }
    

    由于广播的粘性,它可以使用 null BroadcastReceiver。

    它使用 getApplicationContext() 技巧,以防您在意图接收器中并获得异常:

    android.content.ReceiverCallNotAllowedException: IntentReceiver 组件不是 允许注册接收 意图

    【讨论】:

    • 在某些情况下(如在系统服务中运行),getApplicationContext() 将返回 null。在这种情况下,调用应该是: context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    • @hemisphire 写道“在某些情况下(例如在系统服务中运行),getApplicationContext() 将返回 null”。我不认为这总是正确的。也许这取决于服务的类型。
    • 完美!我现在可以在没有服务的情况下做到这一点。
    • 我很确定这是从 BroadcastReceiver 中访问电池信息的唯一方法,而不会收到 ReceiverCallNotAllowedException。感谢您提供有用的提示! :)
    【解决方案2】:

    有没有办法轻推它以使其工作或简单地运行一些代码来查看电池电量 最后一次广播?

    您可以使用您的IntentFilternull BroadcastReceiver 致电registerReceiver() 以获取最后一次广播Intent。这是因为ACTION_BATTERY_CHANGED 是所谓的“粘性广播”,我在this StackOverflow question-and-answer 中对此进行了更多描述。

    【讨论】:

    • 我在问题中的接收器实际上在创建后立即被调用,我只是没有注意到,因为我在它之后重新初始化了变量。
    • 如下所述获取 applicationContext 以进行此调用会导致问题吗?我的问题是我的广播接收器不允许注册意图,即使我传入 null。这个问题的正确解决方案是什么?
    • @Mayra: getApplicationContext() 在这里应该没问题,特别是如果您尝试从BroadcastReceiver 执行此操作。
    【解决方案3】:
        public static String batteryLevel(Context context)
        {
            Intent intent  = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));   
            int    level   = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
            int    scale   = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
            int    percent = (level*100)/scale;
            return String.valueOf(percent) + "%";
        }
    

    【讨论】:

      【解决方案4】:
      // Put this Code into your MainActivity
      
      private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context c, Intent i) {
              int level = i.getIntExtra("level", 0);
              ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
              pb.setProgress(level);
              TextView tv = (TextView) findViewById(R.id.textfield);
              tv.setText("Battery Level: " + Integer.toString(level) + "%");
          }
      
      };
      
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
          registerReceiver(mBatInfoReceiver, new IntentFilter(
                  Intent.ACTION_BATTERY_CHANGED));
      }
      

      【讨论】:

      • 我可能还需要在 onPause 取消注册时取消接收此接收器,但这会产生错误 01-11 15:08:21.711: E/AndroidRuntime(31730): Caused by: java.lang.IllegalArgumentException :接收器未注册:com.example.batterylevel.ChargeActivity$1@426304a0
      【解决方案5】:

      我使用这种方法在不接收更新的情况下获取电池电量。

      public float getMyBatteryLevel() {
              Intent batteryIntent = this.getApplicationContext().registerReceiver(null,
              new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
              return batteryIntent.getIntExtra("level", -1);
      }
      

      【讨论】:

        【解决方案6】:

        请注意,您从 registerReceiver 调用中获得的意图

        Intent intent  = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        

        可以为空。所以请在使用意图之前进行检查,例如

        if(intent != null){ 
        // do your stuff here... 
        }
        

        我刚刚遇到空指针异常,导致应用崩溃!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-31
          相关资源
          最近更新 更多