接《利用wifi实现android手机远程遥控》续---蓝牙版
本帖最后由 lynn3653 于 2014-10-25 11:59 编辑前篇帖子介绍了如何利用wifi实现android手机远程遥控,那假设wifi处于带宽紧张状态,导致命令丢失或延迟很大怎么办?鉴于一般目前的手机都配有蓝牙,我们可以使用蓝牙来实现此远程遥控,在已有wifi实现源码的状况下,只要将发送消息的Socket换成BluetoothSocket即可实现蓝牙版的android手机远程遥控哦~
下面具体看看有哪些修改即可实现吧~
按照Wifi实现远程遥控的技术要点,我们逐一替换成蓝牙实现,首先是搜索设备:
1)Wifi版本下Client端(android手机)Socket广播搜寻Server端(android开发板),获取Server端IP地址;蓝牙搜索则更简单,android已封装好相应的函数调用了,如下:
/* 取得默认的蓝牙适配器 */
private BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();
/* 开始搜索 */
mBtAdapter.startDiscovery();
两行代码Client端即开始搜索了。。。
那如何知道搜索到设备了呢?Wifi是需要自行完成Server端回应搜索,Client端进入循环在协定好的端口等待Server端回复,以获取到相应IP地址。蓝牙则还是更省事,Client端注册如下一个广播监听蓝牙搜索响应事件即可,Server端则需要确保蓝牙已打开并且能被其他设备搜索到,如下图:
Client端蓝牙搜索响应广播
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Message msg = mHandler.obtainMessage();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = new String(device.getName());
Log.d(TAG, "BT found device name:"+ deviceName);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED)
{
deviceNameList.add(device.getName());
deviceAddressList.add(device.getAddress());
}
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
Log.v(TAG, "Receive Bluetooth ACTION_DISCOVERY_FINISHED!");
}
if(deviceNameList.size() > 0)
{
msg.what = HANDLER_FIND_DEVICES;
}
else
{
msg.what = HANDLER_NODEVICES_CHECKNETWORK;
}
mHandler.sendMessage(msg);
}
};
实际以上方式是临时搜索到Server端,系统会自动弹出蓝牙配对窗口提示配对(如未在蓝牙设置界面手动配对成功过),此配对信息在app退出后是不被保存的!既然如此,那最好的做法是先到蓝牙设置界面手动将Client端与Server端进行配对!做法就不用笔者介绍了吧。。。。
如果配对成功了,那无需搜索我们也可以获取到Server端的信息,如下:
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
/*将已配对的设备加入*/
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
String deviceName = new String(device.getName());
Log.d(TAG, "BT found device name:"+ deviceName);
deviceNameList.add(device.getName());
deviceAddressList.add(device.getAddress());
}
}
备注:这里完全由系统的蓝牙搜索协议搜索Server端,所以即使不是我们的Server端的蓝牙设备都会被搜索到,贸然去连接肯定失败,所以需要再想办法筛选出Server端!这个留待读者自行设计,欢迎回复讨论哦~
获取到Server端地址信息后,接下来就是收发消息转化成按键事件上报!
2)Wifi版本是将Client端的虚拟按键事件转化成简单字符串用Socket发送至Sever端,Server端解析字符串获得按键事件,并使用injectInputEvent方法向android上层上报按键事件;蓝牙版本只需将其中的Socket替换成BluetoothSocket,其他事与通信协议无关,自然无需修改。
Wifi下是用某个端口号(笔者使用的9999)在Client端与Server端建立TCP连接:
Client端:
socket_9999 = new Socket(serverAddress_s, 9999);//serverAddress_s为第一步Server端回复中取得
Server端:
try {
mWifiServerSocket = new ServerSocket(9999, 3);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Socket client = mWifiServerSocket.accept();
蓝牙版本类似:
Client端:
device = mBtAdapter.getRemoteDevice(BlueToothAddress);//BlueToothAddress为前面配对的或者临时搜索的蓝牙设备中取得
//创建一个Socket连接:只需要服务器在注册时的UUID号
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
//连接
socket.connect();
Server端:
try {
/* 创建一个蓝牙服务器
* 参数分别:服务器名称、UUID */
mBTServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BluetoothSocket socket = mBTServerSocket.accept();
至此蓝牙替换Wifi版本的android手机远程遥控即OK了!放上一张笔者成功运行的截面图
附源码!
:handshake不错!!!!!
谢谢分享 多谢分享
页:
[1]