Android开发——传统蓝牙通信

1.前言

         应学校课程要求学习传统蓝牙和手机app之间通信,实现的最终结果为:传统蓝牙模块通过串口实现和手机app之间的消息互发

2.开发环境

         华为p20(android 8.1) AndroidStudio 3.2

         经过测试发现有的手机搜索蓝牙设备需要开启location权限,在华为上我的手机没有开启也可以进行搜索,另外还需要动态的允许权限

       

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

      if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},1);
            }

3.搜索设备

          在搜索设备之前首先先判断自己的手机是否是支持蓝牙的,其次有没有打开蓝牙,最后再搜索设备

     BluetoothAdapter  蓝牙适配器  代表移动设备的本地的蓝牙适配器

          BluetoothDevice     代表远程的一个蓝牙设备

          BluetoothSocket     代表蓝牙的一个socket接口,是一个连接点,用于连接设备通过inputstream和outputsream通信

  

          

adapter=BluetoothAdapter.getDefaultAdapter();//获取本地蓝牙设备
if(adapter!=null){
    if(!adapter.isEnabled()){  //判断是否开启了蓝牙,如何未开启执行开启操作
        Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivity(intent);
    }

}else{
    //不支持蓝牙
}

   因为搜索蓝牙是通过广播的形式,手机向周围设备发送广播,app中编写广播过滤器,接着对接收到的广播(返回为BluetoothDevice)进行进行处理,如加入到ListView中用于显示所有搜到的设备

IntentFilter intentFilter=new IntentFilter(BluetoothDevice.ACTION_FOUND);
final BroadcastReceiver broadcastReceiver=new BluetoothReceiver();
registerReceiver(broadcastReceiver,intentFilter);//注册过滤器




public class BluetoothReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                   //此处可以执行加入List中操作
                }
            }
        }
    }

  当前面的操作都设置好了,之后就可以开始搜索设备啦,记得刚才获取到的本地adapter吗,只要用他就可以了,调用后,就会在广播接收器里面收到device了

adapter.startDiscovery();

当你点击不需要搜索之后记得关闭搜索哦

adapter.cancelDiscovery()

4.配对设备

          当获取到很多设备之后你可能显示在ListView中了,当你点击其中一个之后,接着编写配对的代码,想要配对她,那必须获取到他的BluetoothDevice对把,如何你List存的是BluetoothDevice,那就可以直接进行连接,如何存的是Mac地址,那就再用过Mac地址获取到BluetoothDevice,总之你得获取到她的BluetoothDevice

    //通过mac地址获取Device
    //device=adapter.getRemoteDevice(address);

    Method method=BluetoothDevice.class.getMethod("createBond");
    method.invoke(device);

5.连接设备

         配对成功后通过指定串口通信的UUID和设备进行socket连接

         

    private static final UUID My_UUID =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");   
    BluetoothSocket socket=device.createRfcommSocketToServiceRecord(My_UUID);
    socket.connect();

6.接收数据

      连接成功后即可通过socket对象获取inputstream和outputstream,接收数据可以通过inputstream对象读取蓝牙从串口发送过来的信息,接收数据需要开启一个线程不断的监听数据的获取

      

 class ReceiveThread extends Thread{

        String buffer="";
        @Override
        public void run() {
            while(socket!=null ){
                //定义一个存储空间buff
                byte[] buff=new byte[2048];
                try {
                    inputStream = socket.getInputStream();
                    inputStream.read(buff); //读取数据存储在buff数组中
                    processBuffer(buff,2048);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        private void processBuffer(byte[] buff,int size){
            int length=0;
            for(int i=0;i<size;i++){
                if(buff[i]>'\0'){
                    length++;
                }
                else{
                    break;
                }
            }
            byte[] newbuff=new byte[length];  //newbuff字节数组,用于存放真正接收到的数据
            for(int j=0;j<length;j++){
                newbuff[j]=buff[j];
            }
           //此处可对newbuff数据进行操作,如显示在界面上
        }
    }

7.发送数据

           发送数据这里是写了一个异步的类,主要就是一句话,先通过socket获取到outputstream,然后再往里面写入数据就行了,必须是byte类型的

class SendInfoTask extends AsyncTask<String,String,String> {
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
        }
        @Override
        protected String doInBackground(String... arg0) {
            if (arg0[0].length() > 0)//不是空白串
            {
                byte[] msgBuffer = arg0[0].getBytes();
                try {
                    //  将msgBuffer中的数据写到outStream对象中
                    outputStream.write(msgBuffer);

                } catch (IOException e) {

                }

            }
        }
    }
发布了73 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/daguniang123/article/details/90512355