最近在做蓝牙开锁的小项目,手机去连接单片机总是出现问题,和手机的连接也不稳定,看了不少蓝牙方面的文档,做了个关于蓝牙连接的小结。

在做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进行蓝牙连接最好先进行配对操作。

android开发之蓝牙配对连接的方法的更多相关文章

  1. 【视频】零基础学Android开发:蓝牙聊天室APP(四)

    零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...

  2. 【视频】零基础学Android开发:蓝牙聊天室APP(二)

    零基础学Android开发:蓝牙聊天室APP第二讲 2.1 课程内容应用场景 2.2 Android UI设计 2.3 组件布局:LinearLayout和RelativeLayout 2.4 Tex ...

  3. Android开发——RecyclerView特性以及基本使用方法(二)

    0.  前言 随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用.但显然并不能说RecyclerView就一定优于ListView,而是应该根据 ...

  4. Android开发——RecyclerView特性以及基本使用方法(一)

    )关于点击事件,没有像ListView那样现成的API,但是自己封装起来也不难,而且我们使用ListView时,如果item中有可点击组件,那么点击事件的冲突也是一个问题,而在RecyclerView ...

  5. 【视频】零基础学Android开发:蓝牙聊天室APP(三)

    零基础学Android开发:蓝牙聊天室APP第三讲 3.1 ImageView.ImageButton控件具体解释 3.2 GridView控件具体解释 3.3 SimpleAdapter适配器具体解 ...

  6. 【视频】零基础学Android开发:蓝牙聊天室APP(一)

    零基础学Android开发:蓝牙聊天室APP第一讲 1. Android介绍与环境搭建:史上最高效Android入门学习 1.1 Google的大小战略 1.2 物联网与云计算 1.3 智能XX设备 ...

  7. Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能. 下面是一个效果图 ...

  8. Android开发 静态static类与static方法持有Context是否导致内存泄露的疑问

    简述 在Android开发的过程中,难免会使用单例模式或者静态方法工具类.我们会让它们持有一些外部的Context或者View一般有以下几种情况: 单例模式,类的全局变量持有Context 或 Vie ...

  9. Android开发中Parcelable接口的使用方法

    在网上看到很多Android初入门的童鞋都在问Parcelable接口的使用方法,小编参考了相关Android教程,看到里面介绍的序列化方法主要有两种分别是实现Serializable接口和实现Par ...

随机推荐

  1. 再谈协方差矩阵之主成分分析PCA

    上次那篇文章在理论层次介绍了下协方差矩阵,没准很多人觉得这东西用处不大,其实协方差矩阵在好多学科里都有很重要的作用,比如多维的正态分布,再比如今天我们今天的主角——主成分分析(Principal Co ...

  2. 问题解决: WordPress on SAE注册邮件无法发送

    方法一: 修改代码 Step 1: 改写wp-includes/pluggable.php, 把WordPress默认邮件设置改为SMTP模式. // Set to use PHP's mail() ...

  3. Android中利用httpclient进行网络通信的方法(以用户登录为例说明)

    http://www.android100.org/html/201406/09/22915.html 1.服务器端 服务器端和android没有太大关系,对J2EE比较熟悉的话写起来应该很容易,这里 ...

  4. CentOS 6.5系统安装配置图解教程(详细图文)

    转载:http://www.jb51.net/os/128751.html

  5. Qt在各平台上的搭建qt-everywhere

    Qt for windows7-64bit 在电脑上安装mingw(搜索mingw for windows),将C:\MinGW\bin添加进环境变量,打开命令行输入gcc --version和g++ ...

  6. LINUX下使用crontab进行RMAN备份实验

    之前写了脚本,手动执行可以,使用crontab总是无法运行成功,今天下午花了两个小时实验,完成如下: 注意事项:脚本完成首先手动执行,确定可以正常执行. 在crontab中使用,要注意以下几点: 1. ...

  7. C# 计算器 如果设置键盘输入的监听事件

    这个事情困扰了我好久,之前java写的计算器程序可以正常运行了,但是因为打包问题(尝试过多次,感觉好麻烦,个人比较崇尚“点子”,注重创新,思来想去之后,决定试试C#模仿java再写一遍),想要用C#模 ...

  8. ftp上传错误

    明明设置好了权限,但是在上传的时候提示如下错误,但在使用的过程当中,发现有的时候是可以上传的,很奇怪的问题. baidu 了一下,发现是下面的这个设置导致的.改过来后,果然正常. 这个设置只是一个字符 ...

  9. A. Case of the Zeros and Ones----解题报告

    A. Case of the Zeros and Ones Description Andrewid the Android is a galaxy-famous detective. In his ...

  10. DDL 和DML 区别

    DML(Data Manipulation Language)数据操纵语言: 适用范围:对数据库中的数据进行一些简单操作,如insert,delete,update,select等. DDL(Data ...