检查设备是否已插入

63
我的应用程序有一个广播接收器来监听 ACTION_POWER_CONNECTED 的更改,并进而标记屏幕以保持开启状态。
但是我缺少的是应用程序在首次运行时检查充电状态的能力。请问有谁可以帮我提供手动检查充电状态的代码?
9个回答

162

感谢CommonsWare,以下是我写的代码。

public class Power {
    public static boolean isConnected(Context context) {
        Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
    }
}

if (Power.isConnected(context)) {
    ...
}

或Kotlin版本

object Power {
    fun isConnected(context: Context): Boolean {
        val intent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
        val plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
        return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
    }
}

http://developer.android.com/training/monitoring-device-state/battery-monitoring.html


3
请勿忘记取消注册接收器。 - Jeffrey Blattman
3
@JeffreyBlattman这不是必要的,因为你实际上并没有在第一时间注册一个接收器。 - Tim
你正在调用 Context.registerReceiver(),那不是在注册接收器吗? - Jeffrey Blattman
你不需要向后兼容,因为BATTERY_PLUGGED_WIRELESS只是一个常量。 - SDJSK
如果设备没有电池,我们怎样知道设备是否已插入? - Samsad CV

33
public static boolean isPlugged(Context context) {
    boolean isPlugged= false;
    Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
    int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
    isPlugged = plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB;
    if (VERSION.SDK_INT > VERSION_CODES.JELLY_BEAN) {
        isPlugged = isPlugged || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
    }
    return isPlugged;
}

支持无线充电的小型更新。


29

调用registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED))。 这将返回一个带有在BatteryManager上定义的extras的Intent,以告诉您它是否已插入。

这能够工作是因为Intent.ACTION_BATTERY_CHANGED是一种黏性广播。


2
所以这样就无法立刻查询?你必须在应用程序中保持电池状态,并在接收到这些广播时更改它吗? - MattC
2
@MattC:“所以没有办法立即查询?”-- 是的。实际上,这正是我的答案告诉你如何完成的。 - CommonsWare
1
@MattC:你没有仔细阅读我的回答。请一直重复阅读,直到你注意到我并没有告诉你要注册BroadcastReceiver。我是在告诉你调用registerReceiver(),但第一个参数传入null。现在,如果这些数据可以在BatteryManager上简单获取,那当然很好,但正如我的回答所述,你绝对不需要注册BroadcastReceiver - CommonsWare
2
@MattC:“从设计角度来看,仍然似乎不够直观。”--毫无争议。每次我教这个点时,我的学生们都会发笑。在BatteryManager上的方法似乎是更合理的方法。但是,生活还要继续。 - CommonsWare
@commonsware:同意这不是很直观。然而,可能的观点是,如果您想要电池状态,您确实应该注册一个监听器。电池状态会发生变化。 - Robin Davies
显示剩余3条评论

14

在Android M及以上版本中,您可以通过getSystemService(BATTERY_SERVICE)使用BatteryManager服务。对于运行在M之前的设备,您可以像其他人提到的那样使用粘性广播。例如:

public static boolean isCharging(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        BatteryManager batteryManager = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
        return batteryManager.isCharging();
    } else {
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent intent = context.registerReceiver(null, filter);
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        if (status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL) {
            return true;
        }
    }
    return false;
}

我不明白为什么当电池状态为满时被认为是正在充电?当它充满100%然后你拔掉它会发生什么,如果仍然声明它正在充电,那不是错误的吗? - stuckedoverflow

6

你的答案在Android参考资料中!

这里是示例代码:

// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                 status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

5

一个简单的方法是使用意图过滤器ACTION_BATTERY_CHANGED

public void checkBatteryState(View sender) {
    IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    Intent batteryStatus = registerReceiver(null, filter);

    int chargeState = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
    String strState;

    switch (chargeState) {
        case BatteryManager.BATTERY_STATUS_CHARGING:
        case BatteryManager.BATTERY_STATUS_FULL:
            strState = "charging";
            break;
        default:
            strState = "not charging";
    }

    TextView tv = (TextView) findViewById(R.id.textView);
    tv.setText(strState);
}

1
未解决的引用:在 Kotlin 或 Java 中,registerReceiver 我该怎么办? - HandyPawan

3

试试这个:

public class PowerConnectionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

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


        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging =    status == BatteryManager.BATTERY_STATUS_CHARGING ||
                                status == BatteryManager.BATTERY_STATUS_FULL;

        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge   = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge    = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;


        if (batteryStatus != null) {
            int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            float batteryPct = level / (float) scale;
        }


    }//end onReceive


}//end PowerConnectionReceiver

2
BroadcastReceiver receiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        String action = intent.getAction();
        if(action.equalsIgnoreCase(ACTION_POWER_CONNECTED))
        {


                if(chargerConnected != null )
                {
                    chargerConnected.setText("Cable Connected");
                }
                if(chargerImage != null )
                {
                    chargerImage.setImageDrawable(getResources().getDrawable(R.drawable.usb));
                }

        }else if(action.equalsIgnoreCase(ACTION_POWER_DISCONNECTED))
        {


                if(chargerConnected != null )
                {
                    chargerConnected.setText("NOT CHARGE");
                }
                if(chargerImage != null )
                {
                    chargerImage.setImageDrawable(getResources().getDrawable(R.drawable.battery_icon));
                }

            try {

                Toast.makeText(context, "Power Cable Disconnected", Toast.LENGTH_SHORT).show();
            }catch (Exception e){e.printStackTrace();}

        }
    }
};

1
这是一个粘性意图,您无需注册BroadcastReceiver - 只需像下面的代码片段中所示调用registerReceiver并将接收器传递为null,即可返回当前电池状态意图。您可以在此处传递实际的BroadcastReceiver对象,但我们将在后面的部分处理更新,因此不必要。
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

你可以提取当前的充电状态,以及如果设备正在充电,则可以判断是通过USB还是AC充电器进行充电:
// Are we charging / charged?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                     status == BatteryManager.BATTERY_STATUS_FULL;

// How are we charging?
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;

BatteryManager会在设备连接或断开电源时广播一个动作。重要的是,即使您的应用程序没有运行,也应该接收到这些事件--特别是这些事件应该影响您启动应用程序以启动后台更新的频率--因此,您应该在清单中注册BroadcastReceiver来通过定义意图过滤器来监听这两个事件,即ACTION_POWER_CONNECTEDACTION_POWER_DISCONNECTED

<receiver android:name=".PowerConnectionReceiver">
  <intent-filter>
    <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
  </intent-filter>
</receiver>

在相关的BroadcastReceiver实现中,您可以提取当前的充电状态和方法,如前一步骤所述。

public class PowerConnectionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
                            status == BatteryManager.BATTERY_STATUS_FULL;

        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接