標籤:onresume code IV red stream 使用 register super length
準備
1.藍芽序列埠基於SPP協議(Serial Port Profile),能在藍牙裝置之間建立串口進行資料轉送
2.SPP的UUID:00001101-0000-1000-8000-00805F9B34FB
3.Android手機一般以用戶端的角色主動串連SPP協議裝置
串連流程
1.檢測藍芽狀態
若藍芽未開啟,則開啟藍芽~
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();@Overrideprotected void onResume() { super.onResume(); if (!bluetoothAdapter.isEnabled()) { // open blueTooth Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }}@Overrideprotected 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);// receiverprivate 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:找到裝置
@Overridepublic 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();}
android 藍芽SPP協議通訊