• Android 蓝牙学习


    Android 蓝牙学习


    学习缘由

    上个礼拜公司要开发个简单的五子棋游戏!其中一个需求就是支持蓝牙对战!所以苦逼的我学习蓝牙方面的知识了!

    简介

    • Bluetooth是目前使用最广泛的无线通讯协议,近距离无线通讯的标准。传说瑞典有个国王特别爱吃蓝莓导致自己的牙齿天天都是蓝色的,在他执政期间这位国王非常善于交际,能说会到,和邻国的搞得关系非常好,这个Bluetooth的发明者觉得蓝牙它的作用就是在近距离沟通周围的设备,跟这个国王很类似,于是起名叫蓝牙。

    • 主要针对短距离设备通讯(10米)

    • 无线耳机,无线鼠标,无线键盘

    Android 中的使用

    蓝牙 API 简单简介

    • BluetoothAdapter (蓝牙本地适配器)

      1. cancelDiscovery() 停止当前搜索蓝牙的 Task
      2. disable() 关闭蓝牙
      3. enable() 打开蓝牙
      4. getAddress() 得到本地蓝牙适配器的地址
      5. getBondedDevices() 得到已经绑定的蓝牙的设备
      6. getDefaultAdapter() 得到本地蓝牙适配器
      7. getName() 得到本地蓝牙的名称
      8. getRemoteDevice(byte[] address) 得到远程蓝牙设备
      9. getRemoteDevice(String address) 得到远程蓝牙设备
      10. isEnabled() 判断蓝牙是否打开
      11. setName(String name) 设置蓝牙名称
      12. startDiscovery() 开始搜多附近蓝牙
      13. listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid) 创建 BluetoothServerSocket
    • BluetoothDevice

      1. createBond() 蓝牙配对 (低版本不支持,>=api19)
      2. createRfcommSocketToServiceRecord(UUID uuid) 创建 BluetoothSocket
      3. getBondState() 得到配对的状态
      4. getAddress() 得到远程蓝牙适配器的地址
      5. getName() 得到远程蓝牙的名称
    • BluetoothSocket 与 BluetoothServerSocket

      这两个 API 和Socket 和ServerSocket 差不多 这里不予介绍

      *** 当然了,Android 中蓝牙相关的API还很多!这里我只说了几个常用的!!!! ***

    Android 中的实战

    ** 现在我们就按照正常的逻辑来走! **

    第一步

    我们要先得到 蓝牙本地适配器,来判断设备是否支持蓝牙!

        mAdapter=BluetoothAdapter.getDefaultAdapter();
        //判断设备是否支持蓝牙
        if (mAdapter==null){
            Toast.makeText(this, "不支持蓝牙", Toast.LENGTH_SHORT).show();
        }
    
    第二步

    好了!现在下面要做的就是判断蓝牙是否打开了!没有打开则打开!

    	if (!mAdapter.isEnabled()){//蓝牙没有打开
          //  mAdapter.enable();//不支持这样写,影响用户体验
    
            //建议使用这种方式
            Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, 200);
        }
    

    代码写得很清楚!我就不解释啦!!!

    第三步

    成功打开蓝牙之后,要想别人的适配上能够发现,我们得设置蓝牙的可见性,现在我就来设置蓝牙的可见性!看代码

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==200){
            Intent dis=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            dis.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
            startActivity(dis);
        }
    }
    

    不知大家有没有注意到,我是在 onActivityResult(int requestCode, int resultCode, Intent data) 这个回调函数中设置蓝牙可见性的!因为我们在打开蓝牙的时候用了 startActivityForResult(Intent intent,int requestCode) 这个方法!还有一点大家也要注意 就是蓝牙在设置可见性的时候,有个时常。就是这个字段 BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION 对应的值!这个最大值是300秒!

    第四步

    至此,我们就可以搜索附近的蓝牙啦!那么有同学会问了,我们怎么知道有设备被搜索到呢?这个很简单哦!但我们搜索到设备的时候,系统就会给我们发送广播啦!我们只有注册个广播接收器就行啦!

      mAdapter.startDiscovery();//开始搜索
     
     //注册蓝牙广播接收器。
     IntentFilter filter = new IntentFilter();
     filter.addAction(BluetoothDevice.ACTION_FOUND);//发现蓝牙动作
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束动作
     filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//搜素开始动作
     registerReceiver(blueReceiver, filter);
     
     /**
     * 蓝牙接收器
     **/
    public class BlueReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
                BluetoothDevice device = 						intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                deviceList.add(device);
                adapter.notifyDataSetChanged();
            }
            if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
    				
            }
            if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
    
            }
        }
    }
    

    BlueReceiver 中我只是简单的把搜索到得设备放到集合中。被没有做过多的操作!

    第五步

    现在到了比较重要的步骤了!当我们搜索到了蓝牙的之后,我要配对,因为只有在配对之后才能连接哦!

      BluetoothDevice device = (BluetoothDevice) adapter.getItem(i);
      if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//是否已配对
             connect(device);
       } else {
          
                  try {
            		Method boned=device.getClass().getMethod("createBond");
            		boolean isok= (boolean) boned.invoke(device);
            		if(isok)
            		{
            			 connect(device);
            		}
        		  } catch (Exception e) {
           				 e.printStackTrace();
            			
        		  }
             
      }
    

    这里,我想说明的是就是这个配对,在 API19 之后 createBond() Android对外提供了这个方法!但是在 API19 以前并没有提供这个方法,所以呢我只能用反射了!这个兼容性比较好奥!!

    第六步

    现在,就很简答啦!只要连接就行啦!在这里我放在了一个线程中了!

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
    
        public ConnectThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
    
            try {
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                Log.e(TAG, "create() failed", e);
            }
            mmSocket = tmp;
        }
    
        @Override
        public void run() {
            Log.i(TAG, "BEGIN mConnectThread");
            setName("ConnectThread");
    
            mAdapter.cancelDiscovery();
            try {
    
                mmSocket.connect();
    
            } catch (IOException e) {
                connectionFailed();
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() socket during connection failure", e2);
                }
                BlueToothService.this.start();
                return;
            }
    
            synchronized (BlueToothService.this) {
                mConnectThread = null;
            }
    
            connected(mmSocket, mmDevice);//这里是另外一个读取数据的线程,这里就和socket操作一样了
            write("start".getBytes());
        }
    
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect socket failed", e);
            }
        }
    }
    

    ** 好啦!如果你读到这里 就也就学会了蓝牙的简单操作了! **

  • 相关阅读:
    python学习笔记(2)
    数据分析工具pandas
    python学习笔记(1)
    python学习笔记(3)
    python学习笔记(2):科学计算及数据可视化入门
    python学习笔记(1):python基础
    js setTimeout 和 setInterval 区别
    C#根据URL生成签名
    jquery.validate.js客户端验证
    redis学习(一)
  • 原文地址:https://www.cnblogs.com/likeandroid/p/4603724.html
Copyright © 2020-2023  润新知