zoukankan      html  css  js  c++  java
  • Android 蓝牙*

     添加权限:

    <uses-permission Android:name="android.permission.BLUETOOTH_ADMIN"/>

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

    • 客户端

    开启蓝牙:

    void openBT(){
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter!= null){
            if (!mBluetoothAdapter.isEnabled()){
                mBluetoothAdapter.enable();
            }
        }
    }

    搜索蓝牙: 

    @OnClick(R.id.btSearch)
    public void startSearch(View view){
        if(mBluetoothAdapter!= null &&mBluetoothAdapter.isEnabled()){
            if (!mBluetoothAdapter.isDiscovering()){
                mBluetoothAdapter.startDiscovery();
            }
        }
    }

    开启搜索是异步操作,发现设备后会发送广播,所以要定义广播接收者

    在接收到广播后,获取广播里的蓝牙数据

    private class BTBroadCastRev extends BroadcastReceiver{
        @Override
        public void onReceive(Context context,Intent intent) {
            String strAction = intent.getAction();
            if (strAction.equals(BluetoothDevice.ACTION_FOUND)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                mArrDevice.add(device);
                mAdapter.notifyDataSetChanged();
            }else if(strAction.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
                Log.d("qfonReceive","搜索完成");
            }
        }
    }

    //注册广播接收者

    myReceive = new BTBroadCastRev();
    IntentFilter ifFind = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    this.registerReceiver(myReceive,ifFind);
    IntentFilter ifFinishFind = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    this.registerReceiver(myReceive,ifFinishFind);

    连接蓝牙,并开启发送数据线程:

    /**
     * 点击item,连接对应的蓝牙设备
     */
    protected void connectBT() {
        mLvDevice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent,View view, int position, longid) {
                MyClientTask task = newMyClientTask();
                task.execute(mArrDevice.get(position));
            }
        });
    }
    
    class MyClientTask extends AsyncTask<BluetoothDevice,Void,Void>{
        @Override
        protected void doInBackground(BluetoothDevice... devices) {
            BluetoothDevice device = devices[0];
            try {
                //使用安全连接,服务端也要一样使用安全连接,UUID也要跟服务器的监听UUID一致
                BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
                socket.connect();
                Log.d("qfdoInBackground_client","连接成功,开始发送数据");
                byte[] btMsg =new String("Hello").getBytes();
                socket.getOutputStream().write(btMsg,0,btMsg.length);
            } catch(Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    uuid可以通过uuidgen生成,生成结果类似以下结构:

    5D3D5E52-338A-47B8-9F10-27ADF89E204E

    • 服务端

    开启蓝牙,跟客户端一样启动服务线程

    new RevTask().execute();
    class RevTask extends AsyncTask<Void,Void,String>{
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            tvMsg.setText(s);
        }
    
        @Override
        protected String doInBackground(Void... params) {
            try {
                Log.d("qfdoInBackground","开始监听");
                //要跟客户端uuid一致
                BluetoothServerSocket sevSocket =mBluetoothAdapter.listenUsingRfcommWithServiceRecord("blue_service",MY_UUID_SECURE);
                BluetoothSocket socket = sevSocket.accept();
                if(socket != null){
                    Log.d("qfdoInBackground","连接成功");
                    InputStream stream = socket.getInputStream();
                    byte[] btRead =new byte[1024];
                    int iLength = stream.read(btRead);
                    Log.d("qfdoInBackground","读取数据成功"+iLength);
                    String strMsg =new String(btRead,"utf-8");
                    Log.d("qfdoInBackground",strMsg);
                   return strMsg;
                }else{
                    Log.d("qfdoInBackground","失败");
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.d("qfdoInBackground","异常");
            }
            return null;
        }
    }

    上述代码没有实现配对,对应经典蓝牙通信,最好先进行配对再连接,已经配对的蓝牙设备可以直接通过adapter获取到

    //得到所有已经配对的蓝牙适配器对象

    Set<BluetoothDevice> devices = adapter.getBondedDevices();            

    没有配对的蓝牙设备,可以在扫描设备的广播通知中判断,点击设备连接时,判断是否已经配对,如果已经配对,直接连接,如果没有配对,先配对:

    if (btDev.getBondState() == BluetoothDevice.BOND_NONE) {  
      //利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice);  
      Method createBondMethod = BluetoothDevice.class.getMethod("createBond");  
      Log.d("BlueToothTestActivity", "开始配对");  
      returnValue = (Boolean) createBondMethod.invoke(btDev);  
    }else if(btDev.getBondState() == BluetoothDevice.BOND_BONDED){  
      connect(btDev);  
    }  

    配对结果也会通过广播传递结果信息:

    // 注册Receiver来获取蓝牙设备相关的结果  
            IntentFilter intent = new IntentFilter();  
            intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver来取得搜索结果  
            intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);  
            intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);  
            intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);  
            registerReceiver(searchDevices, intent); 

     

    if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)){  
       device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  
        switch (device.getBondState()) {  
          case BluetoothDevice.BOND_BONDING:  
                Log.d("BlueToothTestActivity", "正在配对......");  
                break;  
           case BluetoothDevice.BOND_BONDED:  
                Log.d("BlueToothTestActivity", "完成配对");  
                connect(device);//连接设备  
                break;  
           case BluetoothDevice.BOND_NONE:  
                Log.d("BlueToothTestActivity", "取消配对");  
           default:  
                break;  
    }  
  • 相关阅读:
    HackingLab-再加密一次你就得到key啦~
    操作系统理论细节 2
    操作系统理论细节 1
    各种调度算法均衡利弊
    Github实现代码高亮
    Oracle 生成一张测试表并插入随机的个人基本信息数据
    一,Spring Boot 入门
    关于IDEA2020年1月新版MAVEN无法自动导入依赖
    操作系统存储管理--虚拟内存地址和物理内存地址
    apache2.4 tomcat 出现502 Proxy Error错误
  • 原文地址:https://www.cnblogs.com/chenxibobo/p/6076478.html
Copyright © 2011-2022 走看看