欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

手机端实时定位

程序员文章站 2022-04-14 11:19:49
项目需要做一个管道巡检的模块,需要用到实时定位。实验了好几种办法,最后还是回归原生应用了。项目的APP是用vue做的,但是定位那叫一个难受,必须用原生应用的辅助定位才能做到准确。最后还是放弃了,回归原生。定位大概用了以下几种:1.cordova 的定位插件: 百度,高德都用了,但是效果都不理想。2.H5定位: 信号强的点没问题,但是我们的应用场景都是信号偏弱的地方,也放弃了。3.百度原生: 最后选用了这种,即使放在后台运行,已然很准确。而且可以辅助H5定位,......

项目需要做一个管道巡检的模块,需要用到实时定位。实验了好几种办法,最后还是回归原生应用了。

项目的APP是用vue做的,但是定位那叫一个难受,必须用原生应用的辅助定位才能做到准确。最后还是放弃了,回归原生。

定位大概用了以下几种:

1.cordova 的定位插件:

    百度,高德都用了,但是效果都不理想。

2.H5定位:

    信号强的点没问题,但是我们的应用场景都是信号偏弱的地方,也放弃了。

3.百度原生:

    最后选用了这种,即使放在后台运行,已然很准确。而且可以辅助H5定位,暂时没时间研究,就直接上原生的了。

    简单介绍下怎么用。

    ① 百度地图SDK 的初始化,这里放在了一个Application中。

         走过弯路,一开始放在启动页面里。正常页面开着没问题,一旦页面进入后台运行,定位就停了。

    @Override
    public void onCreate() {
        super.onCreate();

        SDKInitializer.initialize(getApplicationContext());
        SDKInitializer.setCoordType(CoordType.BD09LL);

        mContext = getApplicationContext();
    }

②  地图组件初始化,在需要定位的页面中即可。

     需要注册一个监听器LocationListener,监听定位完成的事件。

    private void initLocates() {
        // 定位初始化
        mClient = new LocationClient(this);
        LocationClientOption mOption = new LocationClientOption();
        mOption.setScanSpan(5000);
        mOption.setCoorType("bd09ll");
        mOption.setIsNeedAddress(true);
        mOption.setOpenGps(true);
        mClient.setLocOption(mOption);
        mClient.registerLocationListener(myLocationListener);

        //设置后台定位
        //android8.0及以上使用NotificationUtils
        if (Build.VERSION.SDK_INT >= 26) {
            mNotificationUtils = new NotificationUtils(this);
            Notification.Builder builder2 = mNotificationUtils.getAndroidChannelNotification
                    ("掌上巡检", "正在后台定位");
            notification = builder2.build();
        } else {
            //获取一个Notification构造器
            Notification.Builder builder = new Notification.Builder(MainActivity.this);
            Intent nfIntent = new Intent(MainActivity.this, MainActivity.class);

            builder.setContentIntent(PendingIntent.
                    getActivity(MainActivity.this, 0, nfIntent, 0)) // 设置PendingIntent
                    .setContentTitle("掌上巡检") // 设置下拉列表里的标题
                    .setSmallIcon(R.drawable.ic_launcher_foreground) // 设置状态栏内的小图标
                    .setContentText("正在后台定位") // 设置上下文内容
                    .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间

            notification = builder.build(); // 获取构建好的Notification
        }
        notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
        //开启后台定位
        mClient.enableLocInForeground(1, notification);
        mClient.start();
    }

③ 监听器

这里对4.9E-324坐标做了处理,手机没信号的时候回定位到几内亚湾,本初子午线和赤道的焦点。

class  MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            if (bdLocation == null || mMapView == null ||
                    bdLocation.getLongitude() == 4.9E-324 || bdLocation.getLatitude() == 4.9E-324) {
                return;
            }
            MyLocationData locData = new MyLocationData.Builder().accuracy(bdLocation.getRadius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360
                    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
            // 设置定位数据
            mBaiduMap.setMyLocationData(locData);
            //地图SDK处理
            if (isFirstLoc) {
                isFirstLoc = false;
                LatLng ll = new LatLng(bdLocation.getLatitude(),
                        bdLocation.getLongitude());
                MapStatus.Builder builder = new MapStatus.Builder();
                builder.target(ll).zoom(18.0f);
                mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            }
            LatLng point = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
            OverlayOptions dotOption = new DotOptions().center(point).color(0xAAA9A9A9);
            mBaiduMap.addOverlay(dotOption);

            currentLat = point.latitude;
            currentLng = point.longitude;

            if (isUploadingPosition) {
                uploadPosition(bdLocation);
            }
        }
    }

大致的代码基本是这些,具体的可以参照官方的demo。

再说下后台运行,需要手机端开放自启动和关闭电源优化。省电策略那里设置到无限制。以小米手机为例:

手机端实时定位

 

本文地址:https://blog.csdn.net/koala6403/article/details/107935763