前言
安卓小白,想了解一下蓝牙通信,就做了这个东西
蓝牙模块
采用的是HC-05型号的蓝牙模块
用 usb-ttl 与 蓝牙模块 连接
VCC接VCC GND接GND Tx Rx交叉连接
使用串口助手调试 波特率为9600
android端
先上效果图
界面搭建
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:background="#199fff"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<TextView
android:id="@+id/show_connection_device"
android:text="未连接"
android:layout_marginLeft="20dp"
android:textColor="#ffffff"
android:textSize="25sp"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/show_menu_list"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:src="@drawable/menu_img"
android:layout_width="30dp"
android:layout_height="30dp" />
</RelativeLayout>
<include layout="@layout/content_main" />
</LinearLayout>
content_main.xml 界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/message_text"
android:singleLine="true"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_weight="1"
android:hint="输入命令"
android:textSize="16sp"
android:layout_gravity="center"
android:background="@null"
android:layout_width="wrap_content"
android:layout_height="35dp" />
<Button
android:id="@+id/send_message"
android:text="发送"
android:textColor="#199fff"
android:background="@drawable/translate"
android:layout_width="50dp"
android:layout_height="35dp" />
</LinearLayout>
<View
android:background="#199fff"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="match_parent"
android:layout_height="1dp"/>
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
主要代码
//搜索设备
private void blue_tooth_search(){
devices.clear();
strings.clear();
if (bluetoothAdapter.isDiscovering())
bluetoothAdapter.cancelDiscovery();
bluetoothAdapter.startDiscovery();
}
//获取已配对列表
private void blue_tooth_pair_list(){
Log.i("main_aa","已配对列表");
deviceList.clear();
stringList.clear();
Set<BluetoothDevice> devices=bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device:devices){
Log.i("main_aa",device.getName()+" "+device.getAddress());
deviceList.add(device);
stringList.add(device.getName());
}
View view=LayoutInflater.from(this).inflate(R.layout.matchlist,null);
ListView show_match_list=view.findViewById(R.id.show_match_list);
final AlertDialog aDialog=new AlertDialog.Builder(this)
.setView(view)
.setCancelable(true)
.create();
show_match_list.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,stringList));
show_match_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
connect(deviceList.get(position),position);
aDialog.dismiss();
show_connection_device.setText("正在连接");
}
});
aDialog.show();
}
//蓝牙连接
static final int CONNECT_FAILED=1;
static final int CONNECT_SUCCESS_TWO=6;
static final int CONNECT_SUCCESS=5;
public void connect(final BluetoothDevice device, final int position){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
BluetoothSocket tmp = null;
Method method;
try {
method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
tmp = (BluetoothSocket) method.invoke(device, 1);
} catch (Exception e) {
setState(CONNECT_FAILED);
Log.e("main_aa", e.toString());
}
socket = tmp;
try {
socket.connect();
setState(CONNECT_SUCCESS);//连接成功
oStream=socket.getOutputStream();
runOnUiThread(new Runnable() {
@Override
public void run() {
show_connection_device.setText(stringList.get(position));
}
});
getMessage();//开启接收消息线程
} catch (IOException e) {
setState(CONNECT_FAILED);
try {
if (isConnection)
oStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Log.e("main_aa", e.toString());
}
}
});
new Thread(thread).start();
}
private void setState(int mes){
Message message=new Message();
message.what=mes;
handler.sendMessage(message);
}
@SuppressLint("HandlerLeak")
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CONNECT_FAILED:
Log.i("main_aa","连接失败");
try {
socket.connect();
Log.i("main_aa","二次连接");
} catch (Exception e) {
Log.e("main_aa", e.toString());
}
Toast.makeText(MainActivity.this,"连接失败,设备可能关闭或距离过远,请重新连接",Toast.LENGTH_SHORT).show();
show_connection_device.setText("未连接");
break;
case CONNECT_SUCCESS:
Log.i("main_aa","连接成功");
isConnection=true;
break;
case CONNECT_SUCCESS_TWO:
Log.i("main_aa","2ok");
break;
}
}
};
广播接收器
public class BlueToothReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
//发现设备
case BluetoothDevice.ACTION_FOUND:{
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED){
Log.i("main_aa", "设备 " + device.getName()+" "+ device.getAddress());
if (TextUtils.isEmpty(device.getName())) {
strings.add("未命名 "+device.getAddress());
devices.add(device);
}else {
devices.add(device);
strings.add(device.getName());
}
}
}break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:{
Log.i("main_aa","搜索完成/蓝牙设备开启/关闭");
list_view.setAdapter(new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,strings));
dialog.dismiss();
}break;
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:{
Log.i("main_aa","开始搜索");
}break;
}
}
}
收发消息
//发送消息
private void sendMessage(String text){
byte[]str=text.getBytes();
try {
oStream.write(str);
message_text.setText("");
} catch (IOException e) {
e.printStackTrace();
Log.i("main_aa","发送失败 "+e.getMessage());
}
}
//接收消息
private void getMessage(){
new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
iStream=socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(iStream));
String Mydata = bufferedReader.readLine();
Log.i("main_aa",Mydata);
} catch (Exception e) {
try {
iStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
Log.i("main_aa","Error "+e.getMessage());
e.printStackTrace();
}
}
}
}).start();
}
最后连接已配对的蓝牙,如果蓝牙连接成功,蓝牙模块的led会闪烁两次
发送数据,串口助手接收正常
遇到的坑
无法连接 :在蓝牙连接时候一直报错
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
网上找了很多办法,但一个个试过后都不行,具体解决是看了个CSDN问答,按他的写法可以连接成功。
原贴找不到了 尴尬,先在这里感谢一下那位大佬