Android学习——地图(实时跟踪导航案例)

实时跟踪导航案例

配置

获取秘钥

	<meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="B0V67sHgKyzFK6QYNwKs6WxhNDvocIq3" />

添加权限

    //获取设备网络状态,禁用后无法获取网络状态
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    //网络权限,当禁用后,无法进行检索等相关业务
    <uses-permission android:name="android.permission.INTERNET" />
    //读取设备硬件信息,统计数据
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    //读取系统信息,包含系统版本等信息,用作统计
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    //获取设备的网络状态,鉴权所需网络代理
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    //允许sd卡写权限,需写入地图数据,禁用后无法显示地图
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    //这个权限用于进行网络定位
    <uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
    //这个权限用于访问GPS定位
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    //获取统计数据
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    //使用步行AR导航,配置Camera权限
    <uses-permission android:name="android.permission.CAMERA" />
    //程序在手机屏幕关闭后后台进程仍然运行
    <uses-permission android:name="android.permission.WAKE_LOCK" />

声明定位的service组件

	<service android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote"/>

导包
在这里插入图片描述在这里插入图片描述

创建跟踪对象和细节对象

package com.example.track;

import java.util.ArrayList;

public class Track {
    private int id;
    private String track_name;
    private String create_date;
    private String start_loc;
    private String end_loc;
    private ArrayList<TrackDetail> trackDetails;

    public Track(int id, String track_name, String create_date, String start_loc, String end_loc) {
        super();
        this.id = id;
        this.track_name = track_name;
        this.create_date = create_date;
        this.start_loc = start_loc;
        this.end_loc = end_loc;
    }

    public Track(String track_name, String create_date, String start_loc, String end_loc) {
        super();
        this.track_name = track_name;
        this.create_date = create_date;
        this.start_loc = start_loc;
        this.end_loc = end_loc;
    }

    public Track(){super();}

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTrack_name() {
        return track_name;
    }

    public void setTrack_name(String track_name) {
        this.track_name = track_name;
    }

    public String getCreate_date() {
        return create_date;
    }

    public void setCreate_date(String create_date) {
        this.create_date = create_date;
    }

    public String getStart_loc() {
        return start_loc;
    }

    public void setStart_loc(String start_loc) {
        this.start_loc = start_loc;
    }

    public String getEnd_loc() {
        return end_loc;
    }

    public void setEnd_loc(String end_loc) {
        this.end_loc = end_loc;
    }

    public ArrayList<TrackDetail> getTrackDetails() {
        return trackDetails;
    }

    public void setTrackDetails(ArrayList<TrackDetail> trackDetails) {
        this.trackDetails = trackDetails;
    }
}

package com.example.track;

public class TrackDetail {
    private int id;
    private double lat;
    private double lag;
    private Track track;

    public TrackDetail(int id, double lat, double lag) {
        super();
        this.id = id;
        this.lat = lat;
        this.lag = lag;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLag() {
        return lag;
    }

    public void setLag(double lag) {
        this.lag = lag;
    }

    public Track getTrack() {
        return track;
    }

    public void setTrack(Track track) {
        this.track = track;
    }
}

创建数据库类

package com.example.track;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME="track.db";
    //表名
    public static String TABLE_TRACK="track";
    public static String TABLE_TRACK_DETAIL="track_detail";

    //字段
    public static String ID="_id";
    //跟踪表
    public static String TRACK_NAME="track_name";
    public static String CREATE_DATE="create_date";
    public static String START_LOC="start_loc";
    public static String END_LOC="end_loc";
    //明细表
    public static String TID="tid";//线路的id
    public static String LAT="lat";//纬度
    public static String LNG="lng";//经度

    private static String CREATE_TABLE_TRACK="create table track(_id integer primary key autoincrement,track_name text,create_date text,start_loc text,end_loc text)";
    private static String CREATE_TABLE_TRACK_DETAIL="create table track_detail(_id integer primary key autoincrement,tid integer not null,lat real,lng real)";

    private static int VERSION=1;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_TRACK);
        db.execSQL(CREATE_TABLE_TRACK_DETAIL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion>oldVersion){
            db.execSQL("drop table if exists track");
            db.execSQL("drop table if exists track_detail");
            db.execSQL(CREATE_TABLE_TRACK);
            db.execSQL(CREATE_TABLE_TRACK_DETAIL);
        }
    }
}

package com.example.track;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;

public class DatabaseAdapter {

    private DatabaseHelper dbHelper;
    public DatabaseAdapter(Context context){
        dbHelper=new DatabaseHelper(context);
    }

    //添加线路跟踪
    public int addTrack(Track track){
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put(DatabaseHelper.TRACK_NAME,track.getTrack_name());
        values.put(DatabaseHelper.CREATE_DATE,track.getCreate_date());
        values.put(DatabaseHelper.START_LOC,track.getStart_loc());
        values.put(DatabaseHelper.END_LOC,track.getEnd_loc());
        long id=db.insertOrThrow(DatabaseHelper.TABLE_TRACK,null,values);
        db.close();
        return (int) id;
    }

    //更新终点地址
    public void updateEndLoc(String endLoc,int id){
        String sql="update track set end_loc=? where _id=?";
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        db.execSQL(sql,new Object[]{endLoc,id});
        db.close();
    }

    //添加线路跟踪明细
    public void addTrackDetail(int tid,double lat,double lng){
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        String sql="insert into track_detail(tid,lat,lng) values(?,?,?)";
        db.execSQL(sql,new Object[]{tid,lat,lng});
        db.close();
    }

    //根据ID查询线路跟踪
    public ArrayList<TrackDetail> getTrackDetails(int id){
        String sql="select _id,lat,lng from track_detail where tid=? order by _id desc";
        ArrayList<TrackDetail> list=new ArrayList<TrackDetail>();
        SQLiteDatabase db=dbHelper.getReadableDatabase();
        Cursor c=db.rawQuery(sql,new String[]{String.valueOf(id)});
        if (c!=null){
            TrackDetail detail=null;
            while (c.moveToNext()){
                detail=new TrackDetail(c.getInt(0),c.getDouble(1),c.getDouble(2));
                list.add(detail);
            }
            c.close();
        }
        db.close
        return list;
    }

    //查询所有线路
    public ArrayList<Track> getTracks(){
        ArrayList<Track> tracks=new ArrayList<Track>();
        String sql="select _id,track_name,create_date,start_loc,end_loc from track";
        SQLiteDatabase db=dbHelper.getReadableDatabase();
        Cursor c=db.rawQuery(sql,null);
        Track t=null;
        if (c!=null){
            while (c.moveToNext()){
                t=new Track(c.getInt(0),c.getString(1),c.getString(2),c.getString(3),c.getString(4));
                tracks.add(t);
            }
            c.close();
        }
        db.close();
        return tracks;
    }

    //根据id删除线路
    public void delTrack(int id){
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        String sql1="delete from track where _id=?";
        String sql2="delete from track_detail where tid=?";
        try {
            db.beginTransaction();
            db.execSQL(sql2,new Object[]{id});
            db.execSQL(sql1,new Object[]{id});
            db.setTransactionSuccessful();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            db.endTransaction();
            if (db!=null){
            	db.close();
            }
        }
    }
}

main类

package com.example.track;

import android.content.DialogInterface;
import android.os.Handler;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity {
    private static final int PLAYBACK_OVER=1;
    private MapView mMapView;
    private BaiduMap baiduMap;
    private LocationClient mLocationClient=null;
    private MyLocationListener myLocationListener;
    private double currentLat,currentLng;//当前经纬度
    private String currentAddr;//当前所有的地址
    private DatabaseAdapter dbAdapter;
    private GeoCoder geoCoder;
    private int currentTrackLineID;//当前跟踪的线路ID
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化SDK
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        //获取地图控件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        initBaiduMap();//初始化地图,显示我的当前位置
        dbAdapter=new DatabaseAdapter(this);
    }

    private void initBaiduMap() {
        baiduMap=mMapView.getMap();
        baiduMap.setMyLocationEnabled(true);//打开定位
        mLocationClient=new LocationClient(getApplicationContext());//声明LocationClient类
        myLocationListener=new MyLocationListener();
        mLocationClient.registerLocationListener(myLocationListener);
        initLocation();
        mLocationClient.start();//开启定位
        mLocationClient.requestLocation();//发起定位请求

        //用于转化地理编码的监听器
        geoCoder=GeoCoder.newInstance();
        geoCoder.setOnGetGeoCodeResultListener(new OnGetGeoCoderResultListener() {
            @Override
            public void onGetGeoCodeResult(GeoCodeResult geoCodeResult) {

            }

            @Override
            public void onGetReverseGeoCodeResult(ReverseGeoCodeResult reverseGeoCodeResult) {
                if (reverseGeoCodeResult==null||reverseGeoCodeResult.error!= SearchResult.ERRORNO.NO_ERROR){
                    //没有检索到结果
                }else {
                    //获取地理编码结果
                    currentAddr=reverseGeoCodeResult.getAddress();
                    Log.i("tag",currentAddr);
                    //更新线路结束位置
                    dbAdapter.updateEndLoc(currentAddr,currentTrackLineID);
                }
            }
        });
    }

    /*设置定位参数包括:定位模式(高精度定位模式,低功耗定位模式和仅用设备定位模式),返回坐标类型,是否打开GPS,是否返回地址信息、位置语义化信息、POI信息等等。
   LocationClientOption类,该类用来设置定位SDK的定位方式,e.g.:*/
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setCoorType("bd09ll");//可选,默认gcj02,设置返回的定位结果坐标系
        int span = 5000;
        option.setScanSpan(span);//可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于5000ms才是有效的
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//可选,默认false,设置是否使用gps
        option.setLocationNotify(true);//可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
        option.SetIgnoreCacheException(false);//可选,默认false,设置是否收集CRASH信息,默认收集
        option.setEnableSimulateGps(false);//可选,默认false,设置是否需要过滤gps仿真结果,默认需要
        mLocationClient.setLocOption(option);
    }

    boolean flag=true;
    //位置监听器
    class MyLocationListener implements BDLocationListener{
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {//接收位置信息的回调方法
            if (bdLocation!=null && flag){
                flag=false;
                currentLat=bdLocation.getLatitude();//当前纬度
                currentLng=bdLocation.getLongitude();//当前精度
                currentAddr=bdLocation.getAddrStr();//当前位置的地址
                //构造我的当前位置信息
                MyLocationData.Builder builder=new MyLocationData.Builder();
                builder.latitude(bdLocation.getLatitude());//设置纬度
                builder.longitude(bdLocation.getLongitude());//设置经度
                builder.accuracy(bdLocation.getRadius());//设置精度
                builder.direction(bdLocation.getDirection());//设置方向
                builder.speed(bdLocation.getSpeed());//设置速度
                MyLocationData locationData=builder.build();
                //把我的位置信息设置到地图上
                baiduMap.setMyLocationData(locationData);
                //配置我的位置 当前经纬度
                LatLng latLng=new LatLng(currentLat,currentLng);
                //(跟随态,允不允许显示方向,默认图标)
                baiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
                        MyLocationConfiguration.LocationMode.FOLLOWING,
                        true,null));
                //设置我的位置为地图中心点(缩放级别3-20)
                baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngZoom(latLng,16));
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main,menu);
        return true;
    }

    //功能菜单项
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.mylocation:
                mylocation();//我的位置
                break;
            case R.id.start_track:
                startTrack();//开始跟踪
                break;
            case R.id.end_track:
                endTrack();//结束跟踪
                break;
            case R.id.track_back:
                trackBack();//跟踪回放
                break;
            default:
                break;
        }
        return true;
    }

    //我的位置
    private void mylocation() {
        Toast.makeText(this, "正在定位中...", Toast.LENGTH_SHORT).show();
        flag=true;
        baiduMap.clear();//清除地图上自定义的图层
        baiduMap.setMyLocationEnabled(true);
        mLocationClient.requestLocation();//发起定位请求
    }

    //开始追踪功能
    private void startTrack() {
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle("线路跟踪");
        builder.setCancelable(true);
        final View view=getLayoutInflater().inflate(R.layout.add_track_line_dialog,null);
        builder.setView(view);
        builder.setPositiveButton("添加", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                EditText et_track_name=view.findViewById(R.id.editText1_track_name);
                String trackName=et_track_name.getText().toString();
                Log.i("tag",trackName);
                createTrack(trackName);//创建线路跟踪
                Toast.makeText(MainActivity.this, "跟踪开始...", Toast.LENGTH_SHORT).show();
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.show();
    }

    //结束跟踪
    private void endTrack() {
        isTracking=false;//结束线程
        Toast.makeText(this, "跟踪结束", Toast.LENGTH_SHORT).show();
        //转化地址编码,把最后的经纬度转换成地址
        geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(new LatLng(currentLat,currentLng)));
    }

    //跟踪回放
    AlertDialog dialog=null;
    private void trackBack() {
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setCancelable(false);
        builder.setTitle("跟踪线路列表");
        View view=getLayoutInflater().inflate(R.layout.track_line_playback_dialog,null);
        ListView playbackListView=view.findViewById(R.id.listView1_play_back);
        ArrayList<HashMap<String,String>> data=new ArrayList<HashMap<String, String>>();
        ArrayList<Track> tracks=dbAdapter.getTracks();
        HashMap<String,String> map=null;
        Track t=null;
        for (int i=0;i<tracks.size();i++){
            map=new HashMap<String,String>();
            t=tracks.get(i);
            map.put("id",String.valueOf(t.getId()));
            map.put("trackName_createDate",t.getTrack_name()+"---"+t.getCreate_date());
            map.put("startEndLoc","从["+t.getStart_loc()+"]到["+t.getEnd_loc()+"]");
            data.add(map);
        }
        SimpleAdapter adapter=new SimpleAdapter(this,data,R.layout.playback_item,new String[]{
                "id","trackName_createDate","startEndLoc"},new int[]{
                        R.id.textView_id,R.id.textView_trackname,R.id.textView_startEndLoc});
        playbackListView.setAdapter(adapter);
        playbackListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                TextView tv_id=view.findViewById(R.id.textView_id);
                int _id=Integer.parseInt(tv_id.getText().toString());
                baiduMap.clear();
                new Thread(new TrackPlaybackThread(_id)).start();
                dialog.dismiss();
            }
        });
        builder.setView(view);
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                list.clear();
                dialog.dismiss();
            }
        });
        dialog = builder.create();
        dialog.show();
    }

    private boolean isTracking=false;
    //用于存储两个相邻的经纬度点划线
    private ArrayList<LatLng> list=new ArrayList<LatLng>();
    //创建一条线路跟踪
    private void createTrack(String trackName) {
        Track track=new Track();
        track.setTrack_name(trackName);
        track.setCreate_date(DateUtils.toDate(new Date()));
        track.setStart_loc(currentAddr);
        currentTrackLineID=dbAdapter.addTrack(track);
        dbAdapter.addTrackDetail(currentTrackLineID,currentLat,currentLng);
        baiduMap.clear();
        addOverlay();
        list.add(new LatLng(currentLat,currentLng));
        isTracking=true;//线程模拟的标记
        Log.i("tag", String.valueOf(list));
        new Thread(new TrackThread()).start();
    }

    //在地图上添加图层(线路的每一个点)
    private void addOverlay() {
        //添加一个标注覆盖物在当前位置
        //构建Marker图标
        baiduMap.setMyLocationEnabled(false);
        BitmapDescriptor bitmap= BitmapDescriptorFactory.fromResource(android.R.drawable.star_on);
        //构建MarkerOption,用于在地图上添加Marker
        LatLng latLng=new LatLng(currentLat,currentLng);
        OverlayOptions options=new MarkerOptions().position(latLng).icon(bitmap);
        //在地图上添加Marker,并登录
        baiduMap.addOverlay(options);
        //把当前添加的位置作为地图中心点
        baiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLng(latLng));
    }
    //两个点之间划线
    private void drawLine(){
        OverlayOptions lineOptions=new PolylineOptions().points(list).color(0xFFFF0000);
        baiduMap.addOverlay(lineOptions);
        list.remove(0);
    }

    private class TrackPlaybackThread implements Runnable {
        private int id;
        public TrackPlaybackThread(int id) {
            this.id=id;
        }

        @Override
        public void run() {
            ArrayList<TrackDetail> trackDetails=dbAdapter.getTrackDetails(id);
            TrackDetail td=null;
            list.clear();
            currentLat=trackDetails.get(0).getLat();
            currentLng=trackDetails.get(0).getLng();
            list.add(new LatLng(currentLat,currentLng));
            addOverlay();
            for (int i = 0; i <trackDetails.size() ; i++) {
                td=trackDetails.get(i);
                currentLat=td.getLat();
                currentLat=td.getLng();
                list.add(new LatLng(currentLat,currentLng));
                addOverlay();
                drawLine();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            handler.sendEmptyMessage(PLAYBACK_OVER);
        }
    }
    private Handler handler=new Handler(){
        public void handleMessage(android.os.Message msg){
            switch (msg.what){
                case PLAYBACK_OVER:
                    Toast.makeText(MainActivity.this, "回放结束", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }
    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
    }

    class TrackThread implements Runnable {
        @Override
        public void run() {
            while (isTracking){
                getLocation();
                dbAdapter.addTrackDetail(currentTrackLineID,currentLat,currentLng);
                addOverlay();
                list.add(new LatLng(currentLat,currentLng));
                drawLine();
                Log.i("tag","drawline");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private void getLocation() {
        currentLat=currentLat+Math.random()/1000;
        currentLng=currentLng+Math.random()/1000;
    }
}


在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/UUUUUltraman/article/details/89850163