转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743

知道Android L对蓝牙对了一些改进,包括添加A2dp sink、HFP client、BLE Peripheral功能等等。

我花了一天多时间对Android L BLE Peripheral SDK进行了研究,网上的资料很少,有一个介绍的还不够清晰,所以就自己写了一个测试应用,希望可以对理解BLE Peripheral有一定的帮助。

此贴主要以讲解代码为主,我会把项目代码也传到CSDN中,帮助大家测试。

首先说明一点,并不是Android L的系统就可以支持BLE Peripheral,这个和硬件也是有关系的(以前有人告诉我支持BLE Peripheral是纯软件的东西,要不就是扯淡,要不就是我测得有问题)。我用我手上的Pad(支持BLE central,android5.0)发现直接不支持,Android5.0 SDK已经开始支持check手机是否支持BLE Peripheral,后面代码会提到。

好了,下面我就直接上代码了。为了代码简单整洁,我用一个Activity来完成最基本的功能,如果还有其他需求,只要稍微改一下就可以了。

我在写这个代码的时候,第一个困惑是BLE Peripheral操作流程是什么?代码流程怎么写?我相信大家和我应该是一样的困惑。所以我不全部贴代码(我上传后,代码直接下载好了)。我按照流程给大家说一下我写的思路。

首先,我去查SDK的接口,我发现在android L SDK中多了一个package:android.bluetooth.le;里面多了Peripheral和Scanner,Scanner我会后面更新。

第二步开始写代码,代码里首先检查是否支持BLE、BLE Peripheral。代码如下:

[java] view plain copy
  1. private void init(){
  2. if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
  3. Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_LONG).show();
  4. finish();
  5. }
  6. final BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
  7. mBluetoothAdapter = mBluetoothManager.getAdapter();
  8. if(mBluetoothAdapter ==  null){
  9. Toast.makeText(this, R.string.bluetooth_not_supported, Toast.LENGTH_LONG).show();
  10. finish();
  11. }
  12. mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
  13. if(mBluetoothLeAdvertiser == null){
  14. Toast.makeText(this, "the device not support peripheral", Toast.LENGTH_SHORT    ).show();
  15. Log.e(TAG, "the device not support peripheral");
  16. finish();
  17. }
  18. }

前几段代码我就不说了,搞过BLE的基本都是通用的,但是你会发现在代码里多了一句

[java] view plain copy
  1. mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();

这一句代码会直接判断你的设备到底支持不支持BLE Peripheral。假如此返回值非空,你才可以继续有机会开发,如果返回空,那说明你的设备搞不了BLE Peripheral(当然,我的代码里没有判断是否打开了蓝牙,这个为了节省时间,你们自己可以添加上)。

支持不支持BLE Peripheral,你也可以用BluetoothAdapter类的isMultipleAdvertisementSupported()函数去check,实际上getBluetoothLeAdvetiser()也会执行上面的isMultipleAdvertisementSupported函数,所以我就直接一步到位了,但是原理大家要懂。

第三,你的设备已经支持BLE Peripheral了,那么下一步就是要考虑我怎么发广播了。但是你在发广播之前,要先准备自己的数据,比如你自己是什么service,里面有什么data等等。

我们先来看看发广播的函数长得什么样子:

[java] view plain copy
  1. mBluetoothLeAdvertiser.startAdvertising(createAdvSettings(true, 0), createAdvertiseData(), mAdvertiseCallback);

从广播函数应该可以看到所需要的参数,一个是广播设置参数,一个是广播数据,还有一个是Callback。当然startAdvertising有两种格式,另外一种可以获得广播数据的response。

下面我们来看一下AdvertiseSettings:

[java] view plain copy
  1. /** create AdvertiseSettings */
  2. public static AdvertiseSettings createAdvSettings(boolean connectable, int timeoutMillis) {
  3. AdvertiseSettings.Builder mSettingsbuilder = new AdvertiseSettings.Builder();
  4. mSettingsbuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
  5. mSettingsbuilder.setConnectable(connectable);
  6. mSettingsbuilder.setTimeout(timeoutMillis);
  7. mSettingsbuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
  8. AdvertiseSettings mAdvertiseSettings = mSettingsbuilder.build();
  9. if(mAdvertiseSettings == null){
  10. if(D){
  11. Toast.makeText(mContext, "mAdvertiseSettings == null", Toast.LENGTH_LONG).show();
  12. Log.e(TAG,"mAdvertiseSettings == null");
  13. }
  14. }
  15. return mAdvertiseSettings;
  16. }

这里面一共有四个参数,AdvertiseMode、Connectable、Timeout、TxPowerLevel。当然我们可以设置我们需要的,其他的参数会使用默认的值。

再就是格式很重要,我们一定要是AdvertiseSettings.builder,不然你只能设置一个参数。

再就是AdvertiseData:

[java] view plain copy
  1. public static AdvertiseData createAdvertiseData(){
  2. AdvertiseData.Builder    mDataBuilder = new AdvertiseData.Builder();
  3. mDataBuilder.addServiceUuid(ParcelUuid.fromString(HEART_RATE_SERVICE));
  4. AdvertiseData mAdvertiseData = mDataBuilder.build();
  5. if(mAdvertiseData==null){
  6. if(D){
  7. Toast.makeText(mContext, "mAdvertiseSettings == null", Toast.LENGTH_LONG).show();
  8. Log.e(TAG,"mAdvertiseSettings == null");
  9. }
  10. }
  11. return mAdvertiseData;
  12. }

这里面就需要设置很多参数了,我这里为了简单,只广播心跳的UUID,但是没有数据。如果你们有自己的数据等等,可以再这里面去设置,自定义函数也在AdvertiseData类里。

最后一步就是准备Callback函数:

[java] view plain copy
  1. private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
  2. @Override
  3. public void onStartSuccess(AdvertiseSettings settingsInEffect) {
  4. super.onStartSuccess(settingsInEffect);
  5. if (settingsInEffect != null) {
  6. Log.d(TAG, "onStartSuccess TxPowerLv=" + settingsInEffect.getTxPowerLevel()     + " mode=" + settingsInEffect.getMode()
  7. + " timeout=" + settingsInEffect.getTimeout());
  8. } else {
  9. Log.e(TAG, "onStartSuccess, settingInEffect is null");
  10. }
  11. Log.e(TAG,"onStartSuccess settingsInEffect" + settingsInEffect);
  12. }
  13. @Override
  14. public void onStartFailure(int errorCode) {
  15. super.onStartFailure(errorCode);
  16. if(D)   Log.e(TAG,"onStartFailure errorCode" + errorCode);
  17. if(errorCode == ADVERTISE_FAILED_DATA_TOO_LARGE){
  18. if(D){
  19. Toast.makeText(mContext, R.string.advertise_failed_data_too_large, Toast.LENGTH_LONG).show();
  20. Log.e(TAG,"Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.");
  21. }
  22. }else if(errorCode == ADVERTISE_FAILED_TOO_MANY_ADVERTISERS){
  23. if(D){
  24. Toast.makeText(mContext, R.string.advertise_failed_too_many_advertises, Toast.LENGTH_LONG).show();
  25. Log.e(TAG,"Failed to start advertising because no advertising instance is available.");
  26. }
  27. }else if(errorCode == ADVERTISE_FAILED_ALREADY_STARTED){
  28. if(D){
  29. Toast.makeText(mContext, R.string.advertise_failed_already_started, Toast.LENGTH_LONG).show();
  30. Log.e(TAG,"Failed to start advertising as the advertising is already started");
  31. }
  32. }else if(errorCode == ADVERTISE_FAILED_INTERNAL_ERROR){
  33. if(D){
  34. Toast.makeText(mContext, R.string.advertise_failed_internal_error, Toast.LENGTH_LONG).show();
  35. Log.e(TAG,"Operation failed due to an internal error");
  36. }
  37. }else if(errorCode == ADVERTISE_FAILED_FEATURE_UNSUPPORTED){
  38. if(D){
  39. Toast.makeText(mContext, R.string.advertise_failed_feature_unsupported, Toast.LENGTH_LONG).show();
  40. Log.e(TAG,"This feature is not supported on this platform");
  41. }
  42. }
  43. }
  44. };

当你广播成功,会受到onStartSuccess的回调,回调的参数也是AdvertiseSettings设置的参数。如果你还有你自己想做的,可以再这里面去做。

为了大家方便,我把errorcode可能遇到的问题,都做了判断,只有这五种错误情况。

最后一步就是关闭了,开了广播要关闭,不然会造成未知问题:

[java] view plain copy
  1. private void stopAdvertise() {
  2. if (mBluetoothLeAdvertiser != null) {
  3. mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
  4. mBluetoothLeAdvertiser = null;
  5. }
  6. }

ok,代码就是这么简单,只要熟悉流程就可以搞定。希望对大家有帮助。

代码路径为:http://download.csdn.net/detail/lansefeiyang08/8799027

转载于:https://www.cnblogs.com/Free-Thinker/p/8677982.html

android5.0(Lollipop) BLE Peripheral牛刀小试相关推荐

  1. android+5.0+ble,android5.0(Lollipop) BLE Peripheral牛刀小试(示例代码)

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743 知道Android L对蓝牙对了一些改进.包含加入A2dp s ...

  2. android ble peripheral,android5.0(Lollipop) BLE Peripheral牛刀小试

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743 知道Android L对蓝牙对了一些改进.包含加入A2dp s ...

  3. android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇

    上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播.首先还是先看一下上一篇文章结束的地方:@Override public void onClientRegistered( ...

  4. Android5.0 Lollipop(棒棒糖)

    Android Lollipop 重点开发特色 材料设计 业绩焦点 通知 你在大屏幕上的应用程序 以文档为中心的应用程序 先进的连接 高性能显卡 更强大的音频 增强的照相和摄像机 屏幕捕捉和分享 新类 ...

  5. 联想a850 android 5.0 lollipop,手机资讯导报:全新纯净款MotoX运行Android5.0Lollipop视频曝光...

    科技.数码.互联网新闻如今都成为了大众所关注的热点了,因为在我们的生活当中如今已经是处处与这些相关了,不论是手机也好,电脑也好,又或者是智能手表也好,与之都相关,那么今天小编也是为大家来推荐一篇关于互 ...

  6. android ble peripheral,Android - BlueTooth BLE 之 Central 与 Peripheral 理解

    一.前言 Andorid 5.0 之前是无法进行 外围设备开发的,在Android 5.0 API 21 android.bluetooth.le包下,新增加 Scaner相关类和 Advertise ...

  7. android BLE Peripheral 手机模拟设备发出BLE广播 BluetoothLeAdvertiser

    android 从4.3系统开始可以连接BLE设备,这个大家都知道了.iOS是从7.0版本开始支持BLE.android 进入5.0时代时,开放了一个新功能,手机可以模拟设备发出BLE广播, 这个新功 ...

  8. android ble status,Android BLE peripheral disconnects with status code BLE_HCI_INSTANT_PASSED(0x28)

    问题 My application is able to connect to the BLE peripheral(which is an OBDII/J1939 device) device su ...

  9. Android5.0,6.0,7.0,8.0新特性整理

    背景 Android5.0(Android Lollipop)是谷歌公司2014年10月发布的全新安卓系统,至今已经两年多.然而由于国产手机对安卓ROM的深度定制或修改,以及手机厂商.芯片制造商.运营 ...

最新文章

  1. 好用的数据增强工具Augmentor(原图和mask扩充)
  2. mysql 手工注入教程_mysql手工注入步骤
  3. ipguard客户端如何卸载_客户端navicat遇到问题怎么办?
  4. 2018 ACM-ICPC World Finals - Beijing
  5. vcm服务器如何修改端口,VCM2000是迈普协同通信解决方案的网管服务器.doc
  6. Mybatis构建sql语法
  7. Scala进阶之路-进程控制之执行shell脚本
  8. java batik读取svg_Java Batik操作SVG,实现svg读取,生成,动态操作
  9. 国际混淆C代码大赛获奖作品部分源码
  10. M1芯片Mac mini 2K显示器开启HiDpi
  11. 昆腾公司稍感安慰:向外扩展存储业务营收有所提升
  12. 千锋培训学python怎么样
  13. 《一切都是最好的安排》——加措
  14. Typora图床设置
  15. 骏文c语言银行系统,C语言学生选课管理系统
  16. 简单货机装运模型lingo求解
  17. 小微企业实施数字化转型的困境
  18. PCB电路板为什要沉金和镀金,什么是沉金和镀金,区别在哪?
  19. kylin在hadoop 中的架构图_Kylin |1.麒麟架构及原理
  20. python--爬虫--获取和解析存储网页内容--以薄荷网为例

热门文章

  1. 开源助推进NFV发展,红帽为运营商“定制”NFV落地方案
  2. docker supervisor管理进程
  3. 百度云网盘 360云盘 金山快盘 等 + Git GUI 实现代码版本管理-个人篇
  4. URAL 1009. K-based Numbers
  5. 关于Web应用程序数据库连接的使用
  6. TCP 三次握手与四次挥手
  7. 计算机文化基础教程教案,新版《计算机文化基础》教案.doc
  8. Python倒排索引函数
  9. 通过xrdp远程访问ubuntu出现输入d最小化问题的处理
  10. 软件作坊模式工件应用论