H5+App后台持续定位功能实现

1. 项目需求

最近有个需求就是需要完成在后台的实时定位,并且要将获取到的定位信息写到Map控件上去。也就是说,即使手机锁屏了或者手机退出到菜单页面也要保证定位能正常运行并且将数据绘制到地图控件中。

2. 实现过程

找了网上很多的实现,各种样的都有。这里稍微列举一下,毕竟都是都是方法,也从中找到了一些实现的思路。其实个人认为主要还是为了保活JS,让JS代码生效,即可完成我们的操作。

1.监听后台事件,让其呈现出不退出的状态。
代码如下

				let mainq = plus.android.runtimeMainActivity();
//为了防止快速点按返回键导致程序退出重写quit方法改为隐藏至后台  
			        plus.runtime.quit = function(){  
			            mainq.moveTaskToBack(false);  
			        };  
//重写toast方法如果内容为 ‘再按一次退出应用’ 就隐藏应用,其他正常toast  
			        plus.nativeUI.toast = (function(str){  
			            if(str == '再按一次退出应用'){  
			                mainq.moveTaskToBack(false);  
			                return false;  
			            }else{  
			                console.log('不处理')  
			            }  
					});

这种方法可以保证用户在按返回键时不会退出应用,而是保持后台状态。但是过一会或者是点击其他应用,然后在进入目标应用的时候,应用显示启动页面,重新开启

2.使用maps的watchlocationpoint()函数进行定位监听。这里就不附上代码了,我自己在尝试后这个方法后台也是会被杀掉,所以也淘汰。

3.使用NJS拉起一个通知栏来保活。这个方法看起来也行(后面的方法也是基于这个思路的),但是我小米8SE 直接复制过来的NJS代码,通知栏空空如也,对我来说这个方法行不通,也看了网上的类似代码,进行了简单修改,但还是无济于事。所以我个人淘汰了这个方法,大家有兴趣可以去官方社区看看。

4.使用原生安卓拉起来保活,这部走了很多弯路。也稍微了解了一下Activity生命周期,服务启动,布局一些乱七八糟的啥的。这里会碰到的问题可能就是:安卓应用后台运行没问题,但是JS还是死掉了(用了websocket和定时器进行测试做出的判断,可能存在测试方式的巧合,不确定性等等)。

附上之前做的小记录。
在这里插入图片描述

3.最终实现

最终是使用了原生安卓调用高德后台持续定位,并开启通知栏服务进行挂活。然后,在监听到定位信息的回调函数中使用webview.loadUrl()调用要执行的JS代码进行保活,在JS的test123()方法中进行maps的描点划线操作。这里我在测试的时候加了网络请求到我的阿里云服务器,在服务器上打印时间来检测JS是否被调用,是否存活。

参考了这位老哥代码博客:
https://blog.csdn.net/qq_22718203/article/details/86571635

附上简单代码:

/**
     * 定位监听
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation location) {
        //这里是单例模式获取webview页面,如果获取多次页面会不断刷新,数据丢失。
            WebView webView = GetMapInfoToWeb.getInstance();
            //调用js的test123()方法
            webView.loadUrl("javascript:test123()");
            System.out.println("======================webview"+webView);
            if (null != location) {
                StringBuffer sb = new StringBuffer();
                //errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
                if (location.getErrorCode() == 0) {
                    double lat = location.getLatitude();
                    double lon = location.getLongitude();
                } else {
                    //定位失败
                    sb.append("定位失败" + "\n");
                    sb.append("错误码:" + location.getErrorCode() + "\n");
                    sb.append("错误信息:" + location.getErrorInfo() + "\n");
                    sb.append("错误描述:" + location.getLocationDetail() + "\n");
                    System.out.println(sb.toString());
                }
            } else {
            }
        }
    };

PS:webview这里也碰到了一些小坑,之前调试的时候已经可以实现安卓直接调用JS代码。但是页面一直刷新,其实是获取当前激活页面的问题。后面使用了单例模式去解决他(可以根据需求来启动再获取对应的页面存入单例即可,或者对单例进行简单修改)。代码也附上(使用双重检查即可):

/*
单例模式获取webview页面,避免获取多次导致页面刷新。
 原功能:获取webview页面,调用JS方法
 */
public class  GetMapInfoToWeb  {
    public static volatile WebView Webview;
    public static WebView getInstance(){
        if(Webview == null){
            synchronized (GetMapInfoToWeb.class){
                if(Webview == null){
                    IApp iApp = SDK.obtainCurrentApp();
                    // 这里获取要调用方法的页面,目前vue打包还有一些问题
                    IWebview iWebview = SDK.obatinFirstPage(iApp);
                    Webview = iWebview.obtainWebview();
                }
            }
        }
        return Webview;
    }
}

4. 关于测试用例

这里的测试我通过:
1.JS原生定时器计数显示到页面上
2.webview.loadUrl()调用JS方法执行网络请求,查看阿里服务器的日志时间;
3.打印出地图点的个数到页面中。(webview.loadUrl()调用一次方法就执行一次创建新点)

/* 绘制路线 */
		function drawMap(x,y){
			if(map == null){
				return;
			}
			/* 定位到当前位置 */
			map.centerAndZoom( new plus.maps.Point(y,x),18);
			let nowPoint = new plus.maps.Point(y,x);
			/* 添加到划线数组中 */
			changedPosition.push(nowPoint);
			document.getElementById('point').innerHTML = changedPosition.length;
			let nowMaker = new plus.maps.Marker(nowPoint);
			nowMaker.setLabel("到此一游");
			map.addOverlay(nowMaker);
			/* 新建一条线 */
			var changemap  = new plus.maps.Polyline( changedPosition );
			map.addOverlay(changemap );
			/* 发送网络请求 */
			doSend("test");
		}

/* 发送网络连接判断JS是否存活 */
		function doSend(info){
			var xhr = new plus.net.XMLHttpRequest();
			xhr.onreadystatechange = function () {
				switch ( xhr.readyState ) {
					case 0:
						console.log( "xhr请求已初始化" );
					break;
					case 1:
						console.log( "xhr请求已打开" );
					break;
					case 2:
						console.log( "xhr请求已发送" );
					break;
					case 3:
						console.log( "xhr请求已响应");
						break;
					case 4:
						if ( xhr.status == 200 ) {
							console.log( "xhr请求成功:"+xhr.responseText );
						} else {
							console.log( "xhr请求失败:"+xhr.readyState );
						}
						break;
					default :
						break;
				}
			}
			xhr.open( "GET", "阿里云服务器"+info );
			xhr.send();
		}

4.测试记录:
在这里插入图片描述

github地址:https://github.com/2017LLLLL/h5plusMaps/tree/master

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
微信社区小程序是基于微信平台的一个应用程序,它提供了与朋友圈、群聊、推送通知等社交功能相结合的多功能app。它具有简单易用、交互性好、功能强大等特点,已经成为了越来越多人的生活必备工具。 在搭建微信社区小程序的过程中,需要编写前端代码和后端代码。前端代码主要用于展示页面和用户交互,而后端代码则负责处理数据的传输和存储。为了更好地帮助大家理解和学习搭建微信社区小程序的过程,我们附带了完整的视频教程。 这个视频教程囊括了整个搭建过程的所有细节,包括项目准备、环境搭建、前端页面设计、后端逻辑开发等内容。通过观看视频,你可以了解到如何使用微信开发者工具进行项目创建和代码编写,如何设计小程序的页面UI和交互逻辑,以及如何实现后台服务器的数据交互和存储。 视频教程的目的是帮助大家更好地理解和掌握微信社区小程序的搭建过程,同时也提供了一种更直观和生动的学习方式。通过观看这个视频,你可以跟着实际操作一步步搭建一个完整的微信社区小程序,掌握相关的技术和技巧。 总之,通过这个视频教程,你可以轻松地学习并掌握微信社区小程序的搭建技术,从而为你的个人或者商业项目构建一个功能完备且用户友好的微信小程序。希望这个视频教程能够帮助到你!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值