Android实现采集GPS数据并通过socket传输到服务器(二)

上一篇完成了在Android6.0以上的手机申请动态权限,采集实时的GPS数据并显示。我们项目需要的是将GPS数据(非视频数据)和视频数据传输到服务器,这里一般采用socket通信进行传输。

目录

  1. 服务器端(windows)
  2. 客户端(Android手机)

原本在java课上学过一些很简单的socket开发,但是在查阅资料的过程中,发现了这篇文章:Android:这是一份很详细的Socket使用攻略 使用了一个高并发的socket框架mina,也满足了我们项目需要的多个客户端连接服务器端的要求,安全性之类的也有保障,所以打算直尝试使用这个。
这是mina的一点介绍:Apache Mina(一)

1.服务器端(windows)

服务器端在eclipse平台运行,需要链接两个mina的jar包,网上可以搜到很多教程(其实是懒得找自己以前看的那个了)
在这里插入图片描述
1)首先在public类里声明端口8989等等信息

public class server {
    public static void main(String[] args) {
        NioSocketAcceptor acceptor = null;
        try {
            acceptor = new NioSocketAcceptor();
            acceptor.setHandler(new TestHandler());
            acceptor.getFilterChain().addLast("mFilter", new ProtocolCodecFilter(new TextLineCodecFactory()));
            acceptor.setReuseAddress(true);
            acceptor.bind(new InetSocketAddress(8989));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}

2)实现handler类,进行数据的接收、发送、连接开连接关等等。messageReceived中注释的部分是要和服务器端的python程序通信建立的,不需要的话直接删去就可以。
从客户端接收的下次即message,System.out.println("recieve : " + (String) message);这一行是将message转换为string类型打印出来。

class TestHandler extends IoHandlerAdapter {

	 @Override
	 public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
	     System.out.println("exceptionCaught: " + cause);
	 }

	 @Override
	 public void messageReceived(IoSession session, Object message) throws Exception {
		 // message为接收到的信息
		 System.out.println("recieve : " + (String) message);
//	        Socket socket = null;
//	        String codeAdress = "127.0.0.1";
//	        try {
//	            socket = new Socket(codeAdress,8990);
//	            OutputStream outputStream = socket.getOutputStream();
//	            InputStream inputStream = socket.getInputStream();
//	            byte[] bytes = new byte[1024];
//	            //发送数据
//	            outputStream.write(((String) message).getBytes());
//	        } catch (IOException e) {
//	            e.printStackTrace();
//	        }
	     
	 }

	 @Override
	 public void messageSent(IoSession session, Object message) throws Exception {
		 //在这里可以向客户端发送消息
	 }
	 
	 @Override
	 public void sessionClosed(IoSession session) throws Exception {
	     System.out.println("sessionClosed");
	 }

	 @Override
	 public void sessionOpened(IoSession session) throws Exception {
	     System.out.println("sessionOpen");
	 }

	 @Override
	 public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
	 }

	}
2.客户端(Android手机)

1)定义变量。用到线程池,在建立连接和发送信息时用子线程进行。

    //定位变量
    private LocationManager lm;
    private StringBuilder loca_data;
    // Socket变量
    private Socket socket;
    // 线程池
    // 为了方便展示,此处直接采用线程池进行线程管理,而没有一个个开线程
    private ExecutorService mThreadPool;
    long timeGetTime =new Date().getTime();
    private Timer timer = new Timer(true);

    // 输出流对象
    OutputStream outputStream;

    // 连接 断开连接 发送数据到服务器 的按钮变量
    private Button btnConnect, btnDisconnect, btnSend1, btnSend2;
    //显示GPS信息变量
    private TextView tv_show;
    //地址变量
    private EditText urlpush;

2)给按钮connect注册事件:和服务器建立连接

        /**
         * 创建客户端 & 服务器的连接
         */
        btnConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 利用线程池直接开启一个线程 & 执行该线程
                mThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 创建Socket对象 & 指定服务端的IP 及 端口号
                            socket = new Socket(urlpush.getText().toString(), 8989);
                            // 判断客户端和服务器是否连接成功
                            System.out.println(socket.isConnected());
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });

3)给按钮send1注册事件:发送GPS定位数据
其中line = loca_data;即定位数据,采用定时器定时500ms发送

        /**
         * 发送消息 给 服务器
         */
        btnSend1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 利用线程池直接开启一个线程 & 执行该线程
                mThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        /**用定时器间隔发送*/
                        //定时执行任务
                        TimerTask task = new TimerTask() {
                            StringBuilder line;
                            @Override
                            public void run() {
                                try {
                                    outputStream = socket.getOutputStream();
                                    line = loca_data;
                                    outputStream.write((line + "\n").getBytes("utf-8"));
                                    //这里将缓冲区的数据冲入
                                    outputStream.flush();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        };
                        timer.schedule(task, 1000, 500);
                    }
                });

            }
        });

4)为了满足测试需求,定义了按钮send2:发送内置的已经采集好的GPS定位数据。

        final InputStream inputStream = getResources().openRawResource(R.raw.n);
        btnSend2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        /**用定时器间隔发送*/
                        //定时执行任务
                        String line;
                        try {
                            outputStream = socket.getOutputStream();
                            InputStreamReader isr = new InputStreamReader(inputStream);
                            BufferedReader br = new BufferedReader(isr);
                            while ((line = br.readLine()) != null) {
                                Thread.sleep(50);//伪计时器
                                outputStream.write((line + "\n").getBytes("utf-8"));
                                //这里将缓冲区的数据冲入
                                outputStream.flush();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        });

5)定义按钮disconnect:停止发送,断开连接

        /**
         * 断开客户端 & 服务器的连接
         */
        btnDisconnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                try {
                    // 断开 客户端发送到服务器 的连接,即关闭输出流对象OutputStream
                    outputStream.close();

                    // 最终关闭整个Socket连接
                    socket.close();

                    // 判断客户端和服务器是否已经断开连接
                    System.out.println(socket.isConnected());

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
    }

5)这里有点笨的用了这样的方法进行更新GPS数据

    //定义一个更新显示的方法
    private StringBuilder updateShow(Location location) {
        if (location != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("当前的位置信息:\n");
            sb.append("经度:" + location.getLongitude() + "\n");
            sb.append("纬度:" + location.getLatitude() + "\n");
            sb.append("高度:" + location.getAltitude() + "\n");
            sb.append("速度:" + location.getSpeed() + "\n");
            sb.append("方向:" + location.getBearing() + "\n");
            sb.append("定位精度:" + location.getAccuracy() + "\n");
            sb.append("时间:" + timeGetTime + "\n");
            tv_show.setText(sb.toString());
            StringBuilder sb1 = new StringBuilder();
            int id = 111;
            sb1.append("{'id':'"+ id + "',");
            sb1.append("'accuracy':'"+ location.getAccuracy() + "',");
            sb1.append("'speed':'"+ location.getSpeed()+ "',");
            sb1.append("'direction':'"+ location.getBearing() + "',");
            sb1.append("'wgs84':["+ location.getLongitude() + "," + location.getLatitude() + "],");
            sb1.append("'altitude':'"+ location.getAltitude() + "',");
            sb1.append("'timestamp':'"+ timeGetTime + "'}");
            return sb1;
        } else {
            tv_show.setText("");
            return null;
        }

    }

两端搭建完毕后,将电脑连接手机的wifi热点,在app上方输入电脑ip地址
在这里插入图片描述

运行电脑的java程序,依次点击connect建立连接
在这里插入图片描述
点击send1进行GPS数据的发送
在这里插入图片描述
点击disconnect断开连接
在这里插入图片描述
至此完毕。
等我能进去github了再传源码

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值