Android 在广播接收器响应 Intent.ACTION_BATTERY_CHANGED 之前获取电池电量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3661464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:13:48  来源:igfitidea点击:

Get battery level before broadcast receiver responds for Intent.ACTION_BATTERY_CHANGED

androidbroadcastreceiverbattery

提问by stealthcopter

I have a broadcast receiver in my program to get react to the battery level like so:

我的程序中有一个广播接收器可以对电池电量做出反应,如下所示:

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));

However this code has to wait for the battery status to be updated so if you have a GUI element that needs to be set based on the battery level it must wait for a battery event to occur. Is there a way to nudge this to get it working or simply run some code to see what the battery level was on the last broadcast?

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

采纳答案by CommonsWare

Is there a way to nudge this to get it working or simply run some code to see what the battery level was on the last broadcast?

有没有办法推动它使其正常工作,或者只是运行一些代码来查看上次广播时的电池电量?

You can call registerReceiver()with your IntentFilterand a nullBroadcastReceiverto get the last-broadcast Intent. This works because ACTION_BATTERY_CHANGEDis a so-called "sticky broadcast", which I describe a bit more in this StackOverflow question-and-answer.

您可以registerReceiver()使用 yourIntentFilter和 a调用nullBroadcastReceiver以获取最后一次广播Intent。之所以有效,ACTION_BATTERY_CHANGED是因为它是所谓的“粘性广播”,我在此 StackOverflow 问答中对其进行了更多描述。

回答by isdal

This is how to get the battery level without registering a receiver:

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

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;
}

It can use a null BroadcastReceiver because of the sticky nature of the broadcast.

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

It uses the getApplicationContext() trick in case you are in a intent receiver and get the exception:

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

android.content.ReceiverCallNotAllowedException: IntentReceiver components are not allowed to register to receive intents

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

回答by XXX

    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) + "%";
    }

回答by Hiren Patel

// 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));
}

回答by Jorgesys

I use this method to get the battery level without receiving updates.

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

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

回答by Johan

Please be aware, that the intent you get from registerReceiver call

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

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

can be null. So please make a check before using the intent, e.g.

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

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

I just got a null pointer exception, causing the app to crash!

我刚刚得到一个空指针异常,导致应用程序崩溃!