基础:
这篇文档描述了怎么使用Android Bluetooth APIs完成数据交换的四个主要的任务:创建Bluetooth,找到本地区域可用的蓝牙设备或匹配的蓝牙设备,连接设备,传输数据。
所有的Bluetooth APIs都在android.bluetooth包下。下面是创建蓝牙连接需要实现的类和接口:
BluetoothAdapter:
表示本地的蓝牙适配器。BluetoothAdapter是所有蓝牙交换的接入点。使用它,你可以发现其他的蓝牙设备,查找一些匹配的设备,用MAC地址来实例化一个BluetoothDevice。创建一个BluetoothServerSocket来监听其他设备,进而和它们进行通信。
BluetoothDevice:
表示远程的蓝牙设备。用它通过BluetoothSocket来请求与远程的设备进行连接。后者查询设备的基本信息,例如名称,地址,类或者结合的状态。
BluetoothSocket:
表示一个Bluetooth socket接口(与TCP socket相似)。它是一个连接点,运行设备通过InputStream和OutputStream的形式来交换数据。
BluetoothServiceSocket:
表示一个打开服务socket,用来监听收到的请求(与TCP server socket相似)。为了连接设备,一个设备必须打开服务socket。当一个远程的设备请求连接的时候,当连接被接收的时候,BluetoothServiceSocket返回一个BluetoothSocket。
BluetoothClass:
描述蓝牙设备的一般特征和性能。这是个只读的一系列属性。定义了主要和最小的设备类和服务。然而,它描述的设备属性和和服务是不完全可靠的,但是,在表示设备类型时,它是有用的。
BluetoothProfile:
一个代表蓝牙属性的接口。指基于无线蓝牙交流的无线接口规则。
BluetoothHeadset:
提供在手机手机上使用蓝牙耳机的支持。
BluetoothA2dp:
定义什么样的数据可以在蓝牙之间传递。
BluetoothProfiles.ServiceListener:
当蓝牙设备连接或者断开时,用它来通知BluetoothProfiles IPC客户端。它是一个接口。
蓝牙权限:
为了使用蓝牙,你必须在你的应用程序中声明权限。
<manifest ...
>
<uses-permission
android:name="android.permission.BLUETOOTH"
/>
...
</manifest>
两种权限:BLUETOOTH和BLUETOOTH ADMIN.
当使用BLUETOOTH ADMIN时,一定要声明BLUETOOTH。
创建Bluetooth:
1.得到BluetoothAdaper。
BluetoothAdapter mBluetoothAdapter
= BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter
== null)
{
// Device does not support Bluetooth
}
如何不为null,说明本机可用蓝牙设备。
2.使用Bluetooth。
if (mBluetoothAdapter.isEnabled())
{
Intent enableBtIntent
= new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
查看匹配的设备:
Set<BluetoothDevice> 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());
}
}
发现设备:
// 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
连接设备:
做为一个服务者:
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)
{ }
}
}
做为客户端:
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)
{ }
}
}
管理连接:
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)
{ }
}
}