博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现Android和PC之间的蓝牙通信
阅读量:7126 次
发布时间:2019-06-28

本文共 4630 字,大约阅读时间需要 15 分钟。

   这两天想实现PC和安卓手机的通信,限于水平,知道的方法大概有两种:基于数据包的socket和蓝牙。虽然看起来简单,但调也调了两天多。自己测试了下socket,在室内WIFI环境下时延大概是0.1s。而在3G网络下时延居然达3s之多,而且只要不发数据,端口貌似就会断掉,总之,很不爽。于是,便考虑了蓝牙的方法。

  实现手机和PC的蓝牙通信,一种是最常用的蓝牙虚拟串口,这种方法可以通过配置非常简单地实现,很多外置蓝牙GPS都用这种做法。但大名鼎鼎的安卓却不支持,因此对大部分外置GPS都不提供支持(可能安卓手机大部分包含内置GPS,觉得外置的太鸡肋了)。因此必须采用第二种,蓝牙socket。

      在电脑上,实在不想去在C++下开发,于是便寻找.NET组件,但实际上微软的NET库中不支持蓝牙,因此必须采用第三方的控件,名字叫inthehand.

      这篇文章中详细的介绍了inthehan

d组件,。由于它讨论了实现文件传输的思路,我们在这篇文章中就只讨论简单的字符传输。

       它的官方网站是inthehand.net,其中多数的类库和方法都能找到。

 下面是手机端的初始化代码。其中的具体含义可参照。

private PrintStream mPrintStream = null;    private BufferedReader mBufferedReader = null;    BluetoothAdapter myBluetoothAdapter = null;    BluetoothServerSocket mBThServer = null;    BluetoothSocket mBTHSocket = null;    myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        myBluetoothAdapter.enable();//open bth        Intent discoverableIntent = new Intent(                BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//使得蓝牙处于可发现模式,持续时间150s        discoverableIntent.putExtra(                BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
下面是PC上的初始化核心代码:PC是作为客户端出现的。它需要通过搜索获取手机的蓝牙MAC地址,实现通信。GUID又名UUID,是标记硬件地址的一种方法。

///         /// 打开端口        ///         /// 端口名称        /// 
成功否
public bool OpenPort(string Name) { InTheHand.Net.Bluetooth.BluetoothRadio.PrimaryRadio.Mode = InTheHand.Net.Bluetooth.RadioMode.Connectable; InTheHand.Net.Sockets.BluetoothClient cli = new InTheHand.Net.Sockets.BluetoothClient(); InTheHand.Net.Sockets.BluetoothDeviceInfo[] devices = cli.DiscoverDevices(); foreach (InTheHand.Net.Sockets.BluetoothDeviceInfo device in devices)//设备搜寻 { device.Update(); device.Refresh(); MessageBox.Show("设备已找到"); break; } BluetoothDeviceInfo bd = new BluetoothDeviceInfo(devices[0].DeviceAddress); bluetoothClient = new BluetoothClient(); Guid mGUID = Guid.Parse("fa87c0d0-afac-11de-8a39-0800200c9a66"); bluetoothClient.Connect(devices[0].DeviceAddress, mGUID);//客户端对地址实现连接,这是一个阻塞线程,需要服务器端的回应 ReceiveThread = new Thread(ReceiveMethod); ReceiveThread.Start(); return true; }
        下面是手机接受PC端连接请求的方法:

if (connected)                {                    return;                }                try                {                    mBThServer = myBluetoothAdapter                            .listenUsingRfcommWithServiceRecord(NAME_SECURE,                                    MY_UUID_SECURE);                } catch (IOException e)                {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                try                {                    mBTHSocket = mBThServer.accept();                } catch (IOException e)                {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                try                {                    mBufferedReader = new BufferedReader(new InputStreamReader(                            mBTHSocket.getInputStream()));                } catch (IOException e1)                {                    // TODO Auto-generated catch block                    e1.printStackTrace();                }// 取得输入、输出流                try                {                    mPrintStream = new PrintStream(                            mBTHSocket.getOutputStream(), true);                    connected = true;                } catch (IOException e)                {                    // TODO Auto-generated catch block                    e.printStackTrace();                }
   要通过手机发送数据,执行以下代码即可:

mPrintStream.write(buff);                } catch (IOException e)                {                    // TODO Auto-generated catch block                    e.printStackTrace();                }// 发送给服务器                mPrintStream.flush();
    PC端的接受代码:

while (isConnecting)            {                try                {                    Stream peerStream = bluetoothClient.GetStream();                    peerStream.Read(buffer, 0, PACKETLENGTH);                  //dataprocess();                }                catch (Exception ex)                {                    isConnecting = false;                    MessageBox.Show(ex.ToString());                }

 这里要注意以下几个小问题,但也就是这几个问题,耽误了我很久时间:

      inthehand.net.personal是PC端上一定要用得到的库,但注意这个库函数的版本,我一开始用了的dll是600K左右的,编译没问题,运行就会报错,提示找不到dll。但后来左思右想,才发现还有另外的一个同名dll,150K左右,换过来以后一切OK,太坑爹了!

        手机设备的蓝牙硬件权限要打开,否则就没法运行。

        还有我特想将手机做个蓝牙HID设备,但这样貌似是不行的。因为这个库本身提供的方法不够底层...总之还想再研究下。

        有任何问题欢迎讨论

转载地址:http://ptoel.baihongyu.com/

你可能感兴趣的文章
使用命令行控制 Windows 演示设置
查看>>
linux 批量拷贝数据脚本
查看>>
TypeScript 3.0 新功能介绍(一)
查看>>
打开摄像头
查看>>
安装SQL Server 2000时的一个小细节
查看>>
就C语言的指针、链表的原理和各类操作撰写一篇技术博客,说说自己学习C语言指针和链表的体会...
查看>>
Android 动画
查看>>
Python27 paramiko模块安装
查看>>
Windows Server 2008 R2 升级之前言
查看>>
linux工具-sar命令
查看>>
『中级篇』k8s基础网络Cluster Network(66)
查看>>
苹果IOS开发者账号总结
查看>>
二叉树转化成双链表的JAVA实现
查看>>
我的友情链接
查看>>
社会心理学在网站运营中的妙用
查看>>
Java NIO与IO的区别和比较
查看>>
Cisco TFTP Server实验与操作
查看>>
sshpass 使Linux可以明文参数输入SSH密码
查看>>
jQuery 表单插件 -- Form
查看>>
[转]RedHat5配置yum源
查看>>