尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️
Linux編程
點擊右側關注,免費入門到精通!
作者QiaoJim
http://blog.csdn.net/qiao_jim/article/details/73008695
最近學習了android傳統藍牙,自己整理了一下思路,然後寫了一個BluetoothStudy小測試程序,來運用所理解的android傳統藍牙開發技術,寫下
一些心得和思路,供其他android熱愛者參考,也方便日後回顧。
博客如有錯誤之處,歡迎留言之處,十分感謝。博客最後會附上源碼,可下載借鑒。
一、整體思路和對應相關方法
1、獲得BluetoothAdapter:BluetoothAdapter.getDefaultAdapter();
2、打開藍牙:詢問用戶打開(推薦)或直接bluetoothAdapter.enable();
3、查詢已綁定設備,發現新設備:bluetoothAdapter.getBondedDevices();bluetoothAdapter.startDiscovery();
4.1、服務端,一直監聽請求,當該端主動發出請求時,關閉該端的監聽,角色轉為客戶端:
bluetoothDevice.createRfcommSocketToServiceRecord(UUID);
4.2、客戶端,點擊目標設備,配對連接:
bluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, UUID);
5、通過BluetoothSocket通信:IO流讀寫
二、開發詳解
1、聲明權限,注意可能需要的運行時權限
<uses-permissionandroid:name="android.permission.BLUETOOTH"/><uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/><uses-permissionandroid:name="android.permission.ACCESS_COARSE_LOCATION"/>
android 6.0以上設備發現新藍牙時,需加入運行時權限,否則無法監聽ACTION_FOUND廣播
if(Build.VERSION.SDK_INT>=6.0){ActivityCompat.requestPermissions(getActivity(),newString[]{Manifest.permission.ACCESS_FINE_LOCATION},Params.MY_PERMISSION_REQUEST_CONSTANT);}publicvoidonRequestPermissionsResult(intrequestCode,Stringpermissions[],int[]grantResults){switch(requestCode){caseParams.MY_PERMISSION_REQUEST_CONSTANT:{if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//運行時權限已授權}return;}}}
2、打開藍牙,推薦用對話框形式讓用戶打開
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();//藍牙未打開,詢問打開if(!bluetoothAdapter.isEnabled()){IntentturnOnBtIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(turnOnBtIntent,Params.REQUEST_ENABLE_BT);}@OverridepublicvoidonActivityResult(intrequestCode,intresultCode,Intentdata){switch(requestCode){caseParams.REQUEST_ENABLE_BT:{//用戶打開藍牙if(resultCode==RESULT_OK){//顯示已綁定藍牙設備showBondDevice();}break;}caseParams.REQUEST_ENABLE_VISIBILITY:{//設置該藍牙設備可被其他設備發現,600是設置的設備可發現時間(博客最後有簡單說明)if(resultCode==600){toast("藍牙已設置可見");}elseif(resultCode==RESULT_CANCELED){toast("藍牙設置可見失敗,請重試");}break;}}}
3、通過BluetoothAdapter獲取已綁定的藍牙設備
privatevoidshowBondDevice(){deviceList.clear();//所有已綁定設備,一個Set集合Set<BluetoothDevice>tmp=bluetoothAdapter.getBondedDevices();for(BluetoothDeviced:tmp){deviceList.add(d);}//更新列表listAdapter.notifyDataSetChanged();}
4、發現藍牙設備,發現一個設備,會發送一條ACTION_FOUND廣播,註冊廣播接收器,可獲得對應藍牙設備信息
bluetoothAdapter.startDiscovery();intentFilter=newIntentFilter();btReceiver=newMyBtReceiver();//監聽搜尋開始,搜尋結束,發現新設備3條廣播intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);intentFilter.addAction(BluetoothDevice.ACTION_FOUND);getActivity().registerReceiver(btReceiver,intentFilter);
//廣播接收器privateclassMyBtReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){Stringaction=intent.getAction();if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){toast("開始搜尋...");}elseif(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){toast("搜尋結束");}elseif(BluetoothDevice.ACTION_FOUND.equals(action)){//獲得發現的設備BluetoothDevicedevice=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if(device.getBondState()!=BluetoothDevice.BOND_BONDED){deviceList.add(device);listAdapter.notifyDataSetChanged();}}}}
5、設備連接,服務器端開啟線程一直等待連接,客戶端點擊某個目標設備,關閉服務器線程監聽,並開啟線程,發出連接請求。
注意:客戶端連接前,一定cancelDiscovery()
//藍牙已開啟if(bluetoothAdapter.isEnabled()){showBondDevice();//默認開啟服務線程監聽if(serverThread!=null){serverThread.cancel();}serverThread=newServerThread(bluetoothAdapter,uiHandler);newThread(serverThread).start();}listView.setOnItemClickListener(newAdapterView.OnItemClickListener(){@OverridepublicvoidonItemClick(AdapterView<?>parent,Viewview,intposition,longid){//關閉服務器監聽if(serverThread!=null){serverThread.cancel();serverThread=null;}BluetoothDevicedevice=deviceList.get(position);//開啟客戶端線程,連接點擊的遠程設備clientThread=newClientThread(bluetoothAdapter,device,uiHandler);newThread(clientThread).start();//通知ui連接的服務器端設備Messagemessage=newMessage();message.what=Params.MSG_CONNECT_TO_SERVER;message.obj=device;uiHandler.sendMessage(message);}});
6、建立BluetoothSocket連接以後,使用IO流數據傳輸,服務器和客戶端讀寫數據類似,貼一部分代碼供參考
publicvoidwriteData(StringdataSend){if(serverThread!=null){serverThread.write(dataSend);}elseif(clientThread!=null){clientThread.write(dataSend);}}
//寫數據publicvoidwrite(Stringdata){try{out.write(data.getBytes("utf-8"));}catch(IOExceptione){e.printStackTrace();}}
newThread(newRunnable(){@Overridepublicvoidrun(){byte[]buffer=newbyte[1024];intlen;Stringcontent;try{//讀數據while((len=in.read(buffer))!=-1){content=newString(buffer,0,len);Messagemessage=newMessage();message.what=Params.MSG_CLIENT_REV_NEW;message.obj=content;//更新uiuiHandler.sendMessage(message);}}catch(IOExceptione){e.printStackTrace();}}}).start();
7、其他說明
(1)新設備綁定,bluetoothDevice.createBond()
(2)設置設備可被發現的時間:
IntentenableIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);enableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,600);startActivityForResult(enableIntent,Params.REQUEST_ENABLE_VISIBILITY);
(3)服務器獲得遠端設備,bluetoothSocket.getRemoteDevice()
(4)通過MAC獲得藍牙設備,bluetoothAdapter.getRemoteDevice(String address)
(5)關閉藍牙,bluetoothAdapter.disable()
三、源碼示例下載
附上源碼github地址
https://github.com/QiaoJim/BluetoothStudy
感謝閱讀,如有錯誤,請留言。
四、效果圖
推薦↓↓↓
長
按
關
註
?【16個技術公眾號】都在這里!
涵蓋:工程師大咖、源碼共讀、工程師共讀、數據結構與算法、黑客技術和網路安全、大數據科技、編程前端、Java、Python、Web編程開發、Android、iOS開發、Linux、數據庫研發、幽默工程師等。