STM32开发GPRS传输的GPS定位器-android studio开发客户端APP显示轨迹

前面文章介绍如何开发定位器硬件,单片机软件,服务器软件,上位机客户端软件,下面介绍如何使用android studio开发客户端APP显示轨迹。

能自己做的事从来不求人,前面用C#实现了PC端显示定位数据轨迹,用android studio开发客户端APP显示轨迹的流程也是大同小异的,只是开发语言的不同,安卓应用程序是使用Java开发的,但是C#和Java很相似。

用android studio开发客户端APP显示轨迹大概分这么几个步骤,1,编写xml文件,2,TCP服务器通信部分,3,调用百度地图API实现轨迹绘制。

1,XML布局文件加入百度地图mapview,和两个文本框,代码及UI界面如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context="com.example.myapplication.MainActivity">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapview"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:clickable="true" />
    <TextView
    android:id="@+id/Text2view"
    android:layout_width="match_parent"
    android:layout_height="20dp"
    android:text="---"
    android:layout_below="@id/bmapview"/>
    <TextView
        android:id="@+id/Textview"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:text="---"
        android:layout_below="@id/Text2view"/>
</RelativeLayout>

2,编写TCP与服务器通信程序

这部分主要有三个线程组成,一个用于连接服务器,一个向服务器发送数据,一个接收服务器的数据。

连接服务器线程,这里要实时检查安卓客户端与服务器的连接是否有效,做断线重连,并且开启发送数据线程和接收数据线程,程序如下

private class connectToServer extends Thread{
        @Override
        public void run() {
            while(true)
            {
                try
                {
                    //客户端向服务器发送连接请求
                    //c_Socket = new Socket("---.---.---.---",8888);
                    if (c_Socket==null)
                    {
                        c_Socket = new Socket("---.---.---.---",8888);
                        if (c_Socket.isConnected())
                        {
                            TCP_R_Count=0;
                            int port = c_Socket.getLocalPort();
                            Message msg = new Message();
                            msg.what = 5;
                            msg.obj = String.valueOf(port);
                            mHandler.sendMessage(msg);
                            c_readflag = true;
                            new c_ReadThread().start();
                            new SenfToServer().start();
                            connect=true;
                        }

                    }
                    if(connect==false)
                    {
                        if(c_Socket!=null){
                            c_Socket.close();
                            c_Socket=null;
                        }

                    }

                    //c_Socket = new Socket("192.168.5.32",8888);
                    //c_Socket.connect(IPAddress.Parse(c_ip.getText().toString()), Int32.Parse(c_port.Text));
                }catch(Exception ee)
                {
                    ee.printStackTrace();
                }
            }
            //super.run();
        }

    }

发送线程 目前这部分比较简单,随着功能的增加会逐步丰富。

    //客户端向服务器发送数据
    private class SenfToServer extends Thread{
        @Override
        public void run() {
            while(true)
            {
                if(c_Socket!=null){
                    if (c_Socket.isConnected())
                    {
                        try{
                            out = c_Socket.getOutputStream();
                            out.write("----------------".getBytes());
                            out.flush();
                            SenfToServer.sleep(60000);
                        }
                        catch(Exception e){
//                        connect=false;
                        }
                    }
                }
            }
            //super.run();
        }
    }

接收线程

接收线程接收服务器发来的GPS定位数据,通过Handler向主线程传递消息。这里要检测TCP连接的有效性,如果断开连接要重连服务器。

    //客户端接收服务器发来的信息
    private class c_ReadThread extends Thread
    {
        @Override
        public void run() {
            // TODO 自动生成的方法存根
            try {
                InputStream input = c_Socket.getInputStream();
                while (c_readflag)
                {
                    byte[] buff = new byte[100];

                    int size = input.read(buff);
                    if((size>12)){
                        if((buff[0]=='$')&&(buff[1]=='3')&&(buff[12]!=0)){
                            Message msg = new Message();
                            msg.what =4;
                            msg.obj = new String(buff,0,size);
                            latitude_o=latitude_n;
                            longitude_o=longitude_n;
                            latitude_n=new String(buff,20,7);
                            longitude_n=new String(buff,12,8);

                            Log.i("n","纬度:"+latitude_n+" | 经度:"+longitude_n);

                            if((latitude_n!="00.0000")&&(longitude_n!="000.0000")){
                                mHandler.sendMessage(msg);
                            }else{
                                latitude_n=null;
                                longitude_n=null;
                            }
                        }
                    }
                    if(size>0)
                    {
                        TCP_R_Count=TCP_R_Count+size;
                        Message msg = new Message();
                        msg.what =5;
                        mHandler.sendMessage(msg);
                    }
                }
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
                connect=false;
            }
            super.run();
        }
    }

3,调用百度地图API实现轨迹绘制

首先获取xml中加入的地图组件,mMapView = (MapView) findViewById(R.id.bmapview);    
mBaiduMap = mMapView.getMap();设置地图缩放级别mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(21).build()));之后,使用Overlay mPolyline = mBaiduMap.addOverlay(mOverlayOptions);逐段加入两点连线,最终形成上图中的轨迹。更新坐标位置,让最后发来的位置坐标作为地图的中心mBaiduMap.animateMapStatus(u);这里还要注意从GPS卫星接收到的经纬度和百度地图经纬度有偏差,要使用下面方法做纠偏。CoordinateConverter converter1  = new CoordinateConverter().from(CoordinateConverter.CoordType.GPS).coord(p1); LatLng desLatLng1 = converter1.convert();

关键代码如下

mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(msg.what ==4){
                    if((latitude_n!=null) &&(longitude_n!=null)&&(latitude_o!=null) &&(longitude_o!=null)){

                        List<LatLng> points = new ArrayList<LatLng>();
                        LatLng p1,p2 ;
                        p1=new LatLng( Double.parseDouble(latitude_n),Double.parseDouble(longitude_n));
                        // sourceLatLng待转换坐标

                        CoordinateConverter converter1  = new CoordinateConverter()
                                .from(CoordinateConverter.CoordType.GPS)
                                .coord(p1);
                        LatLng desLatLng1 = converter1.convert();
                        points.add(desLatLng1);

                        Log.i("P1","纬度:"+desLatLng1.latitude+" | 经度:"+desLatLng1.longitude);

                        p2=new LatLng( Double.parseDouble(latitude_o),Double.parseDouble(longitude_o));
                        // sourceLatLng待转换坐标

                        CoordinateConverter converter2  = new CoordinateConverter()
                                .from(CoordinateConverter.CoordType.GPS)
                                .coord(p2);
                        LatLng desLatLng2 = converter2.convert();
                        points.add(desLatLng2);

                        Log.i("P2","纬度:"+desLatLng2.latitude+" | 经度:"+desLatLng2.longitude);

                        //设置折线的属性
                        OverlayOptions mOverlayOptions = new PolylineOptions()
                                .width(10)
                                .color(0xAAFF0000)
                                .points(points);
                        Overlay mPolyline = mBaiduMap.addOverlay(mOverlayOptions);
                        //if(((latitude_n.equals(latitude_o))&&(longitude_n.equals(longitude_o))))
                        {

                            //定义Maker坐标点
                            LatLng p3;
                            p3=new LatLng( Double.parseDouble(latitude_n),Double.parseDouble(longitude_n));

                            // sourceLatLng待转换坐标

                            CoordinateConverter converter3  = new CoordinateConverter()
                                    .from(CoordinateConverter.CoordType.GPS)
                                    .coord(p3);
                            LatLng desLatLng3 = converter3.convert();
                            /*
                            //构建Marker图标
                            BitmapDescriptor bitmap = BitmapDescriptorFactory
                                    .fromResource(R.drawable.icon_w);
                            //构建MarkerOption,用于在地图上添加Marker
                            OverlayOptions option = new MarkerOptions()
                                    .position(desLatLng3)
                                    .icon(bitmap);
                            //在地图上添加Marker,并显示
                            mBaiduMap.addOverlay(option);
                            */
                            // 构造定位数据
                            MyLocationData locData = new MyLocationData.Builder()
                                    .accuracy(0)    //设置精度
                                    .direction(0)		 // 此处设置开发者获取到的方向信息,顺时针0-360
                                    .latitude(desLatLng3.latitude)  	 	// 设置纬度坐标
                                    .longitude(desLatLng3.longitude)    //设置经度坐标
                                    .build();
                            // 设置定位数据
                            mBaiduMap.setMyLocationData(locData);
                            //设置自定义定位图标
                            BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
                                    .fromResource(R.drawable.icon_w);
                            mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;  //设置定位模式
                            //位置构造方式,将定位模式,定义图标添加其中
                            MyLocationConfiguration config = new MyLocationConfiguration(mCurrentMode, true, mCurrentMarker);
                            mBaiduMap.setMyLocationConfigeration(config);  //地图显示定位图标

                            MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(desLatLng3);  //更新坐标位置
                            mBaiduMap.animateMapStatus(u);                            //设置地图位置
                        }



                        //获取显示LocationProvider名称的TextView组件
                        TextView textView = (TextView) findViewById(R.id.Textview);
                       // StringBuilder stringBuilder = new StringBuilder();  //使用StringBuilder保存数据
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");
                        Date date = new Date(System.currentTimeMillis());
                        String str=simpleDateFormat.format(date);

                        textView.setText("");
                        textView.append(str + "\n");
                        textView.append(("N纬度:"+desLatLng1.latitude).toString() + "\n");
                        textView.append(("N纬度:"+desLatLng2.latitude).toString() + "\n");
                        textView.append(("O经度:"+desLatLng1.longitude).toString() + "\n");
                        textView.append(("O经度:"+desLatLng2.longitude).toString() + "\n");
                    }
                }
                if(msg.what ==5){
                    TextView textView = (TextView) findViewById(R.id.Text2view);
                    textView.setText("receive is  "+Integer.toString(TCP_R_Count));
                }
                super.handleMessage(msg);
            }

        };

猜你喜欢

转载自blog.csdn.net/gd1984812/article/details/103940560