android 藍牙SPP協議通信


准備

1.藍牙串行端口基於SPP協議(Serial Port Profile),能在藍牙設備之間創建串口進行數據傳輸 
2.SPP的UUID:00001101-0000-1000-8000-00805F9B34FB 
3.Android手機一般以客戶端的角色主動連接SPP協議設備

連接流程

1.檢測藍牙狀態 
若藍牙未打開,則打開藍牙~

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();


@Override
protected void onResume() {
    super.onResume();
    if (!bluetoothAdapter.isEnabled()) {
        // open blueTooth
        Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
        finish();
        return;
    }
}

 

 

2.注冊設備搜索廣播信息 
使用registerReceiver注冊broadcastReceiver來獲取搜索設備等消息

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, intentFilter);
// receiver
private final BroadcastReceiver receiver = new BroadcastReceiver(){
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // find a device
            BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                //未配對設備
                newDeviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }else {
                //已經配對過的設備
                TextView tvPaired = (TextView)findViewById(R.id.tv_paired);
                tvPaired.setVisibility(View.VISIBLE);
                lvPairedDevices.setVisibility(View.VISIBLE);
                pairedDeviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
            }
            Log.i(TAG,"name:" + device.getName() + " address"+ device.getAddress());
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action){
            // search finish
            Log.i(TAG, "search finish!");
        }
    }
};

 

 

3.使用BlueAdatper搜索 
使用bluetoothAdapter搜索設備,bluetoothAdapter.startDiscovery()在搜索過程中,系統會發出三個廣播信息: 
ACTION_DISCOVERY_START:開始搜索 
ACTION_DISCOVERY_FINISHED:搜索結束 
ACTION_FOUND:找到設備

@Override
public void onClick(View v) {
    if (bluetoothAdapter.isDiscovering()) {
        bluetoothAdapter.cancelDiscovery();
    }
    bluetoothAdapter.startDiscovery();
}

 

4.獲取搜索到的藍牙設備信息 
在BroadcastReceiver的onReceive()里取得搜索到的藍牙設備信息(如名稱,MAC,RSSI) 
5.通過藍牙設備的MAC地址來建立一個BluetoothDevice對象:

BluetoothDevice romoteDevice = bluetoothAdapter.getRemoteDevice(mDeviceAddress);

 

6.由BluetoothDevice衍生BluetoothSocket 
通過BluetoothSocket的createRfcommSocketToServiceRecord()方法來選擇連接的協議/服務,這里用的是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB)

try {
    bluetoothSocket = romoteDevice.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
} catch (IOException e) {
    e.printStackTrace();
    Toast.makeText(this, "socket init failed", Toast.LENGTH_SHORT).show();
}

 

 

7.使用BluetoothSocket來連接、讀寫藍牙設備 
讀寫可以歸到一個獨立線程去實現~

try {
    bluetoothSocket.connect();
    Toast.makeText(this, "connect success", Toast.LENGTH_SHORT).show();
} catch (IOException e2) {
    e2.printStackTrace();
    Toast.makeText(this, "connect failed", Toast.LENGTH_SHORT).show();
    try {
        bluetoothSocket.close();
        bluetoothSocket = null;
    } catch (IOException e) {
        e.printStackTrace();
        Toast.makeText(this, "socket close failed", Toast.LENGTH_SHORT).show();
    }
    return;
}

try {
    inputStream = bluetoothSocket.getInputStream();
} catch (IOException e2) {
    e2.printStackTrace();
    Toast.makeText(this, "get inputstream failed", Toast.LENGTH_SHORT).show();
    return;
}

try {
    OutputStream os = bluetoothSocket.getOutputStream();
    byte[] osBytes = etInput.getText().toString().getBytes();
    for (int i = 0; i < osBytes.length; i++) {
        if (osBytes[i] == 0x0a)
            n++;
    }
    byte[] osBytesNew = new byte[osBytes.length+n];
    n = 0;
    for (int i = 0; i < osBytesNew.length; i++) {
        //mobile "\n"is 0a,modify 0d 0a then send
        if (osBytesNew[i] == 0x0a) {
            osBytesNew[n] = 0x0d;
            n++;
            osBytesNew[n] = 0x0a;
        }else {
            osBytesNew[n] = osBytes[i];
        }
        n++;
    }
    os.write(osBytesNew);
} catch (Exception e) {
    e.printStackTrace();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM