IOS/Android 读取蓝牙设备电量信息
使用系统API扫描到蓝牙设备:
IOS使用到的framework
     1.CoreBluetooth/CoreBluetooth.h
Android使用到的framework
     1.android.bluetooth.BluetoothAdapter
     2.android.bluetooth.BluetoothDevice
     3.android.bluetooth.BluetoothManager
蓝牙默认广播中是不会带有电量信息的,但是可以通过定制蓝牙硬件的方式,手动添加额外信息ServiceData,然后使用IOS/Android原生的API扫描蓝牙广播数据,并根据自己定义的协议对其进行解析便可得到蓝牙电量信息。
IOS 代码示例
- ( void )centralManager:( CBCentralManager *)central didDiscoverPeripheral:( CBPeripheral *)peripheral advertisementData:( NSDictionary < NSString *, id > *)advertisementData RSSI:( NSNumber *)RSSI {
    NSArray *keys = [advertisementData allKeys ];
    for ( int i = 0 ; i < [keys count ]; ++i) {
        id key = [keys objectAtIndex : i];
        NSString *keyName = ( NSString *) key;
        NSObject *value = [advertisementData objectForKey : key];
        if ([value isKindOfClass : [ NSArray class ]]) {
            printf ( "key01: %s\n" , [keyName cStringUsingEncoding : NSUTF8StringEncoding ]);
            NSArray *values = ( NSArray *) value;
            for ( int j = 0 ; j < [values count ]; ++j) {
                if ([[values objectAtIndex : j] isKindOfClass : [ CBUUID class ]]) {
                    CBUUID *uuid = [values objectAtIndex : j];
                    NSData *data = uuid. data ;
                    printf ( "UUID(%d):" , j);
                    for ( int j = 0 ; j < data. length ; ++j)
                        printf ( " %2X" , (( UInt8 *) data. bytes )[j]);
                    printf ( "\n" );
                } else {
                    const char *valueString = [[value description ] cStringUsingEncoding : NSUTF8StringEncoding ];
                    printf ( "      value(%d): %s\n" , j, valueString);
                }
            }
        } else {
            const char *valueString = [[value description ] cStringUsingEncoding : NSUTF8StringEncoding ];
           
            if ([keyName isEqualToString : @"kCBAdvDataServiceData" ]) {
                NSString *string = [ NSString stringWithUTF8String :valueString];
                [ self checkAndAddNewDevice :string];
            }
            NSLog ( @"   key02: %s, value: %@\n" , [keyName cStringUsingEncoding : NSUTF8StringEncoding ], [ NSString stringWithUTF8String :valueString]);
        }
    }
}
// 解析广播包
- ( void )checkAndAddNewDevice:( NSString *)serverData {
    void (^CallBack)() = ^(){
        if ( self . delegate && [ self . delegate respondsToSelector : @selector (updateDataSources:)]) {
            [ self . delegate updateDataSources : _bleArray ];
        }
        self . status = ( self . bleArray && self . bleArray . count > 0 ) ? BLEStatus_Gotit : BLEStatus_NoDevices ;
        if ( self . delegate && [ self . delegate respondsToSelector : @selector (didScannerStatusChanged:)]) {
            [ self . delegate didScannerStatusChanged : _status ];
        }
    };
    BLEModel *newModel = [ self bluetoothServerDataAnalyzer :serverData];
    BOOL exist = false ;
    if (! newModel) return ;
    if (! _bleArray )  _bleArray = [ NSMutableArray new ];
    for ( BLEModel *model in _bleArray ) {
        if ([model. b_mac isEqualToString :newModel. b_mac ])
            exist = true ;
    }
    if (!exist) {
        [ _bleArray addObject :newModel];
        CallBack();;
    }
}

- ( BLEModel *)bluetoothServerDataAnalyzer:( NSString *)serverData {
    BLEModel *model = nil ;
    if (!serverData) {
        return nil ;
    }
    if ([serverData containsString : @" = " ] && [serverData containsString : @"<" ] && [serverData containsString : @">" ]) {
        NSArray *array = [serverData componentsSeparatedByString : @" = " ];
        if (array. count == 2 ) {
            NSString *data = array[ 1 ];
            data = [data stringByTrimmingCharactersInSet :[ NSCharacterSet whitespaceAndNewlineCharacterSet ]];
            data = [data stringByReplacingOccurrencesOfString : @" " withString : @"" ];
            if (data. length == 21 ) {
                NSString *body = [data substringWithRange : NSMakeRange ( 1 , data. length - 5 )];
                NSString *b_version = [body substringWithRange : NSMakeRange ( 0 , 2 )];
                NSString *b_bettery = [body substringWithRange : NSMakeRange ( 2 , 2 )];
                NSString *b_mac     = [body substringWithRange : NSMakeRange ( 4 , body. length - 4 )];
                model = [[ BLEModel alloc ] init :b_version bettery :b_bettery mac :b_mac];
//                NSLog(@" 版本 :%@ 电量 :%@ mac:%@", model.b_version, model.b_bettery, model.b_mac);
            }
        }
    }
    return model;

}

Android 代码示例
    /**
     * 扫描设备
     *
     * @param enable
     */
    private void scanLeDevice( boolean enable) {
        if (enable) {
            mHandler.postDelayed( new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    invalidateOptionsMenu();
                }
            }, SCAN_PERIOD); // 在搜索时间内,关闭搜索标志,不对搜索回调函数进行响应
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
        Logger.error(TAG, " 是否开始扫描 =" + enable);
        invalidateOptionsMenu();
    }

// Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan( final BluetoothDevice device, int rssi, byte [] scanRecord) {
            final IBeaconClass.IBeacon ibeacon = IBeaconClass.fromScanData(device, rssi, scanRecord);
            if (ibeacon == null ) return ;
            try {
                String strTemp = StringUtil.bytesToHexString(scanRecord);
                Logger.error(TAG, strTemp.length() + "= 长度,回调方法 -onLeScan()=" + strTemp); //0201061aff4c000215fda50693a4e24fb1afcfc6eb07647825000a0007c5090942523531343633310b1642523d6400cdff003ab100000000000000000000
                if (!TextUtils.isEmpty(strTemp)) {
                    String usefulData = strTemp.substring( 86 , 106 ); //4252 3d6400cdff003a9e
                    Logger.error(TAG, usefulData.length() + "= 长度,回调方法 -onLeScan() 截取有用数据 usefulData=" + usefulData);
//                String serviceID1 = usefulData.substring(2);
//                    String serviceID = usefulData.substring(2, 4);
//                    if (serviceID.equals("52")) {
                        String strVersion = usefulData.substring( 4 , 6 );
                        int intVersion = Integer.parseInt(strVersion, 16 );
                        String strPower = usefulData.substring( 6 , 8 );
                        int intPower = Integer.parseInt(strPower, 16 );
                        Logger.error(TAG, strVersion + "=strVersion 回调方法 -onLeScan() ,版本值 intVersion=" + intVersion);
                        Logger.error(TAG, strPower + "=strPower 回调方法 -onLeScan() ,电量值 intPower=" + intPower);
                        if (intPower > 0 ) {
                            ibeacon.version = intVersion;
                            ibeacon.power = intPower;
                            runOnUiThread( new Runnable() {
                                @Override
                                public void run() {
                                    adapter.addDevice(ibeacon);
                                }
                            });

}
//                    }
                }
            } catch (Exception e) {
                Logger.error(TAG, " 解析蓝牙数据出错 =" + e);
            }
        }

    };


IOS/Android 读取蓝牙设备电量信息相关推荐

  1. android主动获取手机电量,获取Android手机的电量信息

    电池的电量是手机用户为关心问题之一,而在Android系统中,专门提供了一个取得电池电量信息的Action--ACTION_BATTERY_CHANGED,在此Action中定义了许多附加信息的名称和 ...

  2. Android之手机电池电量应用

    原理概述: 手机电池电量的获取在应用程序的开发中也很常用,Android系统中手机电池电量发生变化的消息是通过Intent广播来实现的,常用的Intent的Action有  Intent.ACTION ...

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

    效果图 华为手机顶部状态栏 我们客制化后最终效果 实现步骤 1.获取蓝牙设备连接成功后的电量值 2.跟踪蓝牙图标显示流程 3.制作蓝牙带电量图标 4.获取电量后显示对应电量值图标 文件修改清单 ven ...

  4. Android中获取手机电量信息

    有些时候我们需要在我们的应用上为用户展示当前手机的电量,这时候我们就需要用到广播了,我们都知道在动态注册广播的时候,我们需要传入一个BroadcastReceiver类对象,还有一个意图过滤器Inte ...

  5. Android中通过Exifinterface读取图片地理位置信息

    效果图: 一.了解Exif EXIF(Exchangeable Image File)是"可交换图像文件"的缩写,是一种图像文件格式,它的数据存储与JPEG格式是完全相同的,当中包 ...

  6. android 读取U盘apk文件信息,拔掉U盘导致进程被杀

    最近一直在搞appStore,之前一直都是从网络获取apk下载进行安装,现在车机要求需要支持从U 盘安装apk,本以为简单很容易的事,却一不小心掉了一个坑里,爬了好久,主要是没很明显的报错,没遇到过的 ...

  7. Android NFC源码读取公交卡信息余额和交易记录

    通过NFC的读模式,读取公交卡的余额和交易记录.可以读取深圳通.羊城通.北京卡.八达通.武汉通等. 源码亲测可用放心下载. 源码下载Eclipse版本:Android NFC源码读取公交卡信息余额和交 ...

  8. Android手机 通过NFC读取二代证信息

    Android手机 通过NFC读取二代证信息 APK安装包和源码链接 代码示例 本文推荐一个安卓手机通过NFC读取二代证的SDK,目前市面上已经很多通过云解析来读取二代证的SDK,但是都有一个通病:对 ...

  9. 机甲Android on ios,全球首款iOS+Android双系统硬件机甲震撼上市

    原标题:全球首款iOS+Android双系统硬件机甲震撼上市 2016年7月20日,专为苹果打造的高端智能外设--机甲在北京震撼发布.这款全球首创的iOS/Android秒级切换双系统一举颠覆iOS和 ...

  10. 浅谈移动端图片压缩(iOS Android)

    在 App 中,如果分享.发布.上传功能涉及到图片,必不可少会对图片进行一定程度的压缩.笔者最近在公司项目中恰好重构了双端(iOS&Android)的图片压缩模块.本文会非常基础的讲解一些图片 ...

最新文章

  1. 二级域名用asp.net 2.0的实现方案
  2. Python Unittest-根据不同测试环境跳过用例详解
  3. [问题]魔兽双击地面回到选中的单位
  4. python如何下载库_python中如何下载库
  5. OpenCV3学习(2.1)——图像Mat数据的访问-at/ptr/iterator
  6. 再记一下sscanf的一个小问题
  7. Python助力性能测试——报文批量生成
  8. idea 2018 3.3版本破解
  9. 宏电DTU配置教程和配置工具
  10. 机器人控制器编程课程-教案02-基础
  11. 如何查看本机路由表并进行分析?
  12. 快递柜智能柜C语言程序,智能快递柜的设计与实现_李浩然.pdf
  13. 程序员高效的准备HR面试
  14. ubuntu 安装nodebb
  15. 串操作指令应用(MOVS/CMPS/SCAS/LODS/STOS)
  16. Docker各操作系统安装方式及优缺点
  17. 绝妙!不用外部电路检测芯片工作电压!
  18. 你还在为“收钱”发愁吗?BeeCloud打造支付平台
  19. 3天增粉10W+,这是活动的全程复盘
  20. 有什么单纯裁剪图片的手机软件app?

热门文章

  1. 分享128个ASP整站程序源码,总有一款适合您
  2. uniapp组件-uni-countdown倒计时
  3. Due to limitations of the com.mongodb.BasicDBObject, you can't add a second 'operateTime' expression
  4. [PKUWC2018]Slay the Spire
  5. 如何去除各种烦人的广告
  6. 译体验|Forrester:客户体验的未来
  7. 亚马逊基础教程_亚马逊的精品系列:基础设施提供商与竞争对手
  8. 亚马逊主图视频应该怎么上传(附图文操作步骤)
  9. Onmeasure报空指针
  10. mysql主键索引的区别_mysql主键与普通索引的区别(转)