实现Android和PC之间的蓝牙通信

简介:

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

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

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

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

d组件,http://www.cnblogs.com/procoder/archive/2009/09/22/1571580.html。由于它讨论了实现文件传输的思路,我们在这篇文章中就只讨论简单的字符传输。

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

 下面是手机端的初始化代码。其中的具体含义可参照http://android.tgbus.com/Android/tutorial/201103/346657.shtml


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,是标记硬件地址的一种方法。


/// <summary>
        /// 打开端口
        /// </summary>
        /// <param name="Name">端口名称</param>
        /// <returns>成功否</returns>
        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设备,但这样貌似是不行的。因为这个库本身提供的方法不够底层...总之还想再研究下。

        有任何问题欢迎讨论

相关文章
|
Android开发 数据格式 XML
BluetoothAdapter在Android6.0/7.0+以上startDiscovery不能发现蓝牙设备问题
BluetoothAdapter在Android6.0+以上startDiscovery不能发现蓝牙设备问题 问题的重要原因之一是Android 6.0+,Android 7.0+的权限问题引起的。
1585 0
|
8月前
|
传感器 物联网 Android开发
Android蓝牙使用详解(低功耗蓝牙(BLE))
Android蓝牙使用详解(低功耗蓝牙(BLE))
|
Android开发
Android 蓝牙状态获取
Android 蓝牙状态获取
419 0
|
测试技术 数据处理 数据库
Android Modbus 通讯实现
Android Modbus 通讯实现
416 0
Android Modbus 通讯实现
|
传感器 物联网 定位技术
Android 12 蓝牙适配
Android 12 蓝牙适配
826 0
Android 12 蓝牙适配
|
物联网 Android开发
Android 解析蓝牙广播数据
Android 解析蓝牙广播数据
1071 1
Android 解析蓝牙广播数据
|
存储 物联网 Android开发
Android NFC(近程通信)使用
添加权限 1. 读写文本 activity_main.xml MainActivity.java public class MainActivity extends AppCompatActivity { ...
992 0
|
XML 存储 传感器
用ESP8266+android,制作自己的WIFI小车(Android 软件)
先说一下这篇文章里面的内容:TCP 客户端, 自定义对话框, 自定义按钮, ProgressBar竖直显示, 重力感应传感器,手机返回键新开启界面的问题(返回上次的界面),数据保存 软件的通信是配合 http://www.
1450 0

热门文章

最新文章