zoukankan      html  css  js  c++  java
  • Android当无线鼠标,通过蓝牙与pc通信,pc端用java写 分类: Android 2015-07-30 09:24 18人阅读 评论(0) 收藏

    最近想写一个小程序,把android通过蓝牙当做无线鼠标操作笔记本,pc端用java语言实现,于是查了查资料,android的蓝牙开发网上的例子也不少,自动的sdk里也有一个例子BluetoothChat,把android蓝牙经常用的方法基本上都用了,而且http://blog.csdn.net/pku_android/article/details/7430849这个例子也很不错,参照这些例子,android端的程序也就很简单了。首先这个原理很简单,通过蓝牙进行连接,获得手指在屏幕上水平方向移动距离的x和竖直方向y,并发送到pc端,然后控制pc端鼠标移动,至于数据格式,采用了<String,String>这样的形式,这样在pc端解析的时候也很简单,截取字符串就行了,在界面中增加两个按钮分别作为左键和右键,触发事件时发送自定义的字符串就行,在pc端接收后模拟鼠标左键或右键按下事件即可。
          下面android端开始,首先要声明一个[url=]BlueAdapter对象并获得这个对象[/url][mw_shl_code=java,true]blueadapter=BluetoothAdapter.getDefaultAdapter();[/mw_shl_code][url=],[/url][url=]这个对象相当于本地蓝牙,[/url]要通过本地蓝牙远程连接pc端的蓝牙还需要pc端蓝牙的MAC地址,要获得MAC地址首先要在设置页面里让android与pc端蓝牙匹配,然后可以通过getpairedDevices()方法获得,[mw_shl_code=java,true]private void getpairedDevices(){
            Set<BluetoothDevice> pairedDevice=blueadapter.getBondedDevices();
            if(mArrays!=null){
                    mArrays.clear();
            }
            if(pairedDevice.size()>0){
                    for(BluetoothDevice device:pairedDevice){
                            names.add(device.getName());//设备名字
                            addresses.add(device.getAddress());//设备地址
                    }
            }
    } [/mw_shl_code]
    names和addresses是声明的两个ArrayList<String>对象,用来动态添加字符串,我的方法是添加一个ListView对象,把names放在封装在ListView对象中,得到点击ListView的位置,然后通过addresses得到所连接的MAC地址,然后调用[url=]getRemoteDevice[/url]([url=]String[/url] address)方法得到BluetoothDevice对象[mw_shl_code=java,true]BluetoothDevice device = blueadapter.getRemoteDevice(addresses.get(position));[/mw_shl_code]然后就是通过device得到ConnectThread对象,ConnectThread类用来来实现连接,创建BluetoothSocket对象发送数据,由于只需要发送数据不用接收pc端发来的数据,所以sdk例子中的接收数据部分就可以省略了,在ConnectThread中加一个write方法就行了,ConnectThread的代码如下:[mw_shl_code=java,true]private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
            UUID MY_UUID=UUID.fromString("04c6093b-0000-1000-8000-00805f9b34fb");
            private OutputStream mmOutStream;//输出流
        public ConnectThread(BluetoothDevice device) {       
            BluetoothSocket tmp = null;
                  
            try {            
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);//获得socket对象
            } catch (IOException e) { }
            mmSocket = tmp;
        }

        public void run() {
           
            try {            
                mmSocket.connect();//连接
                            mmOutStream = mmSocket.getOutputStream();
            } catch (IOException connectException) {
                try {
                    mmSocket.close();
                } catch (IOException closeException) { }
                return;
            }
        }

       //取消 
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
            //向输出流中写数据
             public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
                    e.printStackTrace();
            }
          
        }
    }[/mw_shl_code]
    下面就是活动手指移动距离了,在界面中随便添加一个控件,TextView或ImageView,只要有setOnTouchListener方法就行,因为要捕捉手指移动事件,[mw_shl_code=java,true]
    private float initx;//初始x,y
    private float inity;
    private float disx;//移动x,y
    private float disy;
                    //mousedraw设置监听,发送鼠标移动信息
    mousedraw.setOnTouchListener(new OnTouchListener(){

                            public boolean onTouch(View arg0, MotionEvent event) {
                                    switch(event.getAction()){
                                    case MotionEvent.ACTION_DOWN:
                                            initx=event.getX();
                                            inity=event.getY();                                        
                                            break;
                                    case MotionEvent.ACTION_MOVE:
                                            disx=event.getX()-initx;//x方向的移动距离
                                            disy=event.getY()-inity;//y方向的移动距离
                                            
                                            initx=event.getX();
                                            inity=event.getY();
                                            if(disx!=0||disy!=0){
                                                    msg="<"+disx+","+disy+">";//根据自定义的格式得到字符串
                                                    connectblue.write(msg.getBytes());//发送数据
                                            }
                                            break;
                                    }
                                    return true;
                            }
                            
                    });[/mw_shl_code]
    其中主要的也就是[mw_shl_code=java,true]msg="<"+disx+","+disy+">";
    connectblue.write(msg.getBytes());[/mw_shl_code]这两句了,connectblue是获得的ConnectThread对象,write就是发送数据了。至于左键,右键就不写了,原理一样,只不过发送字符串变成了特定的字符串了,个人建议不要有大于,小于符号因为pc端可以通过是否含有大于,小于号来判断是鼠标移动还是按下。这样android端就差不多了。

    下面是pc端,pc端用java写,要让鼠标移动,并且可以产生按下事件,于是就用到了Robot。java中的Robot专门用于控制键盘和鼠标。而java调用蓝牙则需要一个叫做bluecove的第三方库,可以在网上下,要取得数据就要取得连接,首先写一个连接类来建立连接[mw_shl_code=java,true]public class WaitThread implements Runnable{
            public WaitThread(){
                    
            }
            @Override
            public void run() {
                    // TODO Auto-generated method stub
                    waitForConnection();
            }
            //Waiting for connection from devices
            private void waitForConnection(){
                    //retrieve the local Bluetooth device object
                    LocalDevice local=null;
                    StreamConnectionNotifier notifier;
                    StreamConnection connection=null;
                    
                    //setup the server to listen for connection
                    try{
                            local=LocalDevice.getLocalDevice();
                            local.setDiscoverable(DiscoveryAgent.GIAC);
                            UUID uuid=new UUID(80087355); // "04c6093b-0000-1000-8000-00805f9b34fb"
                            
                            String url="btspp://localhost:"+uuid.toString()+";name=RemoteBluetooth";
                            notifier=(StreamConnectionNotifier)Connector.open(url);
                    }catch(Exception e){
                            e.printStackTrace();
                            return;
                    }
                    //waiting for connection
                    while(true){
                            try{
                                    System.out.println("waiting for connection...");
                                    connection=notifier.acceptAndOpen();
                                    
                                    Thread processThread=new Thread(new ProcessConnectionThread(connection));
                                    processThread.start();//启动ProcessConnectionThread实例
                            }catch(Exception e){
                                    e.printStackTrace();
                                    return;
                            }
                    }
            }

    }[/mw_shl_code]ProcessConnectionThread作用是接收数据并进行分析[mw_shl_code=java,true]public class ProcessConnectionThread implements Runnable{
            private StreamConnection mConnection;//连接对象
            
            //左键,右键
            private String MOU_LEFT="MOU_LEFT";
            private String MOU_RIGH="MOU_RIGH";
            private float nowx;
            private float nowy;
            private String movex_str;
            private String movey_str;
            private float movex=0.0f;
            private float movey=0.0f;
            InputStream inputStream=null;
            public ProcessConnectionThread(StreamConnection connection){
                    mConnection=connection;
            }
            @Override
            public void run() {
                    // TODO Auto-generated method stub
                    try{
                            inputStream=mConnection.openInputStream();
                            byte[] buffer=new byte[1024];
                            int len=-1;
                            System.out.println("waiting for input");
                            String cmd;
                            while(true){                                
                                    if((len=inputStream.read(buffer))!=-1){                                        
                                            cmd=new String(buffer,0,len,Charset.forName("UTF-8"));//获得字符串
                                            processCommand(cmd);
                                    }
                            }
                    }catch(Exception e){
                            e.printStackTrace();
                    }
            }
            private void processCommand(String command){
                    try{
            
                            Robot robot=new Robot();
                            if(command.contains("<")){
                                    movex_str=command.substring(command.indexOf("<")+1, command.indexOf(","));//截取字符串,获得x方向的移动距离
                                    movey_str=command.substring(command.indexOf(",")+1,command.indexOf(">"));//y方向
                                    movex=Float.parseFloat(movex_str);
                                    movey=Float.parseFloat(movey_str);
                                    Point point = MouseInfo.getPointerInfo().getLocation();//获得当前鼠标位置
                                    nowx=point.x;
                                    nowy=point.y;
                                    robot.mouseMove((int)(nowx+movex),(int)(nowy+movey));//鼠标移动到当前位置
                            }else if(command.equals(MOU_LEFT)){
    //左键按下
                                    robot.mousePress(InputEvent.BUTTON1_MASK);
                                    robot.mouseRelease(InputEvent.BUTTON1_MASK);
                            }else if(command.equals(MOU_RIGH)){
    //右键按下
                                    robot.mousePress(InputEvent.BUTTON3_MASK);
                                    robot.mouseRelease(InputEvent.BUTTON3_MASK);
                            }else{
                                    System.out.println(command);
                            }
                            
                    }catch(Exception e){
                            e.printStackTrace();
                    }
            }
    }[/mw_shl_code]
    最后在一个main函数里声明一个WaitThread对象并启动就行了。pc端启动后,可以启动android端,然后就可以通信了。
          好,打完收工。

  • 相关阅读:
    使用REST风格完成MVC前后端分离
    MySQL数据库开发常见问题及几点优化!
    springboot 使用JPA自动生成Entity实体类的方法
    mybatis-plus 自动生成代码
    springboot中使用ContextLoaderListener.getCurrentWebApplicationContext();获取WebApplicationContext为空问题
    Java 7 使用TWR(Try-with-resources)完成文件copy
    MySQL 删除数据库
    MySQL 创建数据库
    MySQL 创建数据表
    JDBC Java 连接 MySQL 数据库
  • 原文地址:https://www.cnblogs.com/xieping/p/4714157.html
Copyright © 2011-2022 走看看