大家好,本篇文章主要讲的是机器人蓝牙简单开发示例教程,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
目录
概述1、权限申请2、打开蓝牙3、接收蓝牙状态的改变4、扫描其他的设备5、蓝牙配对6、获取已经配对的设备7、连接设备
概述
前段时间学习了一些蓝牙开发的知识,记录一下机器人中蓝牙的简单开发。下面是最重要的两个类。
BluetoothAdapter: 蓝牙适配器,通过getDefaultAdapter()去获取一个实例,如果设备不支持蓝牙的话,返回的是一个空对象,通过它,可以打开、关闭蓝牙,扫描设备、向指定设备创建(电源)插座通道…
BluetoothDevice: 代表一个设备对象,可以通过它获取设备的名字、地址、类型等,也可以创建匹配,建立(电源)插座通道等等。
1、权限申请
uses-permission Android:name=' Android。许可。蓝牙'/使用蓝牙所需要的权限
uses-permission Android:name=' Android。许可。蓝牙_管理'/使用扫描和设置蓝牙的权限(申明这一个权限必须申明上面一个权限)
安卓6以上版本,扫描其他蓝牙还需要位置权限
//安卓9以下版本
用户权限Android:name=' Android。许可。access _ COARSE _ LOCATION '/
//安卓9以上
uses-permission Android:name=' Android。许可。access _ FINE _ LOCATION '/
2、打开蓝牙
mBluetoothAdapter=蓝牙适配器。getdefaultadapter();
//如果设备不支持蓝牙
if (mBluetoothAdapter==null){
返回;
}
//设备支持蓝牙功能,调用startActivityForResult去启动蓝牙
如果(!mbluetoothadapter。已启用()){
start蓝牙. launch(新意图(蓝牙适配器.ACTION _ REQUEST _ ENABLE);
}
打开蓝牙功能是通过开始活动去启动的,但是开始活动这个函数已经过期了,所以我使用官方推荐的活动结果替代它
activityresultlaunchenrent start bluetooth=registerForActivityResult(新活动结果合同.StartActivityForResult(),
new ActivityResultCallbackActivityResult(){
@覆盖
活动结果上的公共void(活动结果结果){
if (result==null){
吐司。制作文本(蓝牙活动。“这,”打开失败,吐司.LENGTH_SHORT).show();
}否则{
如果(结果。get RESULT code()==RESULT _ CANCELED){
Toast.makeText(蓝牙'活动. this '用户取消,吐司. LENGTH _ SHORT);
}
}
}
});
3、接收蓝牙状态的改变
通过广播去接收蓝牙状态的改变
类蓝牙StateChangeReceiver扩展广播接收器{
public int DEFAULT _ VALUE _ BLUETOOTH=1000;
@覆盖
公共接收时无效(上下文语境,意图意图){
字符串动作=意图。get action();
如果(蓝牙适配器ACTION _ STATE _ changed。等于(动作)){
int state=意图。getint extra(蓝牙适配器.EXTRA_STATE,DEFAULT _ VALUE _ BLUETOOTH);
开关(状态){
外壳蓝牙适配器。状态开启:
Log.d(标签,‘接收时:打开’);
打破;
外壳蓝牙适配器。状态关闭:
Log.d(标签,'接收时:关闭');
打破;
外壳蓝牙适配器。状态打开:
Log.d(TAG,' onReceive:正在打开');
打破;
外壳蓝牙适配器。状态_关闭_关闭:
Log.d(TAG,' onReceive:正在关闭');
打破;
}
}
}
}
别忘了广播的注册和解注册
意向过滤器filter=新意向过滤器(蓝牙适配器. ACTION _ STATE _ CHANGED);
state receiver=new bluetooth statechangereceiver();
注册接收者(stateReceiver,过滤器);
4、扫描其他的设备
同样通过广播接收,动作是蓝牙设备。操作_已找到
牛油果类扩展广播接收器{
@覆盖
公共接收时无效(上下文语境,意图意图){
字符串动作=意图。get action();
如果(蓝牙设备. ACTION_FOUND.equals(action)) {
//从目的对象中获取蓝牙设备的信息
蓝牙设备设备=意图。getparcelableextra(蓝牙设备.EXTRA _ DEVICE);
//当发现新设备不存在于配对列表中时添加
if (device.getBondState()!=蓝牙设备. BOND_BONDED) {
蓝色的名字。添加(设备。getname()' \ t '设备。get address());
}
蓝色适配器。notifydatasetchanged();
Log.d(标签,'在接收:'设备上。getname());
}
}
}
动态注册广播
意向过滤器filter=新意向过滤器(蓝牙设备. ACTION _ FOUND);
registerReceiver(mReceiver,filter);
开启扫描
mbluethadapter。开始发现();
5、蓝牙配对
公共类债券接收者扩展广播接收器{
@覆盖
公共接收时无效(上下文语境,意图意图){
如果(蓝牙设备. ACTION _ BOND _ STATE _ changed。等于(意图。get ACTION()){
蓝牙设备设备=意图。getparcelableextra(蓝牙设备.EXTRA _ DEVICE);
switch(device.getBondState()){
蓝牙设备。粘合_粘合:
Log.d(TAG,' onReceive:配对完成');
打破;
蓝牙设备。粘合_粘合:
Log.d(TAG,' onReceive:正在配对');
打破;
蓝牙设备。债券_无:
Log.d(TAG,' onReceive:取消配对');
打破;
}
}
}
}
6、获取已经配对的设备
已经配对的设备会被存储起来,通过蓝牙适配器直接获取即可
setbluetooth设备配对设备=mbluetoothadapter。getbondedevices();
如果(配对设备。size()0){
对于(蓝牙设备配对设备:配对设备){
蓝色的名字。添加(配对的设备。getname()' '配对的设备。get address());
Log.d(标签,' onClick:'配对设备。getname());
}
}
7、连接设备
想要在两台设备之间创建连接,必须实现客户端和服务端机制,他们之间使用套接字机制进行连接,服务端开放服务器套接字,客户端通过测量与控制(测量和控制)地址向服务端发起连接。客户端和服务端以不同的方式获得蓝牙插座,当客户端和服务端在同一个RFCOMM通道上分别拥有已连接的蓝牙插座时,将他们视为彼此已经连接,于是每台设备都获得输入和输出流式传输,并开始传输数据。
连接技术
一种实现技术是自动将每台设备准备为一个服务器,从而使每台设备开放一个服务套接字并侦听连接,在此情况下,任何一台设备都可以发起与另一台设备的连接并称为客户端。
服务器
设置服务器套接字并接受连接,步骤依次如下
1、调用listenUsingRfcommWithServiceRecord()获取一个蓝牙服务器插座,该函数需要两个参数,第一个是服务器的名称,自己取一个即可,第二个是UUID,用来对信息做唯一性标识,我们可以从网上众多UUID生成器中随机的生成一个,然后使用UUID.fromString(字符串)初始化一个UUID。
2、通过接受()函数开始侦听连接请求
只有远程设备发送的连接请求中UUID与使用此套接字注册的UUID相匹配时服务器才会接受请求,接受函数会返回已连接的蓝牙插座
3、连接成功后调用关闭()关闭蓝牙插座
私有类接受线程扩展了线程{
私有最终蓝牙服务器套接字mmserver套接字;
私有字符串mSocketType
公共接受线程(布尔安全){
蓝牙服务器套接字tmp=空
mSocketType=secure?secure ':' in secure ';
尝试{
如果(安全){
tmp=蓝牙适配器。listenusingrfcommwithservicerecord(名称_安全,我的_ UUID _安全);
}否则{
tmp=蓝牙适配器。listenusingrfcommwithservicerecord(名称_不安全,我的_ UUID _不安全);
}
} catch (IOException e) {
Log.e(TAG,' socket type ' mSocketType ' listen()failed ',e);
}
mmServerSocket=tmp
}
@覆盖
公共无效运行(){
Log.d(标记,'套接字类型:' mSocketType
BEGIN maccepthread ' this ');
setName(' accept thread ' mSocketType);
蓝牙套接字=空
Log.d(标记,'运行:开始监听');
while (true){
尝试{
socket=mmserver套接字。接受();
Log.d('acceptThread ',' run:连接成功');
已连接(socket,socket.getRemoteDevice(),mSocketType);
} catch (IOException e) {
Log.e(TAG,' Socket Type:' mSocketType ' accept()failed ',e);
打破;
}
}
Log.i(标记,' END mAcceptThread,套接字类型:' mSocketType ');
}
公共空的取消(){
Log.d(标记,'套接字类型' mSocketType '取消'此);
尝试{
mmserver套接字。close();
} catch (IOException e) {
Log.e(TAG,' Socket Type ' mSocketType ' close()of server failed ',e);
}
}
}
上面的安全的和不稳定的只是使用了不同的UUID而已。
客户端
远程设备开启监听后,我们就发起向此设备的连接,首先必须先获得远程设备的蓝牙设备对象,然后获取蓝牙插座发起连接。
基本步骤如下
1、使用蓝牙设备通过调用createrfcomsockettoservicerecord(UUID)获取蓝牙插座。
2、通过连接发起连接
私有类连接线程扩展线程{
私人决赛蓝牙插座mm插座;
私有最终蓝牙设备mm设备
私有字符串mSocketType
公共连接线程(蓝牙设备设备,布尔安全){
mmDevice=设备;
蓝牙tmp=null
mSocketType=secure?"安全":"不安全";
尝试{
如果(安全){
tmp=设备。createrfcomsockettoservicerecord(我的UUID)安全);
}否则{
tmp=设备。createrfcomsockettoservicerecord(我的UUID)不安全);
}
} catch (IOException e) {
Log.e(标记,'套接字类型:' mSocketType 'create()失败,e);
}
mmSocket=tmp
}
@覆盖
公共无效运行(){
Log.i(标记,' BEGIN mConnectThread套接字类型:' mSocketType ');
setName(' connect thred ' mSocketType);
//总是取消发现,因为它会减慢连接
蓝牙适配器。取消发现();
//连接
//建立到蓝牙套接字的连接
尝试{
//这是一个阻塞调用,只会在
//成功连接或异常
mm插座。connect();
Log.d(标签,'运行:套接字连接成功');
} catch (IOException e) {
//关闭套接字
Log.d(标记,'运行:关闭socket’);
尝试{
mm插座。close();
} catch (IOException e2) {
Log.e(标记,'无法关闭()' mSocketType
连接失败时的套接字,E2);
}
返回;
}
已连接(mmSocket,mmDevice,mSocketType);
}
公共空的取消(){
尝试{
mm插座。close();
} catch (IOException e) {
Log.e(标记,连接“mSocketType”套接字失败的close()),e);
}
}
}
发送数据
连接成功后,我们就可以通过(电源)插座发送数据了,客户端的(电源)插座对象是蓝牙插座,服务端的(电源)插座是蓝牙服务器插座,特别注意不要混淆了。使用getInputStream和getOutputStream分别获取通过套接字处理数据传输的输入流和输出流。写数据比较简单,但是读数据就需要一个单独的线程一直监听才行。
私有类连接线程扩展线程{
私人决赛蓝牙插座mm插座;
私有输入流mmInStream
私有输出流mmOutStream
公共连接线程(蓝牙socket socket,String socketType)引发IOException {
Log.d(标签,'创建连接的线程:'套接字类型');
mmSocket=套接字
InputStream tmpIn=null
OutputStream tmpOut=null
尝试{
TM引脚=插座。getinputstream();
tmp out=socket。获取输出流();
如果(插座!=null){
tmpOut.write(新字符串('你好').getBytes());
Log.d(标记,'连接线程:套接字不是null’);
}
} catch (IOException e) {
Log.e(标签,'未创建临时套接字,e);
}
mmInStream=tmpIn
mmOutStream=tmpOut
//mmOutStream.write(新字符串('你好').getBytes());
}
@RequiresApi(api=Build .版本代码KITKAT)
@覆盖
公共无效运行(){
Log.i(标记,' BEGIN mConnectedThread ');
字节[]缓冲区=新字节[1024];
(同Internationalorganizations)国际组织字节;
while (true){
尝试{
bytes=mmInStream.read(缓冲区);
//将字节发送到用户界面活动
String text=encodeByteToString(缓冲区,字节);
Log.d(标记,'运行:收到消息:' text);
chatItems.add(文本);
mhandler。sendmessage(mhandler。获取消息());
} catch (IOException e) {
Log.d(标记,'运行:没有收到消息');
e。printstacktrace();
打破;
}
}
}
公共字符串encodeByteToString(byte[] data,int length) {
字节[]温度=新字节[长度];
for(int I=0;我长度;i ) {
temp[I]=data[I];
}
尝试{
返回新字符串(temp,' utf-8 ');
} catch(UnsupportedEncodingException e){
返回"";
}
}
公共空的写入(字节[]缓冲区){
尝试{
mmOutStream.write(缓冲区);
//mHandler.obtainMessage(常量消息_写,-1,-1,缓冲区)。sendToTarget();
} catch (IOException e) {
e。printstacktrace();
}
}
公共空的取消(){
尝试{
mm插座。close();
Log.d(标记、‘取消:连接线程’);
} catch (IOException e) {
Log.e(标签,'连接套接字的关闭()失败,e);
}
}
}
上面的例子,我主要是研究了官网蓝牙聊天项目写的代码,你也可以直接看官网项目。从上面的例子可以看出,接收到的数据流都是二进制的,实际项目中需要用到一些编码和转换。也就是说我自己写一些协议,学过socket编程的同学一定都懂。其实蓝牙有很多有用的协议,比如AVRCP(音视频远程控制规范),它定义了蓝牙设备和音视频控制功能之间通信的特点和过程。结合MediaSession,可以轻松实现设备的音视频控制。
这就是这篇关于android蓝牙简单开发实例教程。更多相关android蓝牙开发内容,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。