android5.0(Lollipop) BLE Peripheral牛刀小试
转载请表明作者: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。代码例如以下:
private void init(){
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_LONG).show();
finish();
}
final BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
if(mBluetoothAdapter == null){
Toast.makeText(this, R.string.bluetooth_not_supported, Toast.LENGTH_LONG).show();
finish();
}
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
if(mBluetoothLeAdvertiser == null){
Toast.makeText(this, "the device not support peripheral", Toast.LENGTH_SHORT ).show();
Log.e(TAG, "the device not support peripheral");
finish();
}
}
前几段代码我就不说了。搞过BLE的基本都是通用的,可是你会发如今代码里多了一句
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
这一句代码会直接推断你的设备究竟支持不支持BLE Peripheral。假如此返回值非空。你才干够继续有机会开发,假设返回空,那说明你的设备搞不了BLE Peripheral(当然。我的代码里没有推断是否打开了蓝牙,这个为了节省时间,你们自己能够加入上)。
支持不支持BLE Peripheral,你也能够用BluetoothAdapter类的isMultipleAdvertisementSupported()函数去check,实际上getBluetoothLeAdvetiser()也会运行上面的isMultipleAdvertisementSupported函数,所以我就直接一步到位了,可是原理大家要懂。
第三。你的设备已经支持BLE Peripheral了,那么下一步就是要考虑我怎么发广播了。可是你在发广播之前,要先准备自己的数据,比方你自己是什么service。里面有什么data等等。
我们先来看看发广播的函数长得什么样子:
mBluetoothLeAdvertiser.startAdvertising(createAdvSettings(true, 0), createAdvertiseData(), mAdvertiseCallback);
从广播函数应该能够看到所须要的參数,一个是广播设置參数,一个是广播数据。另一个是Callback。当然startAdvertising有两种格式,第二种能够获得广播数据的response。
以下我们来看一下AdvertiseSettings:
/** create AdvertiseSettings */
public static AdvertiseSettings createAdvSettings(boolean connectable, int timeoutMillis) {
AdvertiseSettings.Builder mSettingsbuilder = new AdvertiseSettings.Builder();
mSettingsbuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
mSettingsbuilder.setConnectable(connectable);
mSettingsbuilder.setTimeout(timeoutMillis);
mSettingsbuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
AdvertiseSettings mAdvertiseSettings = mSettingsbuilder.build();
if(mAdvertiseSettings == null){
if(D){
Toast.makeText(mContext, "mAdvertiseSettings == null", Toast.LENGTH_LONG).show();
Log.e(TAG,"mAdvertiseSettings == null");
}
}
return mAdvertiseSettings;
}
这里面一共同拥有四个參数。AdvertiseMode、Connectable、Timeout、TxPowerLevel。当然我们能够设置我们须要的,其它的參数会使用默认的值。
再就是格式非常重要。我们一定要是AdvertiseSettings.builder。不然你仅仅能设置一个參数。
再就是AdvertiseData:
public static AdvertiseData createAdvertiseData(){
AdvertiseData.Builder mDataBuilder = new AdvertiseData.Builder();
mDataBuilder.addServiceUuid(ParcelUuid.fromString(HEART_RATE_SERVICE));
AdvertiseData mAdvertiseData = mDataBuilder.build();
if(mAdvertiseData==null){
if(D){
Toast.makeText(mContext, "mAdvertiseSettings == null", Toast.LENGTH_LONG).show();
Log.e(TAG,"mAdvertiseSettings == null");
}
}
return mAdvertiseData;
}
这里面就须要设置非常多參数了,我这里为了简单。仅仅广播心跳的UUID,可是没有数据。假设你们有自己的数据等等,能够再这里面去设置。自己定义函数也在AdvertiseData类里。
最后一步就是准备Callback函数:
private AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
if (settingsInEffect != null) {
Log.d(TAG, "onStartSuccess TxPowerLv=" + settingsInEffect.getTxPowerLevel() + " mode=" + settingsInEffect.getMode()
+ " timeout=" + settingsInEffect.getTimeout());
} else {
Log.e(TAG, "onStartSuccess, settingInEffect is null");
}
Log.e(TAG,"onStartSuccess settingsInEffect" + settingsInEffect);
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
if(D) Log.e(TAG,"onStartFailure errorCode" + errorCode);
if(errorCode == ADVERTISE_FAILED_DATA_TOO_LARGE){
if(D){
Toast.makeText(mContext, R.string.advertise_failed_data_too_large, Toast.LENGTH_LONG).show();
Log.e(TAG,"Failed to start advertising as the advertise data to be broadcasted is larger than 31 bytes.");
}
}else if(errorCode == ADVERTISE_FAILED_TOO_MANY_ADVERTISERS){
if(D){
Toast.makeText(mContext, R.string.advertise_failed_too_many_advertises, Toast.LENGTH_LONG).show();
Log.e(TAG,"Failed to start advertising because no advertising instance is available.");
}
}else if(errorCode == ADVERTISE_FAILED_ALREADY_STARTED){
if(D){
Toast.makeText(mContext, R.string.advertise_failed_already_started, Toast.LENGTH_LONG).show();
Log.e(TAG,"Failed to start advertising as the advertising is already started");
}
}else if(errorCode == ADVERTISE_FAILED_INTERNAL_ERROR){
if(D){
Toast.makeText(mContext, R.string.advertise_failed_internal_error, Toast.LENGTH_LONG).show();
Log.e(TAG,"Operation failed due to an internal error");
}
}else if(errorCode == ADVERTISE_FAILED_FEATURE_UNSUPPORTED){
if(D){
Toast.makeText(mContext, R.string.advertise_failed_feature_unsupported, Toast.LENGTH_LONG).show();
Log.e(TAG,"This feature is not supported on this platform");
}
}
}
};
当你广播成功,会受到onStartSuccess的回调。回调的參数也是AdvertiseSettings设置的參数。假设你还有你自己想做的,能够再这里面去做。
为了大家方便,我把errorcode可能遇到的问题,都做了推断,仅仅有这五种错误情况。
最后一步就是关闭了,开了广播要关闭,不然会造成未知问题:
private void stopAdvertise() {
if (mBluetoothLeAdvertiser != null) {
mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
mBluetoothLeAdvertiser = null;
}
}
ok,代码就是这么简单。仅仅要熟悉流程就能够搞定。希望对大家有帮助。
代码路径为:http://download.csdn.net/detail/lansefeiyang08/8799027
android5.0(Lollipop) BLE Peripheral牛刀小试的更多相关文章
- android5.0(Lollipop) BLE Central牛刀小试
转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073 昨天写了android L BLE Peripheral的简单 ...
- android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇
上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播. 首先还是先看一下上一篇文章结束的地方: @Override public void onClientRegistere ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23347612来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...
- Android5.0(Lollipop) BLE蓝牙4.0+浅析概念(四)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23679793来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 置顶:此文转载CSDN博 ...
- Android5.0(lollipop)新特性介绍(一)
今年6月的Google I/O大会上.Android L的初次见面我相信让会让非常多android粉丝有些小激动和小期待.当然作为开发人员的我来说,激动不言而喻,毕竟这是自08年以来改变最大的一个版本 ...
- android5.0 BLE 蓝牙4.0+浅析demo搜索(一)
作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23341414来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Bgwan 莳萝花 ...
- 解决Android5.0以下Dialog引起的内存泄漏
最近项目开发中,开发人员和测试人员均反应在android5.0以下手机上LeakCanary频繁监控到内存泄漏,如下图所示,但凡用到Dialog或DialogFragment地方均出现了内存泄漏. 如 ...
- android BLE Peripheral 做外设模拟设备,供ios、android 连接通讯。
为了能让其它设备可以发现其设备,先启动特定广播.看自己需要什么广播格式. 对于广播可见的mac address: 在调用startAdvertising();时,mac address 就会改变. 并 ...
随机推荐
- 【C#】堆、栈和堆栈的区别
导读:今天看视频,就看到了堆.栈这一块了.记得当年初相见(VB视频),劈头盖脸一阵蒙,什么都不知道,那时候师傅叫我挂起来,说我随着学习的进度,慢慢的就会懂了.现在,学到了这里,想着自己对自己从前的问题 ...
- HDU 4609 3-idiots ——FFT
[题目分析] 一堆小木棍,问取出三根能组成三角形的概率是多少. Kuangbin的博客中讲的很详细. 构造一个多项式 ai=i的个数. 然后卷积之后去重. 统计也需要去重. 挺麻烦的一道题. #inc ...
- BZOJ2245 [SDOI2011]工作安排 【费用流】
题目 你的公司接到了一批订单.订单要求你的公司提供n类产品,产品被编号为1~n,其中第i类产品共需要Ci件.公司共有m名员工,员工被编号为1~m员工能够制造的产品种类有所区别.一件产品必须完整地由一名 ...
- 洛谷P3588 - [POI2015]Pustynia
Portal Description 给定一个长度为\(n(n\leq10^5)\)的正整数序列\(\{a_n\}\),每个数都在\([1,10^9]\)范围内,告诉你其中\(s\)个数,并给出\(m ...
- 栅格网络流(cogs 750)
[问题描述] Bob 觉得一般图的最大流问题太难了,他不知道如何解决,于是他想尝试一个简单点的:栅格网络中的最大流问题,这个虽说简单了一点,但对 Bob 来说依旧太难,现在他有个麻烦需要你帮忙:给你一 ...
- ASP.NET2.0 ObjectDataSource的使用详解《转》
原文发布时间为:2008-08-02 -- 来源于本人的百度文章 [由搬家工具导入] ASP.NET2.0 ObjectDataSource的使用详解(2) http://mqingqing123.c ...
- Android 网络编程之HttpURLConnection运用
Android 网络编程之HttpURLConnection 利用HttpURLConnection对象,我们可以从网络中获取网页数据. 01 URL url = new URL("http ...
- spring boot -- 无法读取html文件,碰到的坑
碰到的坑,无法Controller读取html文件 1. Controller类一定要使用@Controller注解,不要用@RestController 2. resource目录下创建templa ...
- 使用注解开发springmvc
1.导入jar包 commons-logging-1.2.jar spring-aop-4.3.6.RELEASE.jar spring-beans-4.3.6.RELEASE.jar spring- ...
- python--错误了就需要调试(异常处理)
python提供了两个非常重要的功能来处理python程序在运行中出现的异常和错误.你可以使用该功能来调试python程序. 我们可打开idle-->F1进行查看文档,里面很多异常类型,如图: ...