尽管是一种相对较新的技术,但低功耗蓝牙(LE)已证明自己是一种通用且有用的通信介质。 尽管它可以用于无线连接设备,但它也使设备能够充当信标和广播数据。

在本教程中,您将学习BluetoothLeAdvertiser类,该类使开发人员无需额外的硬件即可将受支持的电话变成Bluetooth LE信标。 您还将学习如何扫描Bluetooth LE广告数据,以便可以在自己的应用程序中做出适当的反应。 您可以在GitHub上下载本教程的源文件。

1.项目设置

对于本教程,您可以从在Android Studio中创建一个基本的空项目开始。 您需要在build.gradle文件中将最低SDK版本设置为21 ,因为直到Lollipop发行版才在Android上引入了蓝牙LE广告。 尽管有一些方法可以包装在SDK 21之前不支持的API,但本教程将不介绍它们。 我们只专注于手头的新技术。

defaultConfig {applicationId "com.tutsplus.bleadvertising"minSdkVersion 21targetSdkVersion 23versionCode 1versionName "1.0"
}

接下来,您需要向项目的AndroidManifest.xml添加三个权限。 前两个允许蓝牙通信,第三个许可ACCESS_COARSE_LOCATION是在Android 6.0及更高版本的设备上使用蓝牙的新要求。

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

如果您在运行Android 6.0或更高版本的设备上进行开发,则您的应用需要用户授予的位置权限。 可以在我今年早些时候写的《 了解Android M中的权限》中找到有关执行此操作的说明。 为了简单起见,本教程将仅在Android App Info屏幕上授予权限。


既然您已经有权访问应用程序所需的所有内容,那么现在该创建布局文件了。 打开activity_main.xml并使用两个按钮和一个文本视图创建一个简单的布局。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/advertise_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Advertise"/><Buttonandroid:id="@+id/discover_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Discover" /><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="test"/>
</LinearLayout>

这两个Button对象用于启动广告或发现。 TextView用于显示发现时发现的数据。 完成填写布局文件后,可以将其关闭并打开MainActivity.java 。 在此文件中要做的第一件事是添加按钮所使用的View.OnClickListener的实现。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overridepublic void onClick(View v) {if( v.getId() == R.id.discover_btn ) {discover();} else if( v.getId() == R.id.advertise_btn ) {advertise();}}
}

在上面的onClick(View v)方法中,本教程后面将定义advertise()discover() 。 您现在可以为这些方法添加存根,以便您的应用进行编译。 接下来,您需要在类的顶部创建成员变量,以跟踪按钮和文本视图。

private TextView mText;
private Button mAdvertiseButton;
private Button mDiscoverButton;

定义视图后,需要在onCreate(Bundle savedInstanceState)对其进行初始化,并将每个Button连接到OnClickListener定义的OnClickListener

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mText = (TextView) findViewById( R.id.text );mDiscoverButton = (Button) findViewById( R.id.discover_btn );mAdvertiseButton = (Button) findViewById( R.id.advertise_btn );mDiscoverButton.setOnClickListener( this );mAdvertiseButton.setOnClickListener( this );
}

最后,请确保您或您的用户使用的设备支持多个广告。 虽然Lollipop可以提供外围设备广告所需的软件功能,但制造商还必须使用支持广告的蓝牙芯片组。

如果不支持Bluetooth LE广告,则应禁用应用程序中的两个按钮。 虽然已知此功能可在Nexus 6、5X,6P和9上使用,但其他手机也支持Bluetooth LE广告,随着制造商生产更新的手机和平板电脑,将继续制造其他设备。

if( !BluetoothAdapter.getDefaultAdapter().isMultipleAdvertisementSupported() ) {Toast.makeText( this, "Multiple advertisement not supported", Toast.LENGTH_SHORT ).show();mAdvertiseButton.setEnabled( false );mDiscoverButton.setEnabled( false );
}

2.通过蓝牙LE投放广告

要启动广告通过蓝牙LE,你需要检索BluetoothLeAdvertiser从Android BluetoothAdapter 。 您可以在点击广告按钮时调用的advertise()方法中执行此操作。

BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();

有了BluetoothLeAdvertiser ,您就可以定义在广告中使用的设置,例如广播时天线应使用的电量以及设备应多久进行一次广告宣传。 AdvertiseSettings.Builder类还允许您定义移动设备是否应可连接,从而可以跨设备流式传输更多数据。

AdvertiseSettings settings = new AdvertiseSettings.Builder().setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY ).setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH ).setConnectable( false ).build();

您会注意到,此示例在广告中具有较高的信号强度(发射功率)和较低的延迟。 虽然这可以使您的设备快速被发现,但它也可能会占用大量电池,这在移动空间中发展时是宝贵的商品。

广告模式还有其他选项。 ADVERTISE_MODE_LOW_POWER选项是广告的默认设置,并以最少的频率传输以节省最大电量。 ADVERTISE_MODE_BALANCED选项尝试节省功率,而不必在广告之间等待太久。

可以将TX功率设置为超低,低,中或高。 每个级别对应于蓝牙LE广告包可见的程度,尽管确切范围取决于设备硬件。

接下来,定义一个UUID,用于在发布数据包时标识它们。 您可以从命令行使用uuidgen实用程序来创建新的UUID。

➜  ~  uuidgen
CDB7950D-73F1-4D4D-8E47-C090502DBD63

虽然此实用程序创建了128位的UUID,但Android系统仅使用16位的UUID进行广告宣传,并将自动调整128位的UUID以使其符合要求。 在上面的示例中,16位UUID为950D。 接下来,将128位UUID另存为strings.xml中的字符串

<string name="ble_uuid">CDB7950D-73F1-4D4D-8E47-C090502DBD63</string>

一旦创建了UUID,就该创建ParcelUuidAdvertiseData对象,并广播一些附加数据作为附加服务了。 在此示例中,您仅广播了设备的名称和字符串"Data" (必须将其转换为字节数组),因为您的广告数据包的大小相当有限。

ParcelUuid pUuid = new ParcelUuid( UUID.fromString( getString( R.string.ble_uuid ) ) );AdvertiseData data = new AdvertiseData.Builder().setIncludeDeviceName( true ).addServiceUuid( pUuid ).addServiceData( pUuid, "Data".getBytes( Charset.forName( "UTF-8" ) ) ).build();

使用设备通过Bluetooth LE进行广告的最后一件事是创建一个回调,侦听广告时是否成功,然后再通过BluetoothLeAdvertiser广告。

AdvertiseCallback advertisingCallback = new AdvertiseCallback() {@Overridepublic void onStartSuccess(AdvertiseSettings settingsInEffect) {super.onStartSuccess(settingsInEffect);}@Overridepublic void onStartFailure(int errorCode) {Log.e( "BLE", "Advertising onStartFailure: " + errorCode );super.onStartFailure(errorCode);}
};advertiser.startAdvertising( settings, data, advertisingCallback );

此时,您应该能够运行您的应用并开始通过Bluetooth LE进行广告。 但是,本教程的下一步将涉及发现广告,以便您可以显示该信息。

3.发现蓝牙LE广告

在开始发现Bluetooth LE服务之前,您需要在课程顶部添加一些其他成员变量。

private BluetoothLeScanner mBluetoothLeScanner;
private Handler mHandler = new Handler();

mBluetoothLeScanner用于扫描蓝牙LE数据包,并且mHandler控制一个小的计时器,该计时器在设置的时间段后停止发现。

除了这些成员变量之外,您还需要在类的顶部创建一个新的ScanCallback ,以便稍后内部类可以在应用程序中对其进行访问。 此回调接收发现的可接受广告的结果,并在文本视图中显示广告设备名称和关联的数据。

private ScanCallback mScanCallback = new ScanCallback() {@Overridepublic void onScanResult(int callbackType, ScanResult result) {super.onScanResult(callbackType, result);if( result == null|| result.getDevice() == null|| TextUtils.isEmpty(result.getDevice().getName()) )return;StringBuilder builder = new StringBuilder( result.getDevice().getName() );builder.append("\n").append(new String(result.getScanRecord().getServiceData(result.getScanRecord().getServiceUuids().get(0)), Charset.forName("UTF-8")));mText.setText(builder.toString());}@Overridepublic void onBatchScanResults(List<ScanResult> results) {super.onBatchScanResults(results);}@Overridepublic void onScanFailed(int errorCode) {Log.e( "BLE", "Discovery onScanFailed: " + errorCode );super.onScanFailed(errorCode);}
};

接下来,如下所示在onCreate(Bundle savedInstanceState)初始化mBluetoothLeScanner

mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

初始化蓝牙扫描器后,您可以开始充实discover()方法。 对于此示例应用程序,您将创建一个ScanFilter对象并将其放入List以便您的应用程序仅响应您感兴趣的广告包。

ScanFilter filter = new ScanFilter.Builder().setServiceUuid( new ParcelUuid(UUID.fromString( getString(R.string.ble_uuid ) ) ) ).build();
filters.add( filter );

您还需要创建一个ScanSettings对象,该对象的工作原理与您在本教程前面创建的AdvertiseSettings对象相似。

ScanSettings settings = new ScanSettings.Builder().setScanMode( ScanSettings.SCAN_MODE_LOW_LATENCY ).build();

设置好过滤器,设置和回调后,即可开始发现Bluetooth LE广告。

mBluetoothLeScanner.startScan(filters, settings, mScanCallback);

如果现在在两个都支持Bluetooth LE广告的设备上运行您的应用程序,并且将其中一个设置为做广告,而另一个设置为进行发现,则发现设备应找到广告商并显示广告的数据。 以下屏幕截图显示了Nexus 5X发现了广告Nexus 6。


您需要做的最后一件事是创建一个新的Runnable对象,并将其与mHandler关联。 处理程序等待十秒钟,然后启动可停止发现的Runnable 。 原因是发现会很快耗尽设备的电池。 您只想尝试在短时间内或期望找到广告设备时发现广告包。

mHandler.postDelayed(new Runnable() {@Overridepublic void run() {mBluetoothLeScanner.stopScan(mScanCallback);}
}, 10000);

结论

尽管该示例可能看起来不多,但您刚刚创建了一个可以正常工作的应用程序,该应用程序通过Bluetooth LE进行广告发布,以便其他设备可以发现它并传输数据。 尽管本教程介绍了如何通过Android进行广告和发现,但是您也可以轻松地为iOS创建类似的应用,以便在两个平台之间共享数据或构建自己的支持蓝牙LE的设备,从而可以与手机和平板电脑进行交互。

随着这项技术的不断发展并将其集成到每个人的口袋中,开发人员将有无穷的可能性制作出真正有趣的东西。 有关在Android上使用其他蓝牙技术的更多信息,请查看Matthew Kim的 使用Android的蓝牙API创建蓝牙扫描仪 。

翻译自: https://code.tutsplus.com/tutorials/how-to-advertise-android-as-a-bluetooth-le-peripheral--cms-25426

如何宣传Android作为Bluetooth LE外围设备相关推荐

  1. unity Bluetooth LE 插件连接蓝牙

    unity android通过Bluetooth LE这个插件发生数据记录一下 一.注意点 1.一定要打开定位信息,不然收不到蓝牙的 2.网上有很多写AndroidManifest这个文件的配置的,在 ...

  2. Bluetooth LE(低功耗蓝牙) - 第一部分

    前言 在写这篇文章的时候,谷歌刚刚发布了Android Wear ,摩托罗拉也发布了 Moto 360 智能手表.Android Wear的API还是相当基本的,是很好的文档材料,而且还会不断的更新, ...

  3. android -- 蓝牙 bluetooth解读

    入手一个新的模块或应用,当然首先要知道它都有什么了,与它相关的代码在那里,所以先一起看下蓝牙代码分布吧. 1. 代码分布: packages/apps/Bluetooth/ 看这路径肯定是蓝牙应用方面 ...

  4. ZT android -- 蓝牙 bluetooth (四)OPP文件传输

    android -- 蓝牙 bluetooth (四)OPP文件传输 分类: Android的原生应用分析 2013-06-22 21:51 2599人阅读 评论(19) 收藏 举报 4.2源码AND ...

  5. 【Android 应用开发】Android之Bluetooth编程

    Android Bluetopth 编程大牛文章 http://my.oschina.net/u/994235/blog?catalog=313604 ViewGroup 相关资料 : http:// ...

  6. 这样一款超低功耗的集成 2.4 GHz Wi-Fi 和支持长距离的 Bluetooth LE 5.0的SOC,你怎么能不爱它?

    今天要介绍的这个主角是谁呢?超低功耗的集成 2.4 GHz Wi-Fi 和支持长距离的 Bluetooth LE 5.0的SOC,价格还能对标他的"前辈"单WIFI的ESP8266 ...

  7. 乐鑫代理启明云端用图文带你一分钟快速了解ESP32-S3的功能特性:支持AI加速,更好的应用于图像、语音等识别,集成Wi-Fi + Bluetooth LE 5.0和高达44 个可编程 GPIO 管脚

    乐鑫代理-启明云端用图文带你一分钟快速了解ESP32-S3的功能特性: 支持 AI 加速 ESP32-S3 MCU 增加了用于加速神经网络计算和信号处理等工作的向量指令 (vector instruc ...

  8. 基于Android Classic Bluetooth的蓝牙聊天软件

    代码地址如下: http://www.demodashi.com/demo/12133.html BluetoothChat 基于Android Classic Bluetooth的蓝牙聊天软件,目前 ...

  9. 深入了解Android蓝牙Bluetooth——《基础篇》

    深入了解Android蓝牙Bluetooth--<基础篇> 什么是蓝牙?   也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的 ...

最新文章

  1. linux查看hdfs副本数量,文件副本数量问题,设置的dfs.replication没有生效
  2. linux边看系统信息,Linux查看系统信息大全[备忘]
  3. 专题导读:大数据整理
  4. 我的世界java村民繁殖_我的世界:1.14版本刷新几率小的五种村庄,没有村民咋回事?...
  5. 运行python嵌入式要求_在嵌入式IPython实例中运行配置文件启动文件
  6. NEO技术文章征集大赛
  7. Latex 排版第一页出现空白页
  8. 2020-12-16子类对象指针强转成父类对象指针,父类对象指针调用子类函数问题(待整理)
  9. neovim--ubuntu安装
  10. 【路径规划】基于matlab A_star算法机器人走迷宫路径规划【含Matlab源码 1332期】
  11. 推荐一款好用的Bootstrap后台管理框架——inspinia
  12. 面向对象知识 |《C++编程思想》(《Thinking In Cpp》)阅读感受
  13. deeplink唤醒app测试软件,短信跳转app-DeepLink
  14. 用keil怎么擦除_keil如何使用?图文教程告诉你keil怎么使用
  15. Pygame mixer 模块
  16. U盘和存储卡实际上可以轻松的创建隐藏分区制作PE启动盘
  17. 4.4.1 ICMP报文的种类
  18. PD充电加数据OTG方案
  19. php xampp教程,xampp教程(一):xampp下载,安装,配置,运行PHP的web项目
  20. 在微软Azure的服务器上创建Windows虚拟机的教程

热门文章

  1. TensorFlow学习笔记(1)--TensorFlow简介,常用基本操作
  2. Android 性能优化探究,不愧是Alibaba技术官
  3. 不能共情你还当什么领导
  4. BADI 第三代增强 BADI 和 NEW BADI
  5. Linux--环境变量和进程地址空间
  6. 初学者必学:绘画初学者如何设计人物?
  7. 科目一知识点口诀(考驾照顺手整理了一下课)
  8. java分页爬取站长素材的图片
  9. Zhong__安装配置MySQL8.0
  10. 抱歉出现问题:关闭 windows hello,然后尝试再次运行安装程序