android 前后台保活 实现定位数据定时上传并展示轨迹 (下)

2023-11-11

上一篇地址: https://blog.csdn.net/qq_40803752/article/details/86304508

上2篇写完了,保活。这一篇写进入业务逻辑。

大概5分钟定一次位置,上传到服务器。并且展示。

定位的话,我这里使用的百度定位,说下一我写的时候一个逻辑错误,就是每次只定一次位置,担心百度定位那个持续定位

不能用,后面测试发现没有这个问题。gps定位基本一样的。 也是通过 保活维护着定位监听。下面放代码,

 

//定位 

public class DownloadService extends Service {
    boolean sign=false;
    public Context mContext=this;
    LocationClient mLocationClient;
    public static final int NOTICE_ID = 100;
    private MediaPlayer mMediaPlayer;
    private DownloadBinder mDownloadBinder;
    private Timer mRunTimer;
    private int mTimeSec;
    private int mTimeMin;
    private int mTimeHour;
    private OnTimeChangeListener mOnTimeChangeListener;

    @Override
    public void onCreate() {
        super.onCreate();
        mContext=this;

        mDownloadBinder = new DownloadBinder();
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        //后台播放无声 音乐
        mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.no_notice);
        mMediaPlayer.setLooping(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // 6.0 以上 jobservice
            useJobServiceForKeepAlive();
        }

        // 通知栏
        showNotification();

    }
    /**
     * 使用JobScheduler进行保活
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void useJobServiceForKeepAlive() {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        if (jobScheduler == null) {
            return;
        }
        jobScheduler.cancelAll();
        JobInfo.Builder builder = new JobInfo.Builder(1024, new ComponentName(getPackageName(), ScheduleService.class.getName()));
        //周期设置为了2s
        builder.setPeriodic(1000 * 10);
        builder.setPersisted(true);
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        int schedule = jobScheduler.schedule(builder.build());
        if (schedule <= 0) {

        }

    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("TAG","onStartCommand");
        mContext=this;
        new Thread(new Runnable() {
            @Override
            public void run() {
                startPlayMusic();
            }
        }).start();
        startRunTimer();
        return START_STICKY;
    }
    private void startPlayMusic() {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
        }
    }

    private void stopPlayMusic() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return mDownloadBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("TAG","onUnbind");
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        NotificationManager mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (mManager == null) {
            return;
        }
        mManager.cancel(NOTICE_ID);
        stopRunTimer();
        stopPlayMusic();
        // 重启自己

        if (sign){
            Intent intent = new Intent(getApplicationContext(), PlayerMusicService.class);
            startService(intent);
        }

    }


    private void startRunTimer() {

        if (mLocationClient == null) {
            initLocation(mContext);
        }

    }

    public boolean isNetworkConnected() {
        ConnectivityManager mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
        if (mNetworkInfo != null) {
            return mNetworkInfo.isAvailable();
        }
        return false;
    }

    private void saveLocation(Context mContext,String latitude, String longitude) {
        OffPointBean bean  =new OffPointBean();
        bean.setLatitude(latitude);
        bean.setLongitude(longitude);
        String s="yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
        String format = simpleDateFormat.format(new Date());
        bean.setTimestamp(format);
        //
        MyUtils.conserveOfflineGPSinfo(mContext, bean);

    }
    private void initLocation(Context mContext) {
        //定位客户端的设置
        mLocationClient = new LocationClient(mContext);
        //   mLocationListener = new MyLocationListener();
        //注册监听
        mLocationClient.registerLocationListener(BDAblistener);
        //配置定位
        LocationClientOption option = new LocationClientOption();
        option.setCoorType("GCJ02");//坐标类型
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        option.setOpenGps(true);//打开Gps
        option.setScanSpan(300000);//0代表只定位1次
        option.setIsNeedLocationPoiList(true);//可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
        mLocationClient.setLocOption(option);
        mLocationClient.start();
    }
    private BDAbstractLocationListener BDAblistener = new BDAbstractLocationListener() {
        @Override
        public void onReceiveLocation(BDLocation location) {
         
           final String latitude = location.getLatitude() + "";
            final String longitude = location.getLongitude() + "";
            mTimeSec++;
            if (mOnTimeChangeListener != null) {
                mOnTimeChangeListener.showTime(mTimeSec+"");
            }


//因为百度定位,会出现错误定位信息,所以对数据判断下
            if (!String.valueOf(latitude).contains(".") ||String.valueOf(latitude).contains("E")){
                //   infalistener.getOnetimeLocation(null,GPSUtils.GCJ02);
                //再定位一次
              //  LocationInfoSave.initLocation(mContext,infalistener);

              //  mLocationClient.restart();
                int locType = location.getLocType();

                Log.e("TAG",locType+"");


            }   else {

                //这里判断是否有网络

                boolean networkConnected = isNetworkConnected();

                //保存时候  转84
                double lation = location.getLatitude();
                double longitude1 = location.getLongitude();
                if (networkConnected) {
                    DataControl.addPoint(latitude, longitude, new DataResponse() {
                        @Override
                        public void onSucc(Object response) {

                        }

                        @Override
                        public void onFail(String error) {

                            //失败保存在本地服务器
                            saveLocation(mContext,latitude, longitude);
                        }
                    });
                }else {

                    saveLocation(mContext,latitude, longitude);
                }

            }

        }
    };

    private void stopRunTimer() {
        if (mRunTimer != null) {
            mRunTimer.cancel();
            mRunTimer = null;
        }
        mTimeSec = 0;
        mTimeMin = 0;
        mTimeHour = 0;
        Log.e("TAG","时间为:" + mTimeHour + " : " + mTimeMin + " : " + mTimeSec);
    }

    public interface OnTimeChangeListener {
        void showTime(String time);
    }

    public class DownloadBinder extends Binder {
        public void setOnTimeChangeListener(OnTimeChangeListener onTimeChangeListener) {
            mOnTimeChangeListener = onTimeChangeListener;
        }
        public void setStopStatus(boolean status) {
            sign = status;
        }

    }

    /**
     * 启动前台通知
     */
    private void showNotification() {
        String string = mContext.getResources().getString(R.string.app_name_);
        //创建通知详细信息
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.logo)
                .setContentTitle(string)
                .setContentText("系统后台服务");
      //  Intent intent = new Intent(this, MainProgramActivity.class);
        //创建任务栈Builder
        //获取通知服务
        NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        //获取PendingIntent
        Intent mainIntent = new Intent(this, MainProgramActivity.class);
        PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder .setContentIntent(mainPendingIntent);
        
        //构建通知
        Notification notification = builder.build();
        notification.flags |= Notification.FLAG_NO_CLEAR;
        //显示通知
        nm.notify(NOTICE_ID, notification);
        //启动为前台服务
        startForeground(NOTICE_ID, notification);
    }


}

 

 

启动代码就不发了,下面发展示代码。比较简单

xmL:

<com.baidu.mapapi.map.MapView
    android:layout_weight="1"
    android:id="@+id/bmapView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:clickable="true"/>
public class MapActivity extends BaseActivity {

    BaiduMap mBaiduMap;
    @BindView(R.id.bmapView)MapView mMapView;
//    @tv_share

    private boolean isend=true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        ButterKnife.bind(this);
        initView();
        super.setTitle("地图");


    }
/*
联网请求 数据
*/
    private void initData() {
        Intent intent = getIntent();
        String time="";
        String userId = MyUtils.getUserId(mContext);
        if (intent!=null){
            time= intent.getStringExtra("time");
        }
        if (TextUtils.isEmpty(time)) {

            String s="yyyy-MM-dd";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(s);
            time = simpleDateFormat.format(new Date());
            isend=false;
        }

        DataControl.getPoints(userId, time, new DataResponse() {
            @Override
            public void onSucc(Object response) {
                if (response!=null){
                    final GuijiBean data = (GuijiBean) response;
//展示数据
                    setMapDataView(data);

            }

            @Override
            public void onFail(String error) {
                      Tools.toast(mContext,"数据异常: "+error);
            }
        });
    }


    public void changeData(GuijiBean data){

        List<GuijiBean.PointsBean> points = data.getPoints();
        List<GuijiBean.ReportsBean> reports = data.getReports();
        //setMapDataView(data);

        if (points!=null){
            for (int i=0;i<points.size();i++){
                GuijiBean.PointsBean pointsBean = points.get(i);
                String latitude = pointsBean.getLatitude();
                String longitude = pointsBean.getLongitude();
                double lat = Double.parseDouble(latitude);
                double lon = Double.parseDouble(longitude);
                double[] doubles = GPSChangeUtil.gps84_To_Gcj02(lat,lon);
                double    latitudechange =  doubles[0];
                double    longitudechange =doubles[1];
                pointsBean.setLatitude(latitudechange+"");
                pointsBean.setLongitude(longitudechange+"");
            }
        }

        if (reports!=null){
            for (int i=0;i<reports.size();i++){
                GuijiBean.ReportsBean reportsBean = reports.get(i);
                String latitude = reportsBean.getLat();
                String longitude = reportsBean.getLon();
                double lat = Double.parseDouble(latitude);
                double lon = Double.parseDouble(longitude);
                double[] doubles = GPSChangeUtil.gps84_To_Gcj02(lat,lon);
                double    latitudechange =  doubles[0];
                double    longitudechange =doubles[1];
                reportsBean.setLat(latitudechange+"");
                reportsBean.setLon(longitudechange+"");
            }
        }

    }
    LatLng mdata;
    private void initView() {

        //

        // 不显示百度地图Logo
        mMapView.removeViewAt(1);

        //百度地图
        mBaiduMap = mMapView.getMap();

        //设置缩放比例
        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(new MapStatus.Builder().zoom(18).build()));

        //默认卫星图
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
    }
    @Override
    public void onStart() {
        super.onStart();
        //开启定位

        Intent intent = getIntent();
      //  Serializable data = intent.getSerializableExtra("data");
        LatLng data1 = intent.getParcelableExtra("data");
        if (data1!=null){
            mdata=   data1;
            //展示坐标数据  84转gcj
            double[] doubles = GPSChangeUtil.gps84_To_Gcj02(data1.latitude, data1.longitude);
            double    latitudechange =  doubles[0];
            double    longitudechange =doubles[1];
            data1=new LatLng(latitudechange,longitudechange);
            setMarkerOptionsaaa(data1,R.mipmap.updata);

        }   else {
            initData();
        }

    }

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

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

               /*
               绘制轨迹
                */
    public void  setMapDataView(GuijiBean data){
        List<GuijiBean.PointsBean> pointslist = data.getPoints();
        List<GuijiBean.ReportsBean> reports = data.getReports();
        if (pointslist==null &&  reports==null){
            Tools.toast(mContext,"当前没有数据!!!");
            return;
        }

        // 构造折线点坐标
        List<LatLng> pointszhe = new ArrayList<LatLng>();
        for (int i=0; i<pointslist.size();i++){
            //
            GuijiBean.PointsBean pointsBean = pointslist.get(i);
            LatLng lng = new LatLng(Double.parseDouble(pointsBean.getLatitude()),Double.parseDouble(pointsBean.getLongitude()));
            pointszhe.add(lng);
            if (i>1 &&i==pointslist.size()-1){
                pointszhe.add(lng);
            }
            if (i==0){
                setPositionCenter(lng);
            }
        }
        //构建分段颜色索引数组
        if (pointszhe.size()>1){

            OverlayOptions ooPolyline = new PolylineOptions().width(10)
                    .color(Color.RED).points(pointszhe);
            //添加在地图中
            Polyline mPolyline = (Polyline) mBaiduMap.addOverlay(ooPolyline);
        }

    }
    /**
     * 设置中心点
     */
    public void setPositionCenter(LatLng latLng) {
      //  LatLng mLatLng= new LatLng(latitude,longitude);
        MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(latLng);

        mBaiduMap.animateMapStatus(status);//动画的方式到中间
    }

    private void setMarkerOptionsaaa(LatLng ll, int icon) {
        if (ll == null) return;

        //设置为起点
        MapStatusUpdate status = MapStatusUpdateFactory.newLatLng(ll);
        mBaiduMap.animateMapStatus(status);//动画的方式到中间
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(icon);
        MarkerOptions ooD = new MarkerOptions().position(ll).icon(bitmap);
        mBaiduMap.addOverlay(ooD);
    }
}

 

 

Gps,实现后面单独写一篇。包括声音地图,高仿户外app。 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android 前后台保活 实现定位数据定时上传并展示轨迹 (下) 的相关文章

  • 关于$'\r': command not found错误的一点体会

    今天运行一个其他组开发的jar包 这个jar包由于运行参数是通过命令行的方式输入的 所以需要运行一个shell脚本来启动 启动脚本类似这样 bin bash jdbc driverClassName com mysql jdbc Drive
  • 力扣-->#剑指Offer 897 . 递增顺序搜索树(E)

    class Solution TreeNode curr public TreeNode increasingBST TreeNode root TreeNode first new TreeNode 1 用first 来记录curr的初始
  • 途客圈创业记--读书笔记

    一 初创公司股权结构 2011年6月公司创立 自筹启动资金50万 1 陈天和Alex 每人出资25万元 总计50万元 作为启动资金 2 陈天 CTO兼董事长 股份60 因为是想法的发起人 且在实现这个想法的过程中 Alex CEO 股份40
  • 【C++学习第三讲】C++语句

    目录 C 语句 一 引入 二 声明语句和变量 1 为什么变量必须声明 三 赋值语句 四 cout新花样 五 cout和printf 六 其他C 语句 1 使用cin 2 使用cout进行拼接 七 类简介 一 引入 C 程序是一组函数 而每个
  • Qt::FramelessWindowHint无边框化,移动,大小调整

    QT工作笔记壹 导读 开发环境 QT界面无边框 方法1 方法2 引用 导读 最近工作一个项目需要用QT设计一个UI 看了一下目前主流商业化UI 例如扣扣 微信 网易云音乐 结合个人审美 本人非美术专业 但游戏经验丰富 对人机交互界面有个人看
  • 为什么有了uwsgi 还要 nginx 服务器

    相信每一个使用nginx uwsgi django部署过的人 都感到非常复杂 到底为什么一个项目的发布要经过这么多层级 他们每一层有什么理由存在 这就带大家宏观地看待一下 首先nginx 是对外的服务接口 外部浏览器通过url访问nginx
  • MyBatis 的执行流程

    前言 MyBatis可能很多人都一直在用 但是MyBatis的SQL执行流程可能并不是所有人都清楚了 那么既然进来了 通读本文你将收获如下 1 Mapper接口和映射文件是如何进行绑定的 2 MyBatis中SQL语句的执行流程 3 自定义
  • Js Vue 获取当月第一天、最后一天、当天

    new Date 效果 2023 06 12 注 本文示例以获取当天为例 一 new Date 在vue中使用new Date 获取当月第一天 最后一天 当天 二 使用步骤 1 定义方法 代码如下 示例 param type 0 第一天 1
  • 如何在Gephi中可视化多层网络

    要借助一个插件实现 Isometric Layout 感谢插件作者对gephi社群提供的贡献 作者网页的图片 下载 url https gephi org plugins plugin isometric layout 点击这儿下载再在Ge
  • centos8.5.111安装mysql8.0

    修改网络源 Connecting to 192 168 182 154 22 Connection established To escape to local shell press Ctrl Alt Activate the web c
  • 关于CSS3:justify-self,justify-items和justify-content之间的区别

    这篇文章应该能帮到你 https www codenong com 48535585 总结 flex布局 这三个属性中 只能用justify content属性 1 justify content 2 justify items 3 jus
  • LeetCode: 高频树结构题目总结 - Python

    LeetCode 高频树结构题目总结 问题描述 LeetCode 98 验证二叉搜索树 根据中序遍历 判断大小 LeetCode 99 恢复二叉搜索树 搜索二叉树有两个节点搞错了 恢复好 LeetCode 100 相同的树 LeetCode
  • MyCobot六轴机械臂(六)--Myblockly模块简介

    1 Logic模块 如图3 11所示 表示if 条件 do 程序1 else 程序2 若满足条件则执行程 序1 否则执行程序2 所表示方法的详细讲解可查看图1 2下方的文字讲解 所表示的逻辑判断 返回值为true或者false 可以点击 中

随机推荐

  • spring源码研究之IoC容器在web容器中初始化过程

    前段时间在公司做了一个项目 项目用了spring框架实现 WEB容器是Tomct 5 虽然说把项目做完了 但是一直对spring的IoC容器在web容器如何启动和起作用的并不清楚 所以就抽时间看一下spring的源代码 借此了解它的原理 我
  • 经典SQL题目-求第N高的薪水的解法汇总及知识点复习

    这几天在看Leetcode的时候逐步开始留意SQL题目 不做不知道 一做才感觉自己的SQL太弱了 因此将一道经典题目 求第N高的薪水的解法进行汇总 MySQL 相关解法的原文链接已标注在文末 题目的链接为 第N高的薪水 一 题干 第N高的薪
  • [云原生专题-45]:Kubesphere云治理-基于Kubernetes 构建的企业级容器平台简介与总体架构

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122905834 目录 前言 第1章
  • pip换源+更改默认安装位置

    本文档创建于2023年3月9日 本文记录了pip换源和更改默认安装位置的操作 主要用于pip的一些配置 方便下载和文件管理 pip换源 使用pip安装库时 如果用默认的库经常会遇到连接不上或下载慢的问题 更换为国内的库下载会更快 临时换源
  • 使用TCP方式拉取Canal数据

    1 Canal对接Kafka联调 1 1 配置修改 canal properties 修改 zk canal zkServers 10 51 50 219 2181 instance properties 开启配置项 canal mq dy
  • 1056 组合数的和

    给定 N 个非 0 的个位数字 用其中任意 2 个数字都可以组合成 1 个 2 位的数字 要求所有可能组合出来的 2 位数字的和 例如给定 2 5 8 则可以组合出 25 28 52 58 82 85 它们的和为330 输入格式 输入在一行
  • Springboot3 + SpringSecurity + JWT + OpenApi3 实现认证授权

    Springboot3 SpringSecurity JWT OpenApi3 实现双token 目前全网最新的 Spring Security JWT 实现双 Token 的案例 收藏就对了 欢迎各位看友学习参考 此项目由作者个人创作 可
  • 即使失业,也要把第二个一万小时坚持下去

    这个月打的我有点懵逼 不知所措了 所以 在此写贴 即使失业 也要把第二个一万小时坚持下去 每天8小时学习 反正已经非工资收入九千了 基本上可以活下去了
  • Karma 自动化测试框架搭建文档

    一 前言 此文档为前端自动化单元测试框架 Karma 的搭建以及使用文档 二 准备环境 先列出我们此次搭建测试框架 Karma 必须的环境和包 1 node js node 引擎 2 npm node 包管理器 3 cnpm 可选 淘宝镜像
  • 数列分段(贪心入门)

    问题 对于给定的一个长度为 n 的正整数数列 ai 现要将其分成连续的若干段 并且每段和不超过 m 可以等于 m 问最少能将其分成多少段使得满足要求 算法复杂度为O n 思路 对于已给出数列 从前往后扫描一遍 在扫描过程中 不断记录当前最大
  • win10maven环境变量配置(简洁版):

    准备工作 下载了maven 可以官网下载 也可以通过其他途径获取 没安装之前 在命令行输入mvn v是这样的 解决方案 1 此电脑 属性 高级 环境变量 系统变量 2 新建变量 变量名 MAVEN HOME 值 本地maven的文件夹路径
  • 如何在Geany中添加python的中文注释

    在Geany中编译Python中直接添加中文注释会出现如下错误 只需要在程序的开始位置添加一句 coding utf 8
  • 全网最全Python兼职接单方式,赶快收藏!

    前言 近年来 Python凭借其简洁易入门的特点受到越来越多人群的青睐 当然这不仅仅是针对程序员来说 对于一些学生 职场人士也是如此 Python为什么会大受欢迎 1 Python还被大家称为 胶水语言 它适用于网站 桌面应用开发 自动化脚
  • Unity_DoTween_Path路径动画的使用

    using System Collections using System Collections Generic using System Linq using DG Tweening using UnityEngine public c
  • ResNet学习笔记

    目录 1 背景 2 BN Batch Normalization 层 3 residual结构 残差结构 1 背景 在 ResNet 之前 所有的神经网络都是通过卷积层和池化层的叠加组成的 人们认为卷积层和池化层的层数越多 获取到的图片特征
  • oracle 启动时出现ORA-01157: cannot identify/lock data和ORA-01110: data file 错误

    SQL gt shutdown ORA 01109 database not open Database dismounted ORACLE instance shut down SQL gt startup ORACLE instance
  • 微隔离(MSG)

    微隔离 MSG 参考文章 用 微隔离 实现零信任 什么是微隔离 当下哪家微隔离最靠谱 参考视频 不仅是防火墙 用微隔离实现零信任 定义 微隔离 Micro Segmentation 微隔离是一种网络安全技术 其核心的能力要求是聚焦在东西向流
  • NER标注----使用BILSTM模型训练招投标实体标注模型

    NER标注 BILSTM模型训练招投标实体标注模型 TOC NER标注 BILSTM模型训练招投标实体标注模型 前言 一 NER标注简介 二 从头开始训练一个NER标注器 二 使用步骤 1 引入库 2 数据处理 3 模型训练 前言 上文中讲
  • Python3 迭代器与生成器

    迭代器 迭代是Python最强大的功能之一 是访问集合元素的一种方式 迭代器是一个可以记住遍历的位置的对象 迭代器对象从集合的第一个元素开始访问 直到所有的元素被访问完结束 迭代器只能往前不会后退 迭代器有两个基本的方法 iter 和 ne
  • android 前后台保活 实现定位数据定时上传并展示轨迹 (下)

    上一篇地址 https blog csdn net qq 40803752 article details 86304508 上2篇写完了 保活 这一篇写进入业务逻辑 大概5分钟定一次位置 上传到服务器 并且展示 定位的话 我这里使用的百度