android開發之藍牙配對連接的方法


最近在做藍牙開鎖的小項目,手機去連接單片機總是出現問題,和手機的連接也不穩定,看了不少藍牙方面的文檔,做了個關於藍牙連接的小結。

在做android藍牙串口連接的時候一般會使用

?
1
2
3
4
5
6
7
8
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
         tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
    Log.e(TAG, "create() failed", e);
}

然后是tmp賦給BluetoothSocket,接着調用connect方法進行藍牙設備的連接。

可是 BluetoothSocket 的connect方法本身就會報很多異常錯誤。

以下根據對藍牙開發的一點研究可通過以下方法解決:

方法1.先進行藍牙自動配對,配對成功,通過UUID獲得BluetoothSocket,然后執行connect()方法。

方法2.通過UUID獲得BluetoothSocket,然后先根據mDevice.getBondState()進行判斷是否需要配對,最后執行connnect()方法。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private class ConnectThread extends Thread {
    String macAddress = "";
 
    public ConnectThread(String mac) {
        macAddress = mac;
    }
 
    public void run() {
        connecting = true;
        connected = false;
        if(mBluetoothAdapter == null){
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
        mBluetoothAdapter.cancelDiscovery();
        try {
            socket = mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
             
        } catch (IOException e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            Log.e(TAG, "Socket", e);
        }            
        //adapter.cancelDiscovery();
        while (!connected && connetTime <= 10) {               
            connectDevice();
        }
        // 重置ConnectThread
        //synchronized (BluetoothService.this) {
           //ConnectThread = null;
        //}
    }
 
    public void cancel() {
        try {
            socket.close();
            socket = null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            connecting = false;
        }
    }
}

接下來是調用的連接設備方法connectDevice():

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
protected void connectDevice() { 
        try
            // 連接建立之前的先配對 
            if (mBluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE) { 
                Method creMethod = BluetoothDevice.class 
                        .getMethod("createBond"); 
                Log.e("TAG", "開始配對"); 
                creMethod.invoke(mBluetoothDevice); 
            } else
            
        } catch (Exception e) { 
            // TODO: handle exception 
            //DisplayMessage("無法配對!"); 
            e.printStackTrace(); 
        
        mBluetoothAdapter.cancelDiscovery(); 
        try
            socket.connect(); 
            //DisplayMessage("連接成功!");
            //connetTime++;
            connected = true;
        } catch (IOException e) { 
            // TODO: handle exception 
            //DisplayMessage("連接失敗!");
            connetTime++;
            connected = false;
            try
                socket.close();
                socket = null;
            } catch (IOException e2) { 
                // TODO: handle exception 
                Log.e(TAG, "Cannot close connection when connection failed"); 
            
        } finally {
            connecting = false;
        
    }

 

方法3.利用反射通過端口獲得BluetoothSocket,然后執行connect()方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
private class ConnectThread extends Thread {
    String macAddress = "";
 
    public ConnectThread(String mac) {
        macAddress = mac;
    }
 
    public void run() {
        connecting = true;
        connected = false;
        if(mBluetoothAdapter == null){
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
        mBluetoothAdapter.cancelDiscovery();
        initSocket();                        
        //adapter.cancelDiscovery();
        while (!connected && connetTime <= 10) {
            try {
                socket.connect();
                connected = true;
            } catch (IOException e1) {
                connetTime++;
                connected = false;
                // 關閉 socket
                try {
                    socket.close();
                    socket = null;
                } catch (IOException e2) {
                    //TODO: handle exception 
                    Log.e(TAG, "Socket", e2);
                }
            } finally {
                connecting = false;
            }
            //connectDevice();
        }
        // 重置ConnectThread
        //synchronized (BluetoothService.this) {
           //ConnectThread = null;
        //}
    }
 
    public void cancel() {
        try {
            socket.close();
            socket = null;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            connecting = false;
        }
    }
}

接下來是初始化並得到BluetoothSocket的方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
     * 取得BluetoothSocket
     */
    private void initSocket() {
        BluetoothSocket temp = null;
        try {           
            Method m = mBluetoothDevice.getClass().getMethod(
                    "createRfcommSocket", new Class[] { int.class });
            temp = (BluetoothSocket) m.invoke(mBluetoothDevice, 1);//這里端口為1           
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        socket = temp;
    }

 

要點:1.藍牙配對和連接是兩回事,不可混為一談。

   2.藍牙串口連接可通過端口 (1-30)和UUID兩種方法進行操作。

   3.通過UUID進行藍牙連接最好先進行配對操作。


免責聲明!

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



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