androidQ(10.0) 读取蓝牙设备当前电量并显示

简介: androidQ(10.0) 读取蓝牙设备当前电量并显示

效果图


华为手机顶部状态栏


UCMBHf.png

我们客制化后最终效果


UCMJ4e.png


实现步骤


1、获取蓝牙设备连接成功后的电量值

2、跟踪蓝牙图标显示流程

3、制作蓝牙带电量图标

4、获取电量后显示对应电量值图标


文件修改清单

 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/ic_bluetooth_connected_super.xml                   
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_0.xml  
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_1.xml   
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_2.xml   
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_3.xml  
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_4.xml   
 vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/stat_sys_data_bluetooth_connected_battery_5.xml   
 vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java     


除了 PhoneStatusBarPolicy.java 之外其余都是新增蓝牙图标相关资源文件,资源文件不再贴出,可以去这里下载


资源文件选用 xml path 绘制,好处就是能跟随系统状态栏切换背景色,如果采用 png 图片将需要处理监听状态栏底色改变


读取已连接蓝牙设备电量值,在网上搜索后找到了一个工具类,简单试了下发现可用,通过反射调用 BluetoothDevice 的


getBatteryLevel 方法获取电量值

private  int getBluetoothDeviceBattery(){
        int battery = -1;
        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
        Class<BluetoothAdapter> bluetoothAdapterClass = BluetoothAdapter.class;
        try {
            Method method = bluetoothAdapterClass.getDeclaredMethod("getConnectionState", (Class[]) null);
            method.setAccessible(true);
            int state = (int) method.invoke(btAdapter, (Object[]) null);
            if (state == BluetoothAdapter.STATE_CONNECTED) {
                Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
                for (BluetoothDevice device : devices) {
                    Method batteryMethod = BluetoothDevice.class.getDeclaredMethod("getBatteryLevel", (Class[]) null);
                    batteryMethod.setAccessible(true);
                    Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected", (Class[]) null);
                    isConnectedMethod.setAccessible(true);
                    boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
                    int level = (int) batteryMethod.invoke(device, (Object[]) null);
                    if (device != null && level > 0 && isConnected) {
                        String deviceName = device .getName();
                        battery = level;
                        android.util.Log.i(TAG, "Connected Bluetooth="+deviceName + "  battery="+level);
                    }
                }
            } else {
                android.util.Log.e(TAG, "No Connected Bluetooth Devices Found");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            return battery;
        }
    }

电量值为 -1 说明蓝牙设备不支持读取电量


其实后来通过跟踪系统蓝牙连接界面显示电量值逻辑,最终找到的也是调用此方法获取电量


frameworks\base\packages\SettingsLib\src\com\android\settingslib\bluetooth\CachedBluetoothDevice.java


 /**
     * Return summary that describes connection state of this device. Summary depends on:
     * 1. Whether device has battery info
     * 2. Whether device is in active usage(or in phone call)
     *
     * @param shortSummary {@code true} if need to return short version summary
     */
    public String getConnectionSummary(boolean shortSummary) {
        boolean profileConnected = false;    // Updated as long as BluetoothProfile is connected
        boolean a2dpConnected = true;        // A2DP is connected
        boolean hfpConnected = true;         // HFP is connected
        boolean hearingAidConnected = true;  // Hearing Aid is connected
        int leftBattery = -1;
        int rightBattery = -1;
    .....
     String batteryLevelPercentageString = null;
        // Android framework should only set mBatteryLevel to valid range [0-100] or
        // BluetoothDevice.BATTERY_LEVEL_UNKNOWN, any other value should be a framework bug.
        // Thus assume here that if value is not BluetoothDevice.BATTERY_LEVEL_UNKNOWN, it must
        // be valid
        final int batteryLevel = getBatteryLevel();
        if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
            // TODO: name com.android.settingslib.bluetooth.Utils something different
            batteryLevelPercentageString =
                    com.android.settingslib.Utils.formatPercentage(batteryLevel);
        }
        int stringRes = R.string.bluetooth_pairing;
        //when profile is connected, information would be available
        if (profileConnected) {
            // Update Meta data for connected device
            if (BluetoothUtils.getBooleanMetaData(
                    mDevice, BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) {
                leftBattery = BluetoothUtils.getIntMetaData(mDevice,
                        BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY);
                rightBattery = BluetoothUtils.getIntMetaData(mDevice,
                        BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY);
            }
    ......
}
 /**
     * Get battery level from remote device
     * @return battery level in percentage [0-100], or {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
     */
    public int getBatteryLevel() {
  //android.bluetooth.BluetoothDevice  mDevice;
        return mDevice.getBatteryLevel();
    }

通过跟踪发现控制蓝牙图标显示代码在 PhoneStatusBarPolicy.java 中,只有当蓝牙设备连接成功后蓝牙图标才会显示,


默认用的资源文件为 stat_sys_data_bluetooth_connected.xml,我们就可以在这块做调整,当蓝牙设备连接成功后读取电量值,


根据电量值获取对应电池格数资源文件就ok了。


vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java

 @Override
    public void onBluetoothStateChange(boolean enabled) {
        updateBluetooth();
    }
    private final void updateBluetooth() {
        //int iconId = R.drawable.stat_sys_data_bluetooth_connected;
        int iconId = R.drawable.ic_bluetooth_connected_super;//cczheng change
        String contentDescription =
                mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
        boolean bluetoothVisible = false;
        if (mBluetooth != null) {
            if (mBluetooth.isBluetoothConnected()) {
                contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
                bluetoothVisible = mBluetooth.isBluetoothEnabled();
            }
        }
        //20200602 cczheng add
        if (bluetoothVisible) {
            int battery = getBluetoothDeviceBattery();
            if (battery > 0) {
                iconId = getBatteryLevelIconId(battery);
            }
        }//E
        mIconController.setIcon(mSlotBluetooth, iconId, contentDescription);
        mIconController.setIconVisibility(mSlotBluetooth, bluetoothVisible);
    }
    //20200602 cczheng add for show bt headset battery S
    private int getBatteryLevelIconId(int battery){
        int iconId = 0;
        if (battery <= 10) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_0;
        }else if (battery <= 20) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_1;
        }else if (battery <= 40) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_2;
        }else if (battery <= 60) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_3;
        }else if (battery <= 80) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_4;
        }else if (battery <= 100) {
            iconId = R.drawable.stat_sys_data_bluetooth_connected_battery_5;
        }
        Log.e(TAG, "iconId="+iconId);
        return iconId;
    }
    private  int getBluetoothDeviceBattery(){
        int battery = -1;
        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
        Class<BluetoothAdapter> bluetoothAdapterClass = BluetoothAdapter.class;
        try {
            Method method = bluetoothAdapterClass.getDeclaredMethod("getConnectionState", (Class[]) null);
            method.setAccessible(true);
            int state = (int) method.invoke(btAdapter, (Object[]) null);
            if (state == BluetoothAdapter.STATE_CONNECTED) {
                Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
                for (BluetoothDevice device : devices) {
                    Method batteryMethod = BluetoothDevice.class.getDeclaredMethod("getBatteryLevel", (Class[]) null);
                    batteryMethod.setAccessible(true);
                    Method isConnectedMethod = BluetoothDevice.class.getDeclaredMethod("isConnected", (Class[]) null);
                    isConnectedMethod.setAccessible(true);
                    boolean isConnected = (boolean) isConnectedMethod.invoke(device, (Object[]) null);
                    int level = (int) batteryMethod.invoke(device, (Object[]) null);
                    if (device != null && level > 0 && isConnected) {
                        String deviceName = device .getName();
                        battery = level;
                        android.util.Log.i(TAG, "Connected Bluetooth="+deviceName + "  battery="+level);
                    }
                }
            } else {
                android.util.Log.e(TAG, "No Connected Bluetooth Devices Found");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            return battery;
        }
    }
    //20200602 cczheng add for show bt headset battery E
    private final void updateTTY() {
        TelecomManager telecomManager =
                (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
        if (telecomManager == null) {
            updateTTY(TelecomManager.TTY_MODE_OFF);
        } else {
            updateTTY(telecomManager.getCurrentTtyMode());
        }
    }

参考文章


Android 10 获取已连接的蓝牙设备的当前电量

Android7.0 获取蓝牙设备电量

目录
相关文章
|
7月前
win10 蓝牙开关消失 设备管理器“设备描述符请求失败”
win10 蓝牙开关消失 设备管理器“设备描述符请求失败”
155 1
win10 蓝牙开关消失 设备管理器“设备描述符请求失败”
|
开发框架 JSON 物联网
Nanoframework 操作单片机蓝牙配置WIFI的案例
通过`Nanoframework`的蓝牙配置Wifi的名称和密码
146 0
|
小程序 API Android开发
微信小程序使用蓝牙通信协议连接硬件整理总结(蓝牙连接、获取设备UUID、开水器notify及关闭蓝牙)
微信小程序使用蓝牙通信协议连接硬件整理总结(蓝牙连接、获取设备UUID、开水器notify及关闭蓝牙)
3700 0
微信小程序使用蓝牙通信协议连接硬件整理总结(蓝牙连接、获取设备UUID、开水器notify及关闭蓝牙)
|
Java 开发工具 Android开发
利用MCU实现制作一台蓝牙控制小车方法
今天主要和大家分享一下,如何使用MCU自己做一台蓝牙小车,并通过自己写的APP进行控制。
254 0
利用MCU实现制作一台蓝牙控制小车方法
|
Ubuntu Linux C语言
用C写蓝牙通讯程序:扫描、读取、发送
在Linux下,通过bluez 蓝牙库可以用C语言轻松实现蓝牙通信。在ubuntu下可以用 apt-get install libbluetooth-dev 安装该库。下面是几个简单示例。
2178 0
|
物联网 定位技术 Android开发
【错误记录】BLE 蓝牙搜索失效 ( 关闭了 GPS 定位导致的问题 | 蓝牙串口工具推荐 )
【错误记录】BLE 蓝牙搜索失效 ( 关闭了 GPS 定位导致的问题 | 蓝牙串口工具推荐 )
330 0
【错误记录】BLE 蓝牙搜索失效 ( 关闭了 GPS 定位导致的问题 | 蓝牙串口工具推荐 )
|
搜索推荐 物联网 大数据
蓝牙信标对体育场馆的商业活动的影响
由于其底层技术,信标的物理覆盖范围限制在100米左右,但它们在室内和室外都能很好地工作。它们的主要吸引力在于价格低廉,而且它们可以在商场、音乐厅和体育场等商业场所充当客户参与工具。
318 1
蓝牙信标对体育场馆的商业活动的影响
|
C#
C# 获得设备usb信息
原文:C# 获得设备usb信息 本文告诉大家如何获得设备的usb来进行判断是否有哪些usb和找不到usb可能是什么。 需要在项目右击引用,点击程序集,搜索 System.
1691 0

热门文章

最新文章