當前位置:首頁 » 安卓系統 » android藍牙socket

android藍牙socket

發布時間: 2023-07-29 23:39:47

『壹』 Android藍牙開發(二)經典藍牙消息傳輸實現

上篇文章中,我們主要介紹了藍牙模塊,傳統/經典藍牙模塊BT和低功耗藍牙BLE及其相關的API,不熟悉的可以查看 Android藍牙開發(一)藍牙模塊及核心API 進行了解。

本篇主要記錄用到的經典藍牙開發流程及連接通訊。

藍牙連接前,給與相關系統許可權:

安卓6.0以上系統要動態請求及獲取開啟GPS內容:

藍牙核心對象獲取,若獲取對象為null則說明設備不支持藍牙:

判斷藍牙是否開啟,沒有則開啟:

藍牙掃描:

取消掃描:

藍牙監聽廣播,監聽藍牙開關,發現設備,掃描結束等狀態,定義狀態回調介面,進行對應操作,例如:監聽到藍牙開啟後,進行設備掃描;發現設備後進行連接等。

客戶端,與服務端建立長連接,進行通訊:

服務端監聽客戶端發起的連接,進行接收及通訊:

客戶端連接及服務端監聽基類,用於客戶端和服務端之前Socket消息通訊,進行消息或文件的發送、接收,進行通訊關閉操作等:

我這里只是簡單記錄了項目中用到的藍牙通訊,兩個設備之間不通過配對進行連接、通訊。
相關詳細內容及使用請查看Github項目: https://github.com/MickJson/BluetoothCS

藍牙配對操作及其它內容,可以詳細查看我下面的參考資料,寫的十分詳細,比如設備通過MAC地址,可以通過BluetoothAdapter獲取設備,再通過客戶端connect方法去進行連接等。

連接中遇到問題:read failed, socket might closed or timeout, read ret: -1。

通過改UUID,反射等方法都還是會出現錯誤。連接時,要確保服務端及客戶端都處於完全斷開狀態,否則連接就會出現以上問題,但偶爾還是會有問題,期待有什麼好的方法可留言告訴我。

參考資料:

Android-經典藍牙(BT)-建立長連接傳輸短消息和文件

Android藍牙開發—經典藍牙詳細開發流程

歡迎點贊/評論,你們的贊同和鼓勵是我寫作的最大動力!

『貳』 android開發SPP經典藍牙

Android 開發SPP經典藍牙。

1、傳統藍牙採用的是SPP(Serial Port Profile)協議進行數據傳輸。

2、SPP的UUID:00001101-0000-1000-8000-00805F9B34FB

3、手機一般以客戶端的角色主動連接SPP協議設備

概念:

BluetoothAdapter:

本地藍牙適配器,是所有藍牙交互的入口,表示藍牙設備自身的一個藍牙適配器,整個系統只有一個藍牙適配器,通過他可以發現其他藍牙設備,查詢綁定(配對)設備列表,使用MAC地址實例化BluetoothDevice以及創建BluetoothServerSocket用來偵聽來自其他設備的通信。

myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//獲取默認的藍牙Adapter

BluetoothDevice:

遠程的藍牙設備。

private static BluetoothDevice myDevice;

myDevice = myBluetoothAdapter.getRemoteDevice(BDAddr);//獲取遠程設備,通過藍牙的MAC地址來獲取一個遠程對象

兩種連接方式

BluetoothSocket

客戶端:調用BluetoothDevice的()可以獲取該對象;調用connect()方法可以建立連接。

private static BluetoothSocket mySocket = null;

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

Method m = myDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});//由BluetoothDevice衍生出BluetoothSocket, createRfcommSocket來選擇連接的服務和協議

mySocket = (BluetoothSocket) m.invoke(myDevice, 1);

BluetoothServerSocket:

服務端:通過BluetoothServerSocket對象可以創建BluetoothSocket對象,調用BluetoothServerSocket的accept()的方法可以得到改對象。

開發流程:

1:聲明許可權:

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

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

2:啟動和關閉藍牙

獲取藍牙適配器,使用close()介面可以關閉藍牙適配器

myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//獲取默認的藍牙Adapter

啟動藍牙

if (!blueadapter.isEnabled())

        //判斷本機藍牙是否打開

        {//如果沒打開,則打開藍牙

        blueadapter.enable();

        }

3.使用BlueAdatper搜索 

使用bluetoothAdapter搜索設備,bluetoothAdapter.startDiscovery()在搜索過程中,系統會發出三個廣播信息: 

ACTION_DISCOVERY_START:開始搜索 

ACTION_DISCOVERY_FINISHED:搜索結束 

ACTION_FOUND:找到設備

if (bluetoothAdapter.isDiscovering()) {

        bluetoothAdapter.cancelDiscovery();//如果藍牙設備未連接則取消搜索

    }

    bluetoothAdapter.startDiscovery();

}

4:(1)通過注冊廣播獲取搜索到的設備。

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!");

        }

    }

};

(2),直接得到當前的藍牙設備後,就可用通過遍歷pairedDevices ,得到當前手機已經配對過的藍牙設備。

Set<BluetoothDevice> pairedDevices = myBluetoothAdapter.getBondedDevices();//獲取當前藍牙設備

if (pairedDevices.size() <= 0) return false;

for (BluetoothDevice device : pairedDevices) {

    Map<String, String> map = new HashMap<String, String>();

    map.put("DeviceName", device.getName());

    map.put("BDAddress", device.getAddress());

    list.add(map);

5.建立連接

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

Method m = myDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});//由BluetoothDevice衍生出BluetoothSocket, createRfcommSocket來選擇連接的服務和協議

mySocket = (BluetoothSocket) m.invoke(myDevice, 1);

mySocket.connect();//使用BluetoothSocket來連接設備

6.把得到的藍牙設備給通過點擊ListView選擇設備。

listView.setOnItemClickListener(new ListView.OnItemClickListener() {

    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

        SelectedBDAddress = list.get(arg2).get("BDAddress");

        if (((ListView) arg0).getTag() != null) {

            ((View) ((ListView) arg0).getTag()).setBackgroundDrawable(null);

        }

        ((ListView) arg0).setTag(arg1);

        arg1.setBackgroundColor(Color.BLUE);

        myDevice = myBluetoothAdapter.getRemoteDevice(SelectedBDAddress);

    }

});

7.客戶端發送數據

當兩個設備成功連接之後,雙方都會有一個BluetoothSocket對象,這時,就可以在設備之間傳送數據了。

       1.使用getOutputStream()方法來獲取輸出流來處理傳輸。

       2.調用write()。

os = socket.getOutputStream();//獲取輸出流

if (os != null) {//判斷輸出流是否為空

    os.write(message.getBytes("UTF-8"));

}

os.flush();//將輸出流的數據強制提交

os.close();//關閉輸出流

}

將輸出流中的數據提交後,要記得關閉輸出流,否則,可能會造成只能發送一次數據。

8.服務端接收數據

1.使用getInputStream()方法來獲取輸入流來處理傳輸。

       2.調用read()。

InputStream im=null;

im=bluetoothSocket.getInputStream();

byte buf[] = new byte[1024];

if (is != null) {

    is.read(buf, 0, buf.length);//讀取發來的數據

    String message = new String(buf);//把發來的數據轉化為String類型

    BuletoothMainActivity.UpdateRevMsg(message);//更新信息在顯示文本框

    is.close();//關閉輸入流

使用服務端接收數據時,要先從客戶端向服務端發起連接,只有接收到連接請求之後,才會返回一個BluetoothSocket對象。有BluetoothSocket對象才能獲取到輸入流。

『叄』 Android - Socket簡單使用

ServerSocket類提供如下構造器:

當ServerSocket使用完畢,應使用 close() 方法來關閉此ServerSocket。通常情況下,伺服器不應該只接收一個客戶端請求,而應該不斷接收來自客戶端的請求,所以程序可以通過循環,不斷調用ServerSocket的accept方法:

Socket 常用構造器

註:上面兩個構造器指定遠程主機時既可以使用InetAddress來指定,也可以直接使用String對象來指定遠程IP。本地主機只有一個IP地址時,使用第一個方法更簡單。

在與伺服器進行通訊的時候,無法判斷遠程的伺服器是否斷開連接。如果使用 OutputStream 發送數據則會影響正常的數據發送(無法區分)。所以就引入了一個心跳機制。

心跳機制實現,使用 Socket.sendUrgentData() 方法發送一個位元組流數據(緊急數據)。可以通過判斷服務端的 OOBINLINE 屬性是否打開,來確定是否斷開連接;

setSoTimeout()理解 :設置超時時間;例如:設置為2s,如果阻塞的時間>2s ,那麼就會報錯。

『肆』 Android-藍牙傳輸

通過藍牙傳輸數據與Socket類似。在網路中使用Socket和ServerSocket控制客戶端和服務端的數據讀寫。而藍牙通訊也由客戶端和服務端Socket來完成。藍牙客戶端Socket是BluetoothSocket,藍牙服務端Socket是BluetoothServerSocket。這兩個類都在android.bluetooth包中。

如果打算建議兩個藍牙設備之間的連接,則必須實現伺服器端與客戶端的機制。當兩個設備在同一個RFCOMM channel下分別擁有一個連接的BluetoothSocket,這兩個設備才可以說是建立了連接。

伺服器設備與客戶端設備獲取BluetoothSocket的途徑是不同的。伺服器設備是通過accepted一個incoming connection來獲取的,而客戶端設備則是通過打開一個到伺服器的RFCOMMchannel來獲取的。

通過調用BluetoothAdapter的(String, UUID) 方法來獲取
BluetoothServerSocket(UUID用於客戶端與伺服器端之間的配對)調用BluetoothServerSocket的 accept() 方法監聽連接請求,如果收到請求,則返回一個BluetoothSocket實例。

如果不想在accept其他的連接,則調用BluetoothServerSocket的 close() 方法釋放資源(調用該方法後,之前獲得的BluetoothSocket實例並沒有close。但由於RFCOMM一個時刻只允許在一條channel中有一個連接,則一般在accept一個連接後,便close掉BluetoothServerSocket)

通過搜索得到伺服器端的BluetoothService,調用BluetoothService的(String, UUID)方法獲取BluetoothSocket(該UUID應該同於伺服器端的UUID)。

調用BluetoothSocket的 connect() 方法(該方法為block方法),如果UUID同伺服器端的UUID匹配,並且連接被伺服器端accept,則 connect() 方法返回。

『伍』 android藍牙通訊Socket.connect()方法調用不成功。為什麼

  1. UUID值出現錯誤。

  2. 看一下android有關bluetooth的API,用於普通藍牙適配器和android手機藍牙模塊連接的,而且這個UUID的值必須是00001101-0000-1000-8000-00805F9B34FB。

  3. 這個是android的API上面說明的.connect().在連接的時候,android手機作client(主動和電腦建立連接),如果電腦作為server(一直監聽是否有服務連接),則需要在手機端調用這樣一行代碼.兩邊的UUID必須是一樣的,這是一個服務的唯一標識。

熱點內容
玩單機游戲要哪些配置的電腦 發布:2025-02-04 19:17:41 瀏覽:1002
c語言編程圖書 發布:2025-02-04 19:01:52 瀏覽:896
在哪裡開啟密碼顯示 發布:2025-02-04 18:38:30 瀏覽:789
怎麼查詢qq密碼 發布:2025-02-04 18:20:10 瀏覽:513
python編寫介面 發布:2025-02-04 18:08:30 瀏覽:78
怎麼給游戲設置密碼 發布:2025-02-04 18:03:08 瀏覽:926
商品存儲規劃 發布:2025-02-04 17:45:24 瀏覽:567
ios訪問共享 發布:2025-02-04 17:36:33 瀏覽:335
javabuild 發布:2025-02-04 17:30:19 瀏覽:592
gnulinux編譯 發布:2025-02-04 17:30:18 瀏覽:132