基本功能
- 扫描其他蓝牙设备
- 查询本地蓝牙适配器的配对蓝牙设备
- 建立 RFCOMM 通道
- 通过服务发现连接到其他设备
- 与其他设备进行双向数据传输
在清单文件AndroidManifest中声明蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
如果应用适配 Android 9(API 级别 28)或更低版本,可以声明 ACCESS_COARSE_LOCATION 权限而非 ACCESS_FINE_LOCATION 权限。
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:background="@drawable/img_1"
android:orientation="vertical"
android:padding="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_openBT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/rain"
android:text="打开蓝牙"/>
<TextView
android:id="@+id/text_state2"
android:layout_marginLeft="40dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:text="蓝牙未打开"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_marginTop="10dp"
android:id="@+id/btn_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/rain"
android:text="查看设备"/>
<TextView
android:layout_marginTop="10dp"
android:id="@+id/text_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:textColor="@color/white"
android:text="@string/connect_state"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_marginTop="10dp"
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/rain"
android:text="发送消息"/>
<EditText
android:id="@+id/text_Edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:hint="发送的内容"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_marginTop="10dp"
android:id="@+id/btn_receive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/rain"
android:text="接收消息"/>
<TextView
android:layout_marginTop="10dp"
android:id="@+id/text_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="40dp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:text="收到的消息:"/>
</LinearLayout>
<ListView
android:layout_marginTop="10dp"
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/white"
/>
</LinearLayout>
Android 3.0 开始,Bluetooth API 便支持使用蓝牙配置文件。
使用配置文件: 1.获取默认适配器BlueToothDeviceAdapter.java:
public class BlueToothDeviceAdapter extends ArrayAdapter<BluetoothDevice> {
private final LayoutInflater mInflater;
private int mResource;
public BlueToothDeviceAdapter(Context context, int resource) {
super(context, resource);
mInflater = LayoutInflater.from(context);
mResource = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(mResource, parent, false);
}
TextView name = (TextView) convertView.findViewById(R.id.device_name);
TextView info = (TextView) convertView.findViewById(R.id.device_info);
BluetoothDevice device = getItem(position);
name.setText(device.getName());
info.setText(device.getAddress());
return convertView;
}
}
设置获取蓝牙配对过的设备(因此在APP连接时需要配对一次)
private void getBoundedDevices() {
//获取已经配对过的设备
Set<BluetoothDevice> pairedDevices = bTAdatper.getBondedDevices();
//将其添加到设备列表中
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
adapter.add(device);
}
}
}
设置连接函数
private void connectDevice(BluetoothDevice device) {
text_state.setText(getResources().getString(R.string.connecting));
try {
//创建Socket
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(BT_UUID);
//启动连接线程
connectThread = new ConnectThread(socket, true);
connectThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
设置连接线程
private class ConnectThread extends Thread {
private BluetoothSocket socket;
private boolean activeConnect;
InputStream inputStream;
OutputStream outputStream;
private ConnectThread(BluetoothSocket socket, boolean connect) {
this.socket = socket;
this.activeConnect = connect;
}
@Override
public void run() {
try {
//如果是自动连接 则调用连接方法
if (activeConnect) {
socket.connect();
}
text_state.post(new Runnable() {
@Override
public void run() {
text_state.setText(getResources().getString(R.string.connect_success));
}
});
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int bytes;
while (true) {
//读取数据
bytes = inputStream.read(buffer);
if (bytes > 0) {
final byte[] data = new byte[bytes];
System.arraycopy(buffer, 0, data, 0, bytes);
text_msg.post(new Runnable() {
@Override
public void run() {
text_msg.setText(getResources().getString(R.string.get_msg)+new String(data));
}
});
}
}
} catch (IOException e) {
e.printStackTrace();
text_state.post(new Runnable() {
@Override
public void run() {
text_state.setText(getResources().getString(R.string.connect_error));
}
});
}
}
/**
* 发送数据
*
* @param msg
*/
public void sendMsg(final String msg) {
byte[] bytes = msg.getBytes();
if (outputStream != null) {
try {
//发送数据
outputStream.write(bytes);
text_msg.post(new Runnable() {
@Override
public void run() {
text_msg.setText(getResources().getString(R.string.send_msgs)+msg);
}
});
} catch (IOException e) {
e.printStackTrace();
text_msg.post(new Runnable() {
@Override
public void run() {
text_msg.setText(getResources().getString(R.string.send_msg_error)+msg);
}
});
}
}
}
}
设置监听线程
private class ListenerThread extends Thread {
private BluetoothServerSocket serverSocket;
private BluetoothSocket socket;
@Override
public void run() {
try {
serverSocket = bTAdatper.listenUsingRfcommWithServiceRecord(
NAME, BT_UUID);
while (true) {
//线程阻塞,等待别的设备连接
socket = serverSocket.accept();
text_state.post(new Runnable() {
@Override
public void run() {
text_state.setText(getResources().getString(R.string.connecting));
}
});
connectThread = new ConnectThread(socket, false);
connectThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试下代码结果:
|