搜档网
当前位置:搜档网 › Android Bluetooth详解

Android Bluetooth详解

Android Bluetooth详解
Android Bluetooth详解

对于Android的英文帮助文档,总是看了记不住,远不如对中文资料那么印象深,所以下面的叙述都是对Android帮助文档Bluetooth的翻译。

一、Bluetooth

Android平台包含了对Bluetooth协议栈的支持,允许机器通过Bluetooth设备进行无线数据交换。应用框架通过Android Bluetooth API访问Bluetooth功能模块。这些API能让应用无线连接其他Bluetooth设备,实现点对点和多点之间的通信。

运用蓝牙API,Android应用程序可以完成如下操作:

1、扫描其他Bluetooth设备。

2、查询配对Bluetooth设备的本地Bluetooth适配器。

3、建立RFCOMM通道。

4、通过服务探索连接到其他设备。

5、与其他设备进行数据传输。

6、管理多个连接

二、The Basics

本文描述如何使用Android Bluetooth APIs完成Bluetooth通讯的4个必要任务:设置Bluetooth,搜寻本地配对或者可用的Bluetooth设备,连接Bluetooth设备,与Bluetooth 设备进行数据传输。

所有可用的Bluetooth APIs都包含在android.bluetooth包中。下面是建立Bluetooth连接需要用到的类和接口的总结:

1、BluetoothAdapter

描述本地Bluetooth适配器(Bluetooth接收器)。BluetoothAdapter是所有Bluetooth相关活动的入口。运用BluetoothAdapter可以发现其他Bluetooth设备,查询连接(或配对)的设备列表,用已知MAC地址实例化一个BluetoothDevice对象,创建一个BluetoothServerSocket对象侦听其他设备的通信。

2、BluetoothDevice

描述一个远程Bluetooth设备。可以用它通过一个BluetoothSocket请求一个远程设备的连接,或者查询远程设备的名称、地址、类、连接状态等信息。

3、BluetoothSocket

描述一个Bluetooth Socket接口(类似于TCP Socket)。应用通过InputStream和OutputStream.与另外一个Bluetooth设备交换数据,即它是应用与另外一个设备交换数据的连接点。

4、BluetoothServerSocket

描述一个开放的socket服务器,用来侦听连接进来的请求(类似于RCP ServerSocket)。为了连接两个Android设备,一个设备必须使用该类来开启一个socket做服务器,当另外一个设备对它发起连接请求时并且请求被接受时,BluetoothServerSocket会返回一个连接的BluetoothSocket对象。

5、BluetoothClass

描述一个Bluetooth设备的一般规格和功能。这个是用来定义设备类和它的服务的只读属性集。然而,它并不是可靠的描述设备支持的所有Bluetooth配置和服务,而只是一些设备类型的有用特征。

6、BluetoothProfile

描述Bluetooth Profile的接口。Bluetooth Profile是两个设备基于蓝牙通讯的无线接口描述。(对Bluetooth Profile的详细解释,来自百度:为了更容易的保持Bluetooth设备之间的兼容,Bluetooth规范中定义了Profile。Profile定义了设备如何实现一种连接或者应用,你可以把Profile理解为连接层或者应用层协议。比如,如果一家公司希望它们的Bluetooth芯片支援所有的Bluetooth耳机,那么它只要支持HeadSet Profile即可,而无须考虑该芯片与其它Bluetooth设备的通讯与兼容性问题。如果你想购买Bluetooth产品,你应该了解你的应用需要哪些Profile来完成,并且确保你购买的Bluetooth产品支持这些Profile。)7、BluetoothHeadset

提供移动电话的Bluetooth耳机支持。包括Bluetooth耳机和Hands-Free (v1.5) profiles。

8、BluetoothA2dp

定义两个设备间如何通过Bluetooth连接进行高质量的音频传输。

A2DP(Advanced Audio Distribution Profile):高级音频传输模式。

9、BluetoothProfile.ServiceListener

一个接口描述,在与服务连接或者断连接的时候通知BluetoothProfile IPC(这是内部服务运行的一个特定的模式)。

三、Bluetooth Permissions

要使用Bluetooth功能,至少需要2个Bluetooth权限:BLUETOOTH和

BLUETOOTH_ADMIN.

BLUETOOTH:用来授权任何Bluetooth通信,如请求连接,接受连接,传输数据等。BLUETOOTH_ADMIN:用来授权初始化设备搜索或操作Bluetooth设置。大多数应用需要

它的唯一场合是用来搜索本地Bluetooth设备。本授权的其他功能不应该被使用,除非是需要修改Bluetooth设置的“power manager(电源管理)”应用。

注意:需要BLUETOOTH_ADMIN权限的场合,BLUETOOTH权限也是必需的。

需要在manifest文件中声明Bluetooth权限,示例如下:

...

四、Setting Up Bluetooth

在用Bluetooth通讯之前,需要确认设备是否支持Bluetooth,如果支持,还得确保Bluetooth 是可用的。

如果设备不支持Bluetooth,需要优雅的将Bluetooth置为不可用。如果支持Bluetooth,但没有开启,可以在应用中请求开启Bluetooth。该设置使用BluetoothAdapter.通过两个步骤完成。

1、获取BluetoothAdapter

BluetoothAdapter是每个Bluetooth的Activity都需要用到的。用静态方法getDefaultAdapter()获取BluetoothAdapter,返回一个拥有Bluetooth 适配器的BluetoothAdapter对象。如果返回null,说明设备不支持Bluetooth,关于Bluetooth的故事到此就结束了(因为你干不了什么了)。示例:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

// Device does not support Bluetooth

}

2、Enable Bluetooth

接下来,就是确保Bluetooth功能是开启的。调用isEnabled()来检查Bluetooth当前是否是开启的。用ACTION_REQUEST_ENABLE action Intent调用startActivityForResult()来请求开启Bluetooth,这会通过系统设置发出一个Bluetooth使能请求(并且不会停止本应用程序)。示例:

if (!mBluetoothAdapter.isEnabled()) {

Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

用户请求使能Bluetooth时,会显示一个对话框。选择“Yes”,系统会使能Bluetooth,并且

焦点会返回你的应用程序。

如果使能Bluetooth成功,你的Activity会在onActivityResult()回调函数中收到RESULT_OK 的结果码。如果Bluetooth使能因发生错误(或用户选择了“No”)而失败,收到的结果码将是RESULT_CANCELED。

作为可选项,应用也可以侦听ACTION_STATE_CHANGED broadcast Intent,这样无论Bluetooth状态何时被改变系统都会发出broadcast(广播)。该广播包含附加的字段信息EXTRA_STATE和EXTRA_PREVIOUS_STATE分别代表新的和旧的Bluetooth状态,该字段可能的值为STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, 和STATE_OFF。应用运行时,侦听ACTION_STATE_CHANGED广播来检测Bluetooth状态的改变是很有用的。

提示:启用Bluetooth可被发现功能能够自动开启Bluetooth。如果在完成Activity之前需要持续的使能Bluetooth可被发现功能,那么上面的第2步就可以忽略。

五、Finding Devices

使用BluetoothAdapter可以通过设备搜索或查询配对设备找到远程Bluetooth设备。Device discovery(设备搜索)是一个扫描搜索本地已使能Bluetooth设备并且从搜索到的设备请求一些信息的过程(有时候会收到类似“discovering”,“inquiring”或“scanning”)。但是,搜索到的本地Bluetooth设备只有在打开被发现功能后才会响应一个discovery请求,响应的信息包括设备名,类,唯一的MAC地址。发起搜寻的设备可以使用这些信息来初始化跟被发现的设备的连接。

一旦与远程设备的第一次连接被建立,一个pairing请求就会自动提交给用户。如果设备已配对,配对设备的基本信息(名称,类,MAC地址)就被保存下来了,能够使用Bluetooth API来读取这些信息。使用已知的远程设备的MAC地址,连接可以在任何时候初始化而不必先完成搜索(当然这是假设远程设备是在可连接的空间范围内)。

需要记住,配对和连接是两个不同的概念:

配对意思是两个设备相互意识到对方的存在,共享一个用来鉴别身份的链路键(link-key),能够与对方建立一个加密的连接。

连接意思是两个设备现在共享一个RFCOMM信道,能够相互传输数据。

目前Android Bluetooth API's要求设备在建立RFCOMM信道前必须配对(配对是在使用Bluetooth API初始化一个加密连接时自动完成的)。

下面描述如何查询已配对设备,搜索新设备。

注意:Android的电源设备默认是不能被发现的。用户可以通过系统设置让它在有限的时间内可以被发现,或者可以在应用程序中要求用户使能被发现功能。

1、Querying paired devices

在搜索设备前,查询配对设备看需要的设备是否已经是已经存在是很值得的,可以调用getBondedDevices()来做到,该函数会返回一个描述配对设备BluetoothDevice的结果集。例如,可以使用ArrayAdapter查询所有配对设备然后显示所有设备名给用户:

Set pairedDevices = mBluetoothAdapter.getBondedDevices();

// If there are paired devices

if (pairedDevices.size() > 0) {

// Loop through paired devices

for (BluetoothDevice device : pairedDevices) {

// Add the name and address to an array adapter to show in a ListView

mArrayAdapter.add(device.getName() + "\n" + device.getAddress());

}

}

BluetoothDevice对象中需要用来初始化一个连接唯一需要用到的信息就是MAC地址。2、Discovering devices

要开始搜索设备,只需简单的调用startDiscovery()。该函数时异步的,调用后立即返回,返回值表示搜索是否成功开始。搜索处理通常包括一个12秒钟的查询扫描,然后跟随一个页面显示搜索到设备Bluetooth名称。

应用中可以注册一个带CTION_FOUND Intent的BroadcastReceiver,搜索到每一个设备时都接收到消息。对于每一个设备,系统都会广播ACTION_FOUND Intent,该Intent携带着而外的字段信息EXTRA_DEVICE和EXTRA_CLASS,分别包含一个BluetoothDevice 和一个BluetoothClass。下面的示例显示如何注册和处理设备被发现后发出的广播:

// Create a BroadcastReceiver for ACTION_FOUND

private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

// When discovery finds a device

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

// Get the BluetoothDevice object from the Intent

BluetoothDevice device =

intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// Add the name and address to an array adapter to show in a ListView

mArrayAdapter.add(device.getName() + "\n" + device.getAddress());

}

}

};

// Register the BroadcastReceiver

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy

警告:完成设备搜索对于Bluetooth适配器来说是一个重量级的处理,要消耗大量它的资源。一旦你已经找到一个设备来连接,请确保你在尝试连接前使用了cancelDiscovery()来停止搜索。同样,如果已经保持了一个连接的时候,同时执行搜索设备将会显著的降低连接的带宽,所以在连接的时候不应该执行搜索发现。

3、Enabling discoverability

如果想让本地设备被其他设备发现,可以带ACTION_REQUEST_DISCOVERABLE action Intent调用startActivityForResult(Intent, int) 方法。该方法会提交一个请求通过系统刚设置使设备出于可以被发现的模式(而不影响应用程序)。默认情况下,设备在120秒后变为可以被发现的。可以通过额外增加EXTRA_DISCOVERABLE_DURATION Intent自定义一个值,最大值是3600秒,0表示设备总是可以被发现的(小于0或者大于3600则会被自动设置为120秒)。下面示例设置时间为300:

Intent discoverableIntent = new

Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

startActivity(discoverableIntent);

询问用户是否允许打开设备可以被发现功能时会显示一个对话框。如果用户选择“Yes”,设备会在指定时间过后变为可以被发现的。Activity的onActivityResult()回调函数被调用,结果码等于设备变为可以被发现所需时长。如果用户选择“No”或者有错误发生,结果码会是Activity.RESULT_CANCELLED。

提示:如果Bluetooth没有启用,启用Bluetooth可被发现功能能够自动开启Bluetooth。

在规定的时间内,设备会静静的保持可以被发现模式。如果想在可以被发现模式被更改时受到通知,可以用ACTION_SCAN_MODE_CHANGED Intent注册一个BroadcastReceiver,包含额外的字段信息EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE分别表示新旧扫描模式,其可能的值为SCAN_MODE_CONNECTABLE_DISCOVERABLE (discoverable mode),SCAN_MODE_CONNECTABLE(not in discoverable mode but still able to receive connections),SCAN_MODE_NONE(not in discoverable mode and

unable to receive connections)。

如果只需要连接远程设备就不需要打开设备的可以被发现功能。只在应用作为一个服务器socket的宿主用来接收进来的连接时才需要使能可以被发现功能,因为远程设备在初始化连接前必须先发现了你的设备。

六、Connecting Devices

为了建立两个设备之间的应用的连接,需要完成服务器端和客户端,因为一个设备必须打开一个服务器socket而另外一个设备必须初始化连接(用服务器端的MAC地址)。服务器和客户端在各自获得一个基于同一个RFCOMM信道的已连接的BluetoothSocket对象后就被认为连接已经建立。这个时候,双方设备可以获取输入输出流,数据传输可以开始了。本节描述如何在两个设备之间初始化连接。

服务器设备和客户端设备用不同的方式获取各自需要的BluetoothSocket对象。服务器端的在接收一个进来的连接时获取到,客户端的在打开一个与服务器端的RFCOMM信道的时候获取到。

一个实现技巧是自动把每个设备作为服务器,这样就拥有了一个打开的socket用来侦听连接。然后任一设备就能够发起与另一个设备的连接,并成为客户端。另外,一个设备也可以明确的成为“host”,并打开一个服务端socket,另一个设备可以简单的发起连接。

注意:如果两个设备之前没有配对,那么在连接处理过程中Android应用框架会自动显示一个配对请求的通知或对话框给用户。因此,当尝试连接设备时,应用不需要关心设备是否已经配对。RFCOMM连接会阻塞直到用户成功将设备配对(如果用户拒绝配对或者配对超时了连接会失败)。

1、Connecting as a server

如果要连接两个设备,其中一个必须充当服务器,通过持有一个打开的BluetoothServerSocket对象。服务器socket的作用是侦听进来的连接,如果一个连接被接受,提供一个连接好的BluetoothSocket对象。从BluetoothServerSocket获取到BluetoothSocket对象之后,BluetoothServerSocket就可以(也应该)丢弃了,除非你还要用它来接收更多的连接。

下面是建立服务器socket和接收一个连接的基本步骤:

1.通过调用listenUsingRfcommWithServiceRecord(String, UUID)得到一个BluetoothServerSocket对象。

该字符串为服务的识别名称,系统将自动写入到一个新的服务发现协议(SDP)数据库接入口到设备上的(名字是任意的,可以简单地是应用程序的名称)项。UUID也包括在SDP 接入口中,将是客户端设备连接协议的基础。也就是说,当客户端试图连接本设备,它将携

带一个UUID用来唯一标识它要连接的服务,UUID必须匹配,连接才会被接受。

2.通过调用accept()来侦听连接请求。

这是一个阻塞的调用,知道有连接进来或者产生异常才会返回。只有远程设备发送一个连接请求,并且携带的UUID与侦听它socket注册的UUID匹配,连接请求才会被接受。如果成功,accept()将返回一个连接好的BluetoothSocket对象。

3.除非需要再接收另外的连接,否则的话调用close()。

close()释放server socket和它的资源,但不会关闭连接accept()返回的连接好的BluetoothSocket对象。与TCP/IP不同,RFCOMM同一时刻一个信道只允许一个客户端连接,因此大多数情况下意味着在BluetoothServerSocket接受一个连接请求后应该立即调用close()。

accept()调用不应该在主Activity UI线程中进行,因为这是个阻塞的调用,会妨碍其他的交互。经常是在在一个新线程中做BluetoothServerSocket或BluetoothSocket的所有工作来避免UI线程阻塞。注意所有BluetoothServerSocket或BluetoothSocket的方法都是线程安全的。

示例:

下面是一个简单的接受连接的服务器组件代码示例:

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给一个单独的线程,然后关闭BluetoothServerSocket并跳出循环。注意:accept()返回BluetoothSocket后,socket已经连接了,所以在客户端不应该呼叫connnect()。

manageConnectedSocket()是一个虚方法,用来初始化线程好传输数据。

通常应该在处理完侦听到的连接后立即关闭BluetoothServerSocket。在本例中,close()在得到BluetoothSocket后马上被调用。还需要在线程中提供一个公共的方法来关闭私有的BluetoothSocket,停止服务端socket的侦听。

2、Connecting as a client

为了实现与远程设备的连接,你必须首先获得一个代表远程设备BluetoothDevice对象。然后使用BluetoothDevice对象来获取一个BluetoothSocket来实现来接。

下面是基本的步骤:

1.用BluetoothDevice调用createRfcommSocketToServiceRecord(UUID)获取一个BluetoothSocket对象。

这个初始化的BluetoothSocket会连接到BluetoothDevice。UUID必须匹配服务器设备在打开BluetoothServerSocket 时用到的UUID(用listenUsingRfcommWithServiceRecord(String, UUID))。可以简单的生成一个UUID串然后在服务器和客户端都使用该UUID。

2.调用connect()完成连接

当调用这个方法的时候,系统会在远程设备上完成一个SDP查找来匹配UUID。如果查找成功并且远程设备接受连接,就共享RFCOMM信道,connect()会返回。这也是一个阻塞的调用,不管连接失败还是超时(12秒)都会抛出异常。

注意:要确保在调用connect()时没有同时做设备查找,如果在查找设备,该连接尝试会显著的变慢,慢得类似失败了。

实例:

下面是一个完成Bluetooth连接的样例线程:

private class ConnectThread extends Thread {

private final BluetoothSocket mmSocket;

private final BluetoothDevice mmDevice;

public ConnectThread(BluetoothDevice device) {

// Use a temporary object that is later assigned to mmSocket,

// because mmSocket is final

BluetoothSocket tmp = null;

mmDevice = device;

// Get a BluetoothSocket to connect with the given BluetoothDevice

try {

// MY_UUID is the app's UUID string, also used by the server code

tmp = device.createRfcommSocketToServiceRecord(MY_UUID);

} catch (IOException e) { }

mmSocket = tmp;

}

public void run() {

// Cancel discovery because it will slow down the connection

mBluetoothAdapter.cancelDiscovery();

try {

// Connect the device through the socket. This will block

// until it succeeds or throws an exception

mmSocket.connect();

} catch (IOException connectException) {

// Unable to connect; close the socket and get out

try {

mmSocket.close();

} catch (IOException closeException) { }

return;

}

// Do work to manage the connection (in a separate thread)

manageConnectedSocket(mmSocket);

}

/** Will cancel an in-progress connection, and close the socket */

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) { }

}

}

注意到cancelDiscovery()在连接操作前被调用。在连接之前,不管搜索有没有进行,该调用都是安全的,不需要确认(当然如果有要确认的需求,可以调用isDiscovering())。manageConnectedSocket()是一个虚方法,用来初始化线程好传输数据。

在对BluetoothSocket的处理完成后,记得调用close()来关闭连接的socket和清理所有的内部资源。

七、Managing a Connection

如果已经连接了两个设备,他们都已经拥有各自的连接好的BluetoothSocket对象。那就是一个有趣的开始,因为你可以在设备间共享数据了。使用BluetoothSocket,传输任何数据通常来说都很容易了:

1.通过socket获取输入输出流来处理传输(分别使用getInputStream()和getOutputStream())。

2.用read(byte[])和write(byte[])来实现读写。

仅此而已。

当然,还是有很多细节需要考虑的。首要的,需要用一个专门的线程来实现流的读写。只是很重要的,因为read(byte[])和write(byte[])都是阻塞的调用。read(byte[])会阻塞直到流中有数据可读。write(byte[])通常不会阻塞,但是如果远程设备调用read(byte[])不够快导致中间缓冲区满,它也可能阻塞。所以线程中的主循环应该用于读取InputStream。线程中也应该有单独的方法用来完成写OutputStream。

示例:

下面是一个如上面描述那样的例子:

private class ConnectedThread extends Thread {

private final BluetoothSocket mmSocket;

private final InputStream mmInStream;

private final OutputStream mmOutStream;

public ConnectedThread(BluetoothSocket socket) {

mmSocket = socket;

InputStream tmpIn = null;

OutputStream tmpOut = null;

// Get the input and output streams, using temp objects because

// member streams are final

try {

tmpIn = socket.getInputStream();

tmpOut = socket.getOutputStream();

} catch (IOException e) { }

mmInStream = tmpIn;

mmOutStream = tmpOut;

}

public void run() {

byte[] buffer = new byte[1024]; // buffer store for the stream

int bytes; // bytes returned from read()

// Keep listening to the InputStream until an exception occurs

while (true) {

try {

// Read from the InputStream

bytes = mmInStream.read(buffer);

// Send the obtained bytes to the UI Activity

mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)

.sendToTarget();

} catch (IOException e) {

break;

}

}

}

/* Call this from the main Activity to send data to the remote device */

public void write(byte[] bytes) {

try {

mmOutStream.write(bytes);

} catch (IOException e) { }

}

/* Call this from the main Activity to shutdown the connection */

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) { }

}

}

构造函数中得到需要的流,一旦执行,线程会等待从InputStream来的数据。当read(byte[])返回从流中读到的字节后,数据通过父类的成员Handler被送到主Activity,然后继续等待读取流中的数据。

向外发送数据只需简单的调用线程的write()方法。

线程的cancel()方法时很重要的,以便连接可以在任何时候通过关闭BluetoothSocket来终止。它应该总在处理完Bluetooth连接后被调用。

八、Working with Profiles

从Android 3.0开始,Bluetooth API就包含了对Bluetooth profiles的支持。Bluetooth profile 是基于蓝牙的设备之间通信的无线接口规范。例如Hands-Free profile(免提模式)。如果移动电话要连接一个无线耳机,他们都要支持Hands-Free profile。

你在你的类里可以完成BluetoothProfile接口来支持某一Bluetooth profiles。Android Bluetooth API完成了下面的Bluetooth profile:

Headset:Headset profile提供了移动电话上的Bluetooth耳机支持。Android提供了BluetoothHeadset类,它是一个协议,用来通过IPC(interprocess communication)控制Bluetooth Headset Service。BluetoothHeadset既包含Bluetooth Headset profile也包含Hands-Free profile,还包括对AT命令的支持。

A2DP:Advanced Audio Distribution Profile (A2DP) profile,高级音频传输模式。Android 提供了BluetoothA2dp类,这是一个通过IPC来控制Bluetooth A2DP的协议。

下面是使用profile的基本步骤:

1.获取默认的Bluetooth适配器。

2.使用getProfileProxy()来建立一个与profile相关的profile协议对象的连接。在下面的例子中,profile协议对象是BluetoothHeadset的一个实例。

3.设置BluetoothProfile.ServiceListener。该listener通知BluetoothProfile IPC客户端,当客户端连接或断连服务器的时候。

4.在onServiceConnected()内,得到一个profile协议对象的句柄。

5. 一旦拥有了profile协议对象,就可以用它来监控连接的状态,完成于该profile相关的其他操作。

例如,下面的代码片段显示如何连接到一个BluetoothHeadset协议对象,用来控制Headset profile:

BluetoothHeadset mBluetoothHeadset;

// Get the default adapter

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// Establish connection to the proxy.

mBluetoothAdapter.getProfileProxy(context, mProfileListener,

BluetoothProfile.HEADSET);

private BluetoothProfile.ServiceListener mProfileListener = new

BluetoothProfile.ServiceListener() {

public void onServiceConnected(int profile, BluetoothProfile proxy) {

if (profile == BluetoothProfile.HEADSET) {

mBluetoothHeadset = (BluetoothHeadset) proxy;

}

}

public void onServiceDisconnected(int profile) {

if (profile == BluetoothProfile.HEADSET) {

mBluetoothHeadset = null;

}

}

};

// ... call functions on mBluetoothHeadset

// Close proxy connection after use.

mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);

1、Vendor-specific AT commands

从Android 3.0开始,应用程序可以注册侦听预定义的Vendor-specific AT命令这样的系统广播(如Plantronics +XEVENT command)。例如,应用可以接收到一个广播,该广播表明连接的设备电量过低,然后通知用户做好其他需要的操作。创建一个带

ACTION_VENDOR_SPECIFIC_HEADSET_EVENT intent的broadcast receiver来为耳机处理

Vendor-specific AT commands。

Android蓝牙协议指南

Android蓝牙协议栈 Android蓝牙协议栈使用的是BlueZ,支持GAP, SDP, and RFCOMM规范,是一个SIG认证的蓝牙协议栈。 Bluez 是GPL许可的,因此Android的框架内与用户空间的bluez代码通过D-BUS进程通讯进行交互,以避免专有代码。 Headset和Handsfree(v1.5)规范就在Android框架中实现的,它是跟Phone App紧密耦合的。这些规范也是SIG认证的。 下面的图表提供了一个以库为导向的蓝牙栈视图。 实线框的是Android模块,红色虚线部分为合作伙伴指定模块(译者注:芯片商提供)。 下面的图表是以进程为导向视图:

移植 BlueZ是兼容蓝牙2.1的,可以工作在任何2.1芯片以及向后兼容的旧的蓝牙版本。有要有两个方面: ?串口驱动 UART driver ?蓝牙电源开/关 Bluetooth Power On/Off 串口驱动 BlueZ核心子系统使用hciattach守护进程添加你的指定硬件串口驱动。

例如,MSM7201A,这个文件是在drivers/serial/msm_serial.c。你还需要通过修改init.rc为hciattach来编辑命令 行选项。 蓝牙电源开/关 蓝牙芯片的电源开关方法1.0和Post 1.0是不同的,具体如下: ? 1.0:Android框架写0或1到/sys/modules/board_[PLATFORM]/parameters/bluetooth_power_on ?Post 1.0:Android框架使用linux rfkill API,参考 arch/arm/mach-msm/board-trout-rfkill.c例子。 编译 编译Android打开蓝牙支持,添加下面这行内容到BoardConfig.mk。 BOARD_HAVE_BLUETOOTH :=true 解决问题 调试 调试你的蓝牙实现,可以通过读跟蓝牙相关的logs(adb logcat)和查找ERROR和警告消息。Android使用Bluez,同时 会带来一些有用的调式工具。下面的片段为了提供一个建议的例子: hciconfig -a # print BT chipset address and features. Useful to check if you can communicate with your BT chipset. hcidump -XVt # print live HCI UART traffic. hcitool scan # scan for local devices. Useful to check if RX/TX works. l2ping ADDRESS # ping another BT device. Useful to check if RX/TX works. sdptool records ADDRESS # request the SDP records of another BT device. 守护进程日志 hcid(STDOUT)和hciattach(STDERR)的守护进程日志缺省是被写到/dev/null。编辑init.rc和init.PLATFORM.rc在logwrapper下运行这些守护进程,把它们输出到logcat。 hciconfig -a 和 hcitool

基于Android的蓝牙遥控小车设计

成绩评定表

课程设计任务书

阐述一种通过手机蓝牙遥控小车行走的软、硬件设计。手机蓝牙作为客户端,小车上的蓝牙模块HC-05作为服务端。客户端采用Eclipse 开发环境,J2ME编程,服务端采用单片机控制。双方通过串口仿真协议进行通信,单片机驱动直流电机控制小车行动。实验结果表明,小车可以接收手机遥控信号并灵活地进行前行、倒退、左转、右转和停止等功能。 关键词:89c52,hc-05,遥控小车,Andriod

目录 1引言 (1) 1.1课题设计目的及意义 (1) 1.1.1设计的目的 (1) 1.1.2设计的意义 (2) 2 方案比较与论证 (2) 2.1无线单元方案与比较 (2) 3 硬件电路设计 (4) 3.1 总体设计 (4) 3.2 单片机模块 (5) 3.2.1 STC89C52简介 (5) 3.2.2 L298N驱动模块及原理介绍 (6) 3.2.3 蓝牙模块 (7) 4 软件设计 (8) 4.1 智能车运动控制程序 (8) 4.2 Android蓝牙客户端设计与实现 (9) 4.2.1 客户端界面设计 (10)

4.2.2 BluetoothCar类设计 (10) 4.2.3 单片机C语言代码 (10) 5 实验结果及分析 (16) 6 心得体会 (17) 参考文献 (17)

1引言 1.1课题设计目的及意义 1.1.1设计的目的 遥控小车起源于美国,由于政府对无线遥控小车研发的资助以及相关资助的推动作用,日本、美国、德国等工业大国在遥控小车技术上占据着明显优势。我国的无线遥控小车研究工作始于20世纪中后期,在国家的863、973等技术发展计划的重点支持下,国内已大范围地进行无线遥控小车的研究。在研发应用方面取得了重要发展,但是与国际先进还存在一定的差距。无线遥控实现方法包括蓝牙、红外、射频几种,其中蓝牙技术具有一定优势。目前在信息家电方面应用正在铺。遥控小车起源于美国,由于政府对无线遥控小车研发的资助以及相关资助的推动作用,日本、美国、德国等工业大国在遥控小车技术上占据着明显优势。我国的无线遥控小车研究工作始于20世纪中后期,在国家的863、973等技术发展计划的重点支持下,国内已大范围地进行无线遥控小车的研究。在研发应用方面取得了重要发展,但是与国际先进还存在一定的差距。无线遥控实现方法包括蓝牙、红外、射频几种,其中蓝牙技术具有一定优势。目前在信息家电方面应用正在铺开。各种家电共用遥控,并可组网与公众互联网相接,共享有用信息。目前蓝牙技术实现无线遥控的短板在于传输距离短和芯片

Android蓝牙编程

ANDROID 蓝牙编程 用BluetoothAdapter类,你能够在Android设备上查找周边的蓝牙设备然后配对(绑定),蓝牙通讯是基于唯一地址MAC来相互传输的,考虑到安全问题Bluetooth通讯时需要先配对。然后开始相互连接,连接后设备将会共享同一个RFCOMM通道以便相互传输数据,目前这些实现在Android 2.0或更高版本SDK 上实现。 一、查找发现 findding/discovering devices 对于Android查找发现蓝牙设备使用BluetoothAdapter类的startDiscovery()方法就可以执行一个异步方式获取周边的蓝牙设备,因为是一个异步的方法所以我们不需要考虑线程被阻塞问题,整个过程大约需要12秒时间,这时我们紧接着注册一个 BroadcastReceiver 对象来接收查找到的蓝牙设备信息,我们过滤ACTION_FOUND这个 Intent动作来获取每个远程设备的详细信息,通过附加参数在Intent字段EXTRA_DEVICE 和 EXTRA_CLASS, 中包含了每个BluetoothDevice 对象和对象的该设备类型BluetoothClass ,示例代码 private final BroadcastReceiver cwjReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); myArrayAdapter.add(device.getName() + " android123 " + device.getAddress()); //获取设备名称和mac地址 } } }; // 注册这个 BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(cwjReceiver, filter); 最后android123提醒大家需要注意的是,记住在Service或Activity中重写onDestory()方法,使用unregisterReceiver方法反注册这个BroadcastReceiver对象保证资源被正确回收。 一些其他的状态变化有 ACTION_SCAN_MODE_CHANGED 额外参数 EXTRA_SCAN_MODE 和 EXTRA_PREVIOUS_SCAN_MODE以及SCAN_MODE_CONNECTABLE_DISCOVERABLE、 SCAN_MODE_CONNECTABLE和SCAN_MODE_NONE, 蓝牙模块 二、配对绑定 bnded/paired device 在Android中配对一个蓝牙设备可以调用BluetoothAdapter类的getBondedDevices()方法可以获取已经配对的设备,该方法将会返回一个BluetoothDevice数组来区分每个已经配对的设备,示例代码如下: Set pairedDevices = cwjBluetoothAdapter.getBondedDevices();

Android手机蓝牙通信设计 RFCOMM协议客户端+语音传送与接收

手机蓝牙通信设计RFCOMM协议客户端+语音传送与接收 最近作相关蓝牙RFCOMM协议的东西,下面类主要是针对蓝牙串口协议的客户端,其中包含了设备的搜索,服务的搜索,以及MMAPI函数的应用,希望通过这个类,能让初学者掌握基本的设备的搜索,服务的搜索,和蓝牙串口协议以及录音和语音发送播放等: 注意HelloMidlet midlet为一个基础设计的界面类,用来调用ClientBox 类 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.*; import java.util.V ector; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import https://www.sodocs.net/doc/dd10796444.html,mand; import https://www.sodocs.net/doc/dd10796444.html,mandListener; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Gauge; import javax.microedition.lcdui.StringItem; import javax.microedition.lcdui.TextField; //jsr082 API import javax.bluetooth.BluetoothStateException; import javax.bluetooth.DeviceClass; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.DiscoveryListener; import javax.bluetooth.LocalDevice; import javax.bluetooth.RemoteDevice; import javax.bluetooth.ServiceRecord; import javax.bluetooth.UUID; import hello.HelloMidlet; import java.io.InputStream; // import javax.microedition.media.*; import javax.bluetooth.DataElement; /** * 客户端GUI */ public class ClientBox extends Form. implements Runnable, CommandListener, DiscoveryListener {

Android蓝牙功能及RFCOMMSDP简介

A n d r o i d蓝牙功能及R F C O M M S D P简介文件管理序列号:[K8UY-K9IO69-O6M243-OL889-F88688]

A n d r o i d2.0蓝牙功能及R F C O M M、S D P简介一.Android2.0蓝牙功能简介 Google于2009年10月28日发布了AndroidSDK2.0版本。对于开发人员来说,最关心的莫过于新版本添加了哪些新特性,API有哪些改动。2.0版本发布前,最受关注的就是能否在新版本中添加蓝牙功能。Google果然不负众望,在2.0版本中加入了蓝牙功能,使Android平台功能更加强大。蓝牙模块实现了以下功能: 蓝牙的打开/关闭。 设备和服务的探索。 使用RFCOMM连接远程设备发送/接收数据。 公布RFCOMM服务和监听接入的RFCOMM连接。 新版本添加了android.bluetooth包。该包提供了一些用于管理蓝牙设备的功能类。蓝牙的APIs允许应用程序连接或断开headset(头戴式耳机),扫描其他蓝牙设备并与之配对。增强了写和修改本地服务发现协议(ServiceDiscoveryProtocol,SDP)数据库,查询其他蓝牙设备SDP数据库,在Android上建立RFCOMM通道/Socket,连接到其他设备指定Socket的控制。 注意:不是所有的Android设备都能保证有蓝牙功能。 下面是android.bluetooth包中类的简述: BluetoothAdapter代表本地蓝牙适配器。 可以使用getDefaultAdapter()方法获得默认的本地蓝牙适配 器。

Android平台蓝牙通信的实现

Android平台蓝牙通信的实现 一、Android蓝牙概况 1.蓝牙的来历 蓝牙这个名称来自于第十世纪的一位丹麦国王哈拉尔蓝牙王,Blatand 在英文里的意思可以被解释为Bluetooth( 蓝牙)因为国王喜欢吃蓝莓,牙龈每天都是蓝色的所以叫蓝牙。在行业协会筹备阶段,需要一个极具有表现力的名字来命名这项高新技术。行业组织人员,在经过一夜关于欧洲历史和未来无线技术发展的讨论后,有些人认为用Blatand 国王的名字命名再合适不过了。Blatand 国王将挪威,瑞典和丹麦统一起来;他的口齿伶俐,善于交际,就如同这项即将面世的技术,技术将被定义为允许不同工业领域之间的协调工作,保持着各个系统领域之间的良好交流,例如计算机,手机和汽车行业之间的工作。名字于是就这么定下来了。 Blatand 国王 蓝牙的创始人是爱立信公司,爱立信早在1994 年就已进行研发。1997 年,爱立信与其他设备生产商联系,并激发了他们对该项技术的浓厚兴趣。1998 年2 月,跨国大公司包括诺基亚、苹果、三星组成的一个特殊兴趣小组(SIG),他们共同的目标是建立一个全球性的小范围无线通信技术,即蓝牙。而蓝牙这个标志的设计:它取自Harald Bluetooth 名字中的「H」和「B」两个字母,用古北欧字母来表示,将这两者结合起来,就成为了蓝牙的logo (见图)。

蓝牙logo 2.蓝牙开发概况 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少 Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发 现如今,蓝牙已是每部安卓手机标配的功能,多用于蓝牙耳机和传输文件,还可以多部手机之间建立蓝牙通信,本文就通过参考SDK自带的一个BluetoothChat的例程,开发一个新的蓝牙聊天室。 在Android1 的时候,相关API 非常不完善,还不能简单的使用Bluetooth 开发,有一个开源项目可以帮助程序员使用、开发蓝牙,支持直接方法bluetooth 协议栈。在Android2 以后,框架提供了一些官方API 来进行蓝牙的通信,但目前的程序也比较不完善。本文主要讨论Android2 蓝牙通信的API 使用方法。 首先看聊天效果图: 二、Android编程介绍 (一)编程环境 Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

基于Android的蓝牙In-band ring功能的实现

龙源期刊网 https://www.sodocs.net/doc/dd10796444.html, 基于Android的蓝牙In-band ring功能的实现 作者:陈媛媛 来源:《中国新通信》2016年第08期 【摘要】蓝牙作为一种短距无线数据与语音传输的开放性全球规范,目前在整个世界范 围内都得到了很广泛的应用。它可以支持便携式计算机、移动终端以及其他电子设备之间通过建立无线电空中接口相互通信,可以方便地进行数据和语音传输。Android是基于Linux的移动操作系统,目前在终端市场占据了70%的市场份额,应用相当广泛。本文通过研究Android 系统以及蓝牙协议栈,在现有架构基础上平台实现了in-band ring功能。 【关键字】蓝牙 Android in-band ring 一、引言 蓝牙(Bluetooth)技术规范由蓝牙特别兴趣小组(SIG)制订,在使用通用无线传输模块和数据通信协议的基础上,开发交互式服务和应用,多用于便携式通信设备。 整个蓝牙协议体系结构自上而下分为高端应用层、中间协议层和底层硬件模块,结构如图1所示。 蓝牙协议栈最上层为应用层,它对应于各种应用模型的剖面(Profile)。 中间协议层由逻辑链路控制与适配协议、服务发现协议、串口仿真协议和电话控制协议等规范组成。它是蓝牙协议栈的核心部分,主要实现了逻辑链路控制与适配协议实现数据的拆装、服务质量的控制和协议复用等功能,为上层协议的实现提供相应的基础。服务发现协议主要为上层应用程序提供一种发现网络中可用的服务及其特性的特殊机制;串口仿真协议是为运行在不同设备上的两个应用程序建立一条完整的通信路径,并保持两个设备之间有一个通信段;电话控制协议则提供蓝牙设备间话音和数据的呼叫控制指令[1]。 蓝牙射频、基带层和链路管理层构成蓝牙的底层模块。蓝牙射频用于实现数据位流的过滤和无线传输;基带层主要控制跳频和蓝牙数据信息帧的传输;链路管理层则用于建立和拆除链路,以及链接的安全和控制。它们共同为上层软件模块提供相应的访问接口。两个模块之间的数据的传输必须通过蓝牙主机控制器接口(HCI)的解释才能进行[2]。

Android+2.0+蓝牙功能及RFCOMM、SDP简介

Android 2.0 蓝牙功能及RFCOMM、SDP简介 一.Android 2.0蓝牙功能简介 Google 于2009年10月28日发布了Android SDK 2.0版本。对于开发人员来说,最关心的莫过于新版本添加了哪些新特性,API有哪些改动。2.0版本发布前,最受关注的就是能否在新版本中添加蓝牙功能。Google果然不负众望,在2.0版本中加入了蓝牙功能,使Android平台功能更加强大。蓝牙模块实现了以下功能: ?蓝牙的打开/关闭。 ?设备和服务的探索。 ?使用RFCOMM连接远程设备发送/接收数据。 ?公布RFCOMM服务和监听接入的RFCOMM连接。 新版本添加了android.bluetooth包。该包提供了一些用于管理蓝牙设备的功能类。蓝牙的APIs允许应用程序连接或断开headset(头戴式耳机),扫描其他蓝牙设备并与之配对。增强了写和修改本地服务发现协议(Service Discovery Protocol ,SDP)数据库,查询其他蓝牙设备SDP数据库,在Android上建立RFCOMM通道/Socket,连接到其他设备指定Socket 的控制。 注意:不是所有的Android设备都能保证有蓝牙功能。 下面是android.bluetooth包中类的简述:

Android蓝牙模型原理及设备之间的连接已再【eoeAndroid特刊】第六期中有所说明,在此不做赘述。详情请参见【eoeAndroid特刊】第六期4-6节。 二.协议简述 蓝牙规范(Specification of the Bluetooth System)就是蓝牙无线通信协议标准,它规定了蓝牙应用产品应遵循的标准和需要达到的要求。蓝牙协议规范遵循开放系统互连参考模型(Open System Interconnetion/Referenced Model, OSI/RM),从低到高地定义了蓝牙协议堆栈的各个层次。 在蓝牙规范中,中介协议是为高层应用协议或程序在蓝牙逻辑链路上工作提供了必要的支持,为应用曾提供了各种不同的标准接口。这部分协议包括RFCOMM、SDP、IrDA、(PPP/IP/TCP/UDP)、(TCS/AT)等。 2.1 串口仿真协议(RFCOMM) 基于欧洲电信标准化协会(European Telecommunication Standardization Institute, ETSI)的TS07.10标准制定。该协议用于模拟串行接口环境,使得基于串口的传统应用仅作少量的修改或者不做任何修改可以直接在该层上运行。 通过提供串行端口仿真,RFCOMM 可以同时支持遗留串行端口应用程序以及其它应用程序中的OBEX 协议。RFCOMM 是ETSI TS 07.10 标准的一个子集,也具有一些蓝牙特定的适配性。 RFCOMM 协议能在两台蓝牙设备之间同时维持多达60 个连接。蓝牙设备中同时使用的连接数目取决于特定实施。 由于有了RFCOMM,完整的通信路径包括两个运行在不同设备(通信端点)上的应用程序及它们之间的通信段。上图显示了完整的通信路径 RFCOMM 旨在覆盖利用串行端口设备的应用程序。在简单的配置中,通信段是一个设

ANDROID蓝牙编程

ANDROID蓝牙编程 用BluetoothAdapter类,你能够在Android设备上查找周边的蓝牙设备然后配对(绑定),蓝牙通讯是基于唯一地址MAC来相互传输的,考虑到安全问题Bluetooth通讯时需要先配对。然后开始相互连接,连接后设备将会共享同一个RFCOMM通道以便相互传输数据,目前这些实现在Android 2.0或更高版本SDK 上实现。 一、查找发现 findding/discovering devices 对于Android查找发现蓝牙设备使用BluetoothAdapter类的startDiscovery()方法就可以执行一个异步方式获取周边的蓝牙设备,因为是一个异步的方法所以我们不需要考虑线程被阻塞问题,整个过程大约需要12秒时间,这时我们紧接着注册一个 BroadcastReceiver 对象来接收查找到的蓝牙设备信息,我们过滤ACTION_FOUND这个 Intent动作来获取每个远程设备的详细信息,通过附加参数在Intent字段EXTRA_DEVICE 和 EXTRA_CLASS, 中包含了每个BluetoothDevice 对象和对象的该设备类型 BluetoothClass ,示例代码 private final BroadcastReceiver cwjReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); myArrayAdapter.add(device.getName() + " android123 " + device.getAddress()); //获取设备名称和mac地址 } } }; // 注册这个 BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(cwjReceiver, filter); 最后android123提醒大家需要注意的是,记住在Service或Activity中重写onDestory()方法,使用unregisterReceiver方法反注册这个BroadcastReceiver对象保证资源被正确回收。 一些其他的状态变化有 ACTION_SCAN_MODE_CHANGED 额外参数 EXTRA_SCAN_MODE 和 EXTRA_PREVIOUS_SCAN_MODE以及 SCAN_MODE_CONNECTABLE_DISCOVERABLE、 SCAN_MODE_CONNECTABLE和 SCAN_MODE_NONE, 蓝牙模块

基于Android与BLE的蓝牙通信系统的实现

基于Android与BLE的蓝牙通信系统的实现 高科技电子行业的发展,引领了可穿戴设备的风潮,人们越发追求于其低功耗和稳定性。文章實现了一个基于Android和BLE的蓝牙通信系统,除了能通过蓝牙连接Android手机进行通信以及强大的低耗能优势以外,还对BLE连接流程进行了优化,提高了硬件和软件之间的蓝牙通信性能。 标签:BLE;Android;蓝牙通信 Abstract:The development of high-tech electronic industry leads the trend of wearable devices,and people increasingly pursue its low power consumption and stability. In this paper,a Bluetooth communication system based on Android and BLE is implemented. In addition to being able to communicate with Android mobile phone through Bluetooth and powerful low energy consumption advantage,the flow of BLE connection is optimized,improving Bluetooth communication performance between hardware and software. Keywords:BLE;Android;Bluetooth communication 引言 自从“可穿戴设备”这个名词进入人们的视线,越来越多的消费者愿意去尝试这项新技术,在巨大利益的推动下,对可穿戴设备的研究也如火如荼地展开。目前可穿戴设备的技术还不够成熟,功能强大的设备无法独立使用,很多功能需要配合手机软件才能够完成,因此设备与App之间的通信成为人们重点关注的对象。目前,大多数的可穿戴设备和App的通信都是使用蓝牙作为数据传输方式,而Android系统亦是目前手机最流行的操作系统,故本文开发了一个基于Android 的蓝牙通信系统。 蓝牙分为低功耗蓝牙和经典蓝牙,低功耗蓝牙,即BLE,对应的是蓝牙4.0及以上版本。经典蓝牙又分为传统蓝牙和高速蓝牙,高速蓝牙指的是3.0版本,蓝牙3.0以下版本属于传统蓝牙[1]。低功耗蓝牙与经典蓝牙相比,它的通信距离从10米扩展到100米,发送数据所需的时间也从100ms降至3ms,相应延时也从100ms降至6ms。虽然数据传输速率还无法与高速蓝牙相比,但在耗能方面,极大体现了低功耗蓝牙的价值,能够以极低的运行和待机功耗使一粒纽扣电池连续工作数年之久,此外,它还有低成本和跨厂商的互操作性[2],所以低功耗蓝牙将是可穿戴设备更好的选择。数据同步成功率是设备与App之间蓝牙通信性能的一大体现,很多网络上的Android App与各种设备的数据同步成功率不到80%,如何提高设备和App之间的蓝牙通信性能,也是BLE应用开发者关注的重点。 BLE在待机功耗和运行功耗上的特点符合当今可穿戴设备的发展需求,在未来一段时间,它将占据可穿戴设备通信的主流市场。本系统基于Android 4.3

Android蓝牙功能及RFCOSDP简介

A n d r o i d2.0蓝牙功能及R F C O M M、S D P简介 一.Android2.0蓝牙功能简介 Google于2009年10月28日发布了AndroidSDK2.0版本。对于开发人员来说, 最关心的莫过于新版本添加了哪些新特性,API有哪些改动。2.0版本发布前,最受 关注的就是能否在新版本中添加蓝牙功能。Google果然不负众望,在2.0版本中加 入了蓝牙功能,使Android平台功能更加强大。蓝牙模块实现了以下功能: ?蓝牙的打开/关闭。 ?设备和服务的探索。 ?使用RFCOMM连接远程设备发送/接收数据。 ?公布RFCOMM服务和监听接入的RFCOMM连接。 新版本添加了android.bluetooth包。该包提供了一些用于管理蓝牙设备的功能类。蓝牙的APIs允许应用程序连接或断开headset(头戴式耳机),扫描其他蓝牙设备并与之配对。增强了写和修改本地服务发现协议(ServiceDiscoveryProtocol,SDP)数据库,查询其他蓝牙设备SDP数据库,在Android上建立RFCOMM通道/Socket,连接到其他设备指定Socket的控制。 注意:不是所有的Android设备都能保证有蓝牙功能。 下面是android.bluetooth包中类的简述:

Android蓝牙模型原理及设备之间的连接已再【eoeAndroid特刊】第六期中有所说明,在此不做赘述。详情请参见【eoeAndroid特刊】第六期4-6节。 二.协议简述 蓝牙规范(SpecificationoftheBluetoothSystem)就是蓝牙无线通信协议标准,它规定了蓝牙应用产品应遵循的标准和需要达到的要求。蓝牙协议规范遵循开放系

Android蓝牙开发(整理)

Android蓝牙开发 学习之前先了解两个基本概念: 1.RFCOMM协议: 一个基于欧洲电信标准协会ETSI07.10规程的串行线性仿真协议。此协议提供RS232控制和状态信号,如基带上的损坏,CTS以及数据信号等,为上层业务(如传统的串行线缆应用)提供了传送能力。 RFCOMM是一个简单传输协议,其目的是针对如何在两个不同设备上的应用之间保证一条完整的通信路径,并在它们之间保持一通信段。 RFCOMM是为了兼容传统的串口应用,同时取代有线的通信方式,蓝牙协议栈需要提供与有线串口一致的通信接口而开发出的协议。RFCOMM协议提供对基于L2CAP协议的串口仿真,基于ETSI07.10。可支持在两个BT设备之间同时保持高达60路的通信连接。 RFCOMM只针对直接互连设备之间的连接,或者是设备与网络接入设备之间的互连。通信两端设备必须兼容于RFCOMM协议,有两类设备:DTE (Data Terminal Endpoint,通信终端,如PC,PRINTER)和DCE (Data Circuit Endpoint,通信段的一部分,如Modem)。此两类设备不作区分。 2.MAC硬件地址 MAC(Medium/MediaAccess Control, 介质访问控制)MAC地址是烧录在NetworkInterfaceCard(网卡,NIC)里的.MAC地址,也叫硬件地址,是由48比特长(6字节),16进制的数字组成.0-23位叫做组织唯一标志符(organizationally unique,是识别LAN(局域网)节点的标识.24-47位是由厂家自己分配。其中第40位是组播地址标志位。网卡的物理地址通常是由网卡生产厂家烧入网卡的EPROM(一种闪存芯片,通常可以通过程序擦写),它存储的是传输数据时真正赖以标识发出数据的电脑和接收数据的主机的地址。 Android平台提供的蓝牙API去实现蓝牙设备之间的通信,蓝牙设备之间的通信主要包括了四个步骤:设置蓝牙设备、寻找局域网内可能或者匹配的设备、连接设备和设备之间的数据传输。以下是建立蓝牙连接的所需要的一些基本类: BluetoothAdapter类:代表了一个本地的蓝牙适配器。它是所有蓝牙交互的的入口点。利用它你可以发现其他蓝牙设备,查询绑定了的设备,使用已知的MAC地址实例化一个蓝牙设备和建立一个BluetoothServerSocket(作为服务器端)来监听来自其他设备的连接。 BluetoothDevice类:代表了一个远端的蓝牙设备,使用它请求远端蓝牙设备连接或者获取远端蓝牙设备的名称、地址、种类和绑定状态(其信息是封装在BluetoothSocket中)。 BluetoothSocket类:代表了一个蓝牙套接字的接口(类似于TCP中的套接字),它是应用程序通过输入、输出流与其他蓝牙设备通信的连接点。 BlueboothServerSocket类:代表打开服务连接来监听可能到来的连接请求(属于server 端),为了连接两个蓝牙设备必须有一个设备作为服务器打开一个服务套接字。当远端设备发起连接连接请求的时候,并且已经连接到了的时候,BlueboothServerSocket类将会返回一个BluetoothSocket。 BluetoothClass类:描述了一个蓝牙设备的一般特点和能力。它的只读属性集定义了设备的主、次设备类和一些相关服务。然而,它并没有准确地描述所有该设备所支持的蓝牙文件和服务,而是作为对设备种类来说的一个小小暗示。

基于安卓的蓝牙通信系统开发

目录 一、系统背景 (2) 1.1 Android系统概述 (2) 1.2 蓝牙概述 (3) 二、系统分析 (5) 2.1 需求分析 (5) 2.2 技术基础 (5) 2.3 平台搭建 (8) 2.4 运行环境 (11) 三、系统总体设计 (12) 3.1 设计思想 (12) 3.2 设计框架 (13) 四、程序设计 (16) 4.1 设置蓝牙权限 (16) 4.3 设置蓝牙可见 (16) 4.4 查询已配对蓝牙设备 (17) 4.5 扫描周围蓝牙设备 (17) 4.6 服务器端的连接 (18) 4.7 客户端的连接 (19) 4.8 数据通信线程 (20) 五、系统测试 (22) 六、设计体会 (26)

一、系统背景 1.1 Android系统概述 自从2008年9月22日,美国运营商T-Mobile USA在纽约正式发布了第一款基于android安卓的手机后,更多的移动设备厂商看到了安卓android的光明前景,并纷纷加入其中,android甚至已经涉足上网本市场了其发展前景广阔涉及领域越来越大。随着android手机的普及,android应用的需求势越来越大,这个潜力巨大的市场,已经吸引无数软件开发厂商和开发者投身其中。android 的开放性使其比苹果和黑莓对年轻人更具吸引力,更能吸引年轻人群的关注和喜爱。在18岁至24岁族群中,Android是最多人选用的操作系统。同时因为Android 系统的开放性为Android平板电脑的快速发展奠定了基础,也才能促使其吸引着越来越多的用户接受和使用。同时Android还具有应用程序无界限、应用程序是在平的的条件下创建的、应用程序可以轻松的嵌入网络、应用程序可以并行运行等众多出色的品质。具有其他操作系统无法比拟的优势和发展空间。 安卓系统在不断升级完善,如今,平板电脑市场已成为Android与苹果IOS 除了智能手机领域之外争夺的第二个焦点。一直以来,多数新闻仍然显示iPad 在平板市场的霸主地位难撼。但是,以Android领头的平板电脑正以高速的增长对苹果iPad造成冲击。放眼整个平板市场,生产Android平板电脑的确是大势所趋。世界上所有的顶级设备制造商,三星、索尼、摩托罗拉、联想、LG、宏碁、HTC、华硕,几乎每一家都在卖Android平板电脑。 安卓给用户的触屏体验非常好,安卓手机在高端机领域泛滥的同时也在中低端机领域涉足,这将给安卓系统手机带来非常好的前景,从目前的市场上来看,安卓系统能够在短短的时间里面,占据着超大的市场份额,而且还有非常好的信誉口碑,绝对不是一两个人吹捧出来的,那是因为安卓手机真的能够让人体验到好,才能够有如此高的评价。所以说,虽然目前安卓手机还是存在一定问题上的不足,很多问题都有待需要改善,这就说明安卓系统处于一种发展状态,那么它的生命力就会很强,前景很广阔。 Android是一套真正意义的开放性移动设备综合平台,它包括操作系统、中间件和一些关键的平台应用。Android的Java程序运行环境包含一组Java核心函数库及Dalvik虚拟机,他们有效地优化了Java程序的运行过程。Android系

相关主题