Firefly开源社区

打印 上一主题 下一主题

接《利用wifi实现android手机远程遥控》续---蓝牙版

19

积分

0

威望

0

贡献

注册会员

Rank: 8Rank: 8

积分
19

接《利用wifi实现android手机远程遥控》续---蓝牙版

发表于 2014-10-25 11:59:03      浏览:12406 | 回复:3        打印      只看该作者   [复制链接] 楼主
本帖最后由 lynn3653 于 2014-10-25 11:59 编辑

       前篇帖子介绍了如何利用wifi实现android手机远程遥控,那假设wifi处于带宽紧张状态,导致命令丢失或延迟很大怎么办?鉴于一般目前的手机都配有蓝牙,我们可以使用蓝牙来实现此远程遥控,在已有wifi实现源码的状况下,只要将发送消息的Socket换成BluetoothSocket即可实现蓝牙版的android手机远程遥控哦~
下面具体看看有哪些修改即可实现吧~
按照Wifi实现远程遥控的技术要点,我们逐一替换成蓝牙实现,首先是搜索设备:
1)Wifi版本下Client端(android手机)Socket广播搜寻Server端(android开发板),获取Server端IP地址;蓝牙搜索则更简单,android已封装好相应的函数调用了,如下:

  1. /* 取得默认的蓝牙适配器 */
  2.     private BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
  3. /* 开始搜索 */
  4.         mBtAdapter.startDiscovery();
复制代码


两行代码Client端即开始搜索了。。。
那如何知道搜索到设备了呢?Wifi是需要自行完成Server端回应搜索,Client端进入循环在协定好的端口等待Server端回复,以获取到相应IP地址。蓝牙则还是更省事,Client端注册如下一个广播监听蓝牙搜索响应事件即可,Server端则需要确保蓝牙已打开并且能被其他设备搜索到,如下图:



Client端蓝牙搜索响应广播
  1. // The BroadcastReceiver that listens for discovered devices and
  2.     // changes the title when discovery is finished
  3.     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  4.         @Override
  5.         public void onReceive(Context context, Intent intent) {
  6.             String action = intent.getAction();
  7.             Message msg = mHandler.obtainMessage();
  8.             // When discovery finds a device
  9.             if (BluetoothDevice.ACTION_FOUND.equals(action))
  10.             {
  11.                 // Get the BluetoothDevice object from the Intent
  12.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  13.                 String deviceName = new String(device.getName());
  14.                 Log.d(TAG, "BT found device name:"+ deviceName);
  15.                 // If it's already paired, skip it, because it's been listed already
  16.                 if (device.getBondState() != BluetoothDevice.BOND_BONDED)
  17.                 {
  18.                     deviceNameList.add(device.getName());
  19.                     deviceAddressList.add(device.getAddress());
  20.                 }

  21.             }
  22.             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
  23.             {
  24.                 Log.v(TAG, "Receive Bluetooth ACTION_DISCOVERY_FINISHED!");            
  25.             }
  26.             if(deviceNameList.size() > 0)
  27.             {
  28.                 msg.what = HANDLER_FIND_DEVICES;   
  29.             }
  30.             else
  31.             {
  32.                 msg.what = HANDLER_NODEVICES_CHECKNETWORK;
  33.             }
  34.             mHandler.sendMessage(msg);
  35.         }
  36.     };
复制代码

   
实际以上方式是临时搜索到Server端,系统会自动弹出蓝牙配对窗口提示配对(如未在蓝牙设置界面手动配对成功过),此配对信息在app退出后是不被保存的!既然如此,那最好的做法是先到蓝牙设置界面手动将Client端与Server端进行配对!做法就不用笔者介绍了吧。。。。
如果配对成功了,那无需搜索我们也可以获取到Server端的信息,如下:
  1. // Get a set of currently paired devices
  2.         Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();

  3.         /*将已配对的设备加入*/
  4.         if (pairedDevices.size() > 0) {
  5.             for (BluetoothDevice device : pairedDevices) {
  6.                 String deviceName = new String(device.getName());
  7.                 Log.d(TAG, "BT found device name:"+ deviceName);
  8.                 deviceNameList.add(device.getName());
  9.                 deviceAddressList.add(device.getAddress());   
  10.             }            
  11.         }
复制代码


备注:这里完全由系统的蓝牙搜索协议搜索Server端,所以即使不是我们的Server端的蓝牙设备都会被搜索到,贸然去连接肯定失败,所以需要再想办法筛选出Server端!这个留待读者自行设计,欢迎回复讨论哦~

获取到Server端地址信息后,接下来就是收发消息转化成按键事件上报!
2)Wifi版本是将Client端的虚拟按键事件转化成简单字符串用Socket发送至Sever端,Server端解析字符串获得按键事件,并使用injectInputEvent方法向android上层上报按键事件;蓝牙版本只需将其中的Socket替换成BluetoothSocket,其他事与通信协议无关,自然无需修改。
Wifi下是用某个端口号(笔者使用的9999)在Client端与Server端建立TCP连接:
Client端:
  1. socket_9999 = new Socket(serverAddress_s, 9999);//serverAddress_s为第一步Server端回复中取得
复制代码


Server端:
  1. try {
  2.         mWifiServerSocket = new ServerSocket(9999, 3);
  3. } catch (IOException e1) {
  4.         // TODO Auto-generated catch block
  5.         e1.printStackTrace();
  6. }
  7. Socket client = mWifiServerSocket.accept();
复制代码



蓝牙版本类似:
Client端:
  1. device = mBtAdapter.getRemoteDevice(BlueToothAddress);//BlueToothAddress为前面配对的或者临时搜索的蓝牙设备中取得
  2. //创建一个Socket连接:只需要服务器在注册时的UUID号
  3.                 socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
  4.                 //连接
  5.                 socket.connect();
复制代码


Server端:
  1. try {
  2.                     /* 创建一个蓝牙服务器
  3.                      * 参数分别:服务器名称、UUID     */   
  4.                     mBTServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
  5.                             UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));   
  6.                     break;               

  7.                 } catch (IOException e) {
  8.                     // TODO Auto-generated catch block
  9.                     e.printStackTrace();
  10.                 }   
  11. BluetoothSocket socket = mBTServerSocket.accept();
复制代码



至此蓝牙替换Wifi版本的android手机远程遥控即OK了!放上一张笔者成功运行的截面图


附源码!
RemotecontrolBluetooth_test.zip (1.63 MB, 下载次数: 41) RemoteServiceBluetooth_test.zip (43.31 KB, 下载次数: 29)

回复

使用道具 举报

33

积分

0

威望

0

贡献

游客

积分
33
发表于 2014-12-19 15:59:27        只看该作者  沙发
:handshake  不错!!!!!
回复

使用道具 举报

57

积分

0

威望

0

贡献

技术小白

积分
57
发表于 2016-7-8 16:29:58        只看该作者  板凳

谢谢分享
回复

使用道具 举报

154

积分

0

威望

0

贡献

技术小白

积分
154
发表于 2016-10-29 16:37:53        只看该作者  地板
多谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

友情链接 : 爱板网 电子发烧友论坛 云汉电子社区 粤ICP备14022046号-2
快速回复 返回顶部 返回列表