Android 与蓝牙模块通信

前言

安卓小白,想了解一下蓝牙通信,就做了这个东西

蓝牙模块

采用的是HC-05型号的蓝牙模块
在这里插入图片描述
usb-ttl蓝牙模块 连接
VCC接VCC GND接GND Tx Rx交叉连接
在这里插入图片描述
使用串口助手调试 波特率为9600

发送AT,返回OK  说明已经连接成功(需要加回车换行)

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问答,按他的写法可以连接成功。
原贴找不到了 尴尬,先在这里感谢一下那位大佬

发布了13 篇原创文章 · 获赞 2 · 访问量 1114

猜你喜欢

转载自blog.csdn.net/AneTist/article/details/92410617