关闭

基于SnapDragonBoard蓝牙通信(二)

标签: android
128人阅读 评论(0) 收藏 举报
分类:

咋们接着上次的blog接着说一下Android 蓝牙的调用流程,如不清楚上节我们说的内容请小伙伴移步到基于SnapDragonBoard410c的蓝牙控制

(1)开启搜索
如果想要使自己的蓝牙设备可见,使用ACTION_REQUEST_DISCOVERABLE的Intent,调用startActivityForResult(Intent, int)方法即可。这将会通过系统设置请求开启搜索模式。默认情况下,设备将在120秒内可见。你可以定义不同的时间长度,通过添加Intent的extra: EXTRA_DISCOVERABLE_DURATION即可。该时长最大为3600秒,最小为0,超出该范围的值都会被设为120秒。其中,0表示设备始终处于可见状态。例如:

Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);

一个请求蓝牙可见的对话框将会被显示出来。如果用户选择“是”,那么该设备将会在指定时间内可见,你的Activity将会在onActiviyResult()中返回和时限相同的result code。如果用户选择“否”,那么result code将为ESULT_CANCELED。

设备将在指定时间内保持可见。如果你想要检查状态的变化,可以通过使用ACTION_SCAN_MODE_CHANGED的Intent注册广播进行监听。该广播onReceive()的Intent包含两个额外域:EXTRA_SCAN_MODE 和 EXTRA_PREVIOUS_SCAN_MODE,分别表示新旧状态。可能的值有:SCAN_MODE_CONNECTABLE_DISCOVERABLE(可连接可见),SCAN_MODE_CONNECTABLE(可连接但不可见) 或 SCAN_MODE_NONE(不可连接不可见)。

如果仅仅是连接到远程蓝牙设备的话,你并不需要开启可见性。开启可见性仅仅在你的应用中作为服务端时才是必要的。因为其他蓝牙设备必须找到你的设备之后才能建立连接。

(2)连接设备

为了在你的应用中让双方设备建立连接,你必须同时实现服务器端和客户端的机制。因为其中一个设备一定会开启服务器Socket,而另一个进行连接(使用作为服务器端的MAC地址进行连接)。当客户端和服务器端彼此拥有一个在同一个RFCOMM通道已连接的BluetoothSocket时便可以进行数据的交换。在每一端,都可以获得输入和输出流,从而可以开始数据的传输。该部分将在后文描述,本部分只描述如何初始化设备间的连接。

服务器端和客户端通过不同的方式获得BluetoothSocket。当一个连接接受(accept)的时候服务器端接收BluetoothSocket。而客户端则通过打开服务器端的RFCOMM通道得到BluetoothSocket。

一种实现技术是,应用程序同时实现客户端和服务器端。因此,每一个服务器端的程序拥有一个server socket并监听连接。当然,也可以在一个应用中实现服务器端的功能,而另一个应用中实现客户端的部分。

如果两个设备之前并没有配对过,那么Android的框架将会自动进行配对的请求通知。因此当尝试进行连接时,你的应用并不需要关心两台设备是否已经配对。你的RFCOMM连接将会被阻塞,直到用户成功配对,或因为用户拒绝配对而取消,或者配对失败以及超时等。

(3)服务器端

两个设备进行连接时,必须有一个设备通过BluetoothServerSocket作为服务器。该server socket的目的是监听未来的连接请求,并当该请求被接受时,提供一个已经连接的BluetoothSocket。当从BluetoothServerSocket获得BluetoothSocket时,BluetoothServerSocket必须被抛弃,除非你想要连接多个设备。

步骤如下:

通过调用listenUsingRfcommWithServiceRecord(String, UUID)获取BluetoothServerSocket。
String是你服务的可辨别名称。系统将会自动写入一个新的“服务发现协议(Service Discovery Protocol 简称SDP)”数据库入口至你的设备,该名称可随意命名,通常情况下是应用名称。UUID也包括SDP的入口,并作为和客户端连接基础。当客户端尝试连接至服务端设备时,将会带有想要连接设备的独一无二的UUID。这些UUID必须匹配,目的是为了能够使连接被接受。

可通过网络上的诸多UUID生成器来获得UUID的字符串,然后通过fromString(String)方法获得。

通过调用accept(),开始监听连接请求。
这是一个阻塞的调用,将会在抛出异常或者连接被接受时返回。连接只有在远程设备发送一个带有和服务器端已注册的UUID相匹配的连接请求时才会被接受。当连接成功时,accept()将会返回一个已经连接的BluetoothSocket。

除非你想要接受多个连接,否则的话,调用close()进行关闭。
这将会释放server socket以及相关的资源,但是并不会关闭从accept()中返回的,已经连接的BluetoothSocket。和TCP/IP不同,RFCOMM仅仅允许在一个通道中同时存在一个客户端。因此大多数情况下,在获得BluetoothSocket后立即调用close()是很有必要的。

accept()方法不应当在主线程(UI线程)中执行,因为这是一个阻塞的调用,能够租住任何和程序的交互。通常情况下和BluetoothServerSocket以及BluetoothSocket有关的任何操作都应该在新的线程中进行。在另外的线程中调用close()方法将会撤销该阻塞方法调用并立即返回。请注意,BluetoothServerSocket和BluetoothSokcet中的任何方法都是线程安全的。`private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;

public AcceptThread() {
    // Use a temporary object that is later assigned to mmServerSocket,
    // because mmServerSocket is final
    BluetoothServerSocket tmp = null;
    try {
        // MY_UUID is the app's UUID string, also used by the client code
        tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
    } catch (IOException e) { }
    mmServerSocket = tmp;
}

public void run() {
    BluetoothSocket socket = null;
    // Keep listening until exception occurs or a socket is returned
    while (true) {
        try {
            socket = mmServerSocket.accept();
        } catch (IOException e) {
            break;
        }
        // If a connection was accepted
        if (socket != null) {
            // Do work to manage the connection (in a separate thread)
            manageConnectedSocket(socket);
            mmServerSocket.close();
            break;
        }
    }
}

/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
    try {
        mmServerSocket.close();
    } catch (IOException e) { }
}

在例子中,一旦连接被接受并获得BluetoothSocket后,应用立即将该BluetoothSocket发送至独立的线程并关闭BluetoothSocket,挑出循环。

注意到,当accept()返回BluetoothSocket时,socket已经连接了,因此不应该调用connect方法。
manageConnectedSocket()是一个虚构的方法,用来初始化数据传输的线程,将在后文介绍数据传输的部分。

一旦监听到连接并获得BluetoothSocket时,应当立即调用close()关闭BluetoothServerSocket。cancel()则为此提供了一个公共的方法。

0
0
查看评论

蓝牙通信(二)

public class ClientBluetooth {  public void connectToServerSocket (BluetoothDevice device,UUID uuid){   try {    Blue...
  • xiaoqiangliu
  • xiaoqiangliu
  • 2014-02-24 15:37
  • 371

Android Bluetooth 蓝牙通信(二)

前面一篇文章实现了最简单的蓝牙通信,本篇文章对其进行优化。首先由于项目需求,将蓝牙的搜索和连接做成Dialog形式,并且在搜索过程中加入弹窗。其次,将蓝牙连接和数据发送改成Service,便于整个项目里使用,不局限于某个activity里。然后,由于之前Server端的线程是在onCreat里开启的...
  • AmazingUU
  • AmazingUU
  • 2017-01-09 21:35
  • 785

蓝牙通讯模块(C#)

 在Windows Mobile软件开发中.Net正扮演着日益重要的角色,我们已经可以看到很多用.Net CF开发的软件,这些软件涉及到了日常应用的方方面面。在智能设备的软件开发中,无线互联是一个相当重要的一块,我们可以看到,红外几乎是所有智能设备的标配,而蓝牙也日益在越来越多的智能设备上...
  • eddygong
  • eddygong
  • 2008-08-19 10:00
  • 3677

Android开发之蓝牙通信(二)

接着上篇蓝牙通信往下写,本篇准备深入理解蓝牙通信模块源码,若有不对还请指出,大家共同进步。
  • AnalyzeSystem
  • AnalyzeSystem
  • 2016-08-31 10:56
  • 2516

android 蓝牙通信(二)

实现功能:蓝牙配对在上篇的基础上,配对第一个找到的蓝牙设备 1、重写Handler中找到蓝牙设备后的逻辑/** 判断是否是第一个发现的蓝牙设备*/ private boolean hasFindOneDevice = false; case ACTION_FOND: ...
  • u012764110
  • u012764110
  • 2015-09-23 18:09
  • 1248

Windows蓝牙通信的开发

持续更新
  • qq_38446366
  • qq_38446366
  • 2017-10-23 16:30
  • 127

蓝牙通信

http://blog.csdn.net/shulianghan/article/details/11989681
  • shaohuazuo
  • shaohuazuo
  • 2013-10-23 22:43
  • 662

读Android蓝牙通信源码

我说的读android蓝牙通信源码并不是说,读google官方api,那个我也看了一下,里面全是英文倒不说,英文好的,直接无视掉。关键是代码写的我实在难以理解。当然,这也和我的阅读源码的能力有关联的。不过,幸好我在网上找到了一份开源的蓝牙通信的代码是menghnhhuan写的。大家想看他的源码可以直...
  • DucklikeJAVA
  • DucklikeJAVA
  • 2015-11-21 23:32
  • 863

android:手机之间蓝牙通信(二)

功能:扫描周围蓝牙设备,获取设备名称、地址等,并添加到ListView上面,并能够获取选中项,显示设备地址 搜索蓝牙 if (!mBluetoothAdapter.isDiscovering())//扫描蓝牙 {       mBluetoothAdapter.s...
  • bigtree_mfc
  • bigtree_mfc
  • 2016-08-11 12:01
  • 351

android:手机之间蓝牙通信(四)

功能:蓝牙设备通信连接。 蓝牙连接分为两种情况。 一、手机与手机间通信 二、手机与蓝牙模块通信。 注意:蓝牙通信使用了多线程,必须掌握线程的创建使用才能使用蓝牙进行通信。 手机与手机间通信: 手机间蓝牙通信使用客户端和服务端。 客户端:搜索设备找到服务端,和服务端配对,连接服务端。 服务端:等...
  • bigtree_mfc
  • bigtree_mfc
  • 2016-09-01 19:46
  • 614
    个人资料
    • 访问:4817次
    • 积分:303
    • 等级:
    • 排名:千里之外
    • 原创:24篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类