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;  
}  

 

posted @ 2016-04-29 09:50  chenxibobo  阅读(401)  评论(0编辑  收藏  举报