Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注

2023-11-07

技术背景

我们在做GB28181设备接入端的时候,其中有个功能,不难但非常重要:那就是GB28181实时位置的订阅(mobileposition subscribe)和上报(notify)。

特别是执法记录仪、智能安全帽、车载终端等场景下,现场人员的实时位置是国标平台侧非常关注的。国标平台侧通过周期性的获取GB28181设备接入端的经纬度信息,并在电子地图显示,需要看现场的情况,点开图标,进行音视频回传和语音广播语音对讲等操作,现场人员的总体概况一目了然。

规范解读

其他不表,我们先看看GB/T28181-2016规范中,关于订阅通知流程:

基本流程和注解如下:

  1. 国标服务平台向Android平台GB28181设备接入终端发送SUBSCRIBE消息体,并携带Expire头域指定订阅过期时间;
  2. Android平台GB28181设备接入终端收到SUBSCRIBE后,200 OK响应;
  3. Android平台GB28181设备接入终端发送 NOTIFY 消息相关的位置信息,并使用Event头域描述订阅事件,国标GB28181的移动设备位置订阅这个值是"presence"
  4. 国标服务平台收到 Android平台GB28181设备接入终端NOTIFY消息后,200 OK响应;
  5. NOTIFY...200 OK...NOTIFY...200 OK...etc..
  6. 国标服务平台在订阅过期之前,向Android国标接入终端发送刷新订阅 SUBSCRIBE 消息,消息头域中使用 Event头域描述订阅事件,消息体中携带订阅的详细参数,使用 Expire头域指定订阅过期时间;
  7. Android平台GB28181设备接入终端收到订阅消息后,向国标服务平台发送200 OK响应;
  8. NOTIFY...200 OK...NOTIFY...200 OK........
  9. 如国标服务平台需要取消订阅,可以向Android平台GB28181设备接入终端发送取消订阅SUBSCRIBE消息,消息头域中使用Event头域描述订阅事件,消息体中携带订阅的详细参数,Expire头域值为0;
  10. Android国标接入终端收到订阅消息后,向国标服务平台发送200 OK响应,取消向国标服务平台发送实时位置通知消息,取消订阅成功的话,也会发一个最终的NOTIFY给国标服务端;
  11. 这里需要注意的是:Android平台GB28181设备接入终端收到SUBSCRIBE请求后,会检查SUBSCRIBE请求中"Expires"值的大小,当且仅当这个值大于0且小于1小时,并且小于Notifier配置的最小值时,Notifier可能会返回一个"423 Interval too  small"错误,并包含一个""Min-Expires" 头域;
  12. Android国标接入端发送的NOTIFY请求超时的话,应该移除这个订阅;
  13. NOTIFY request必须包含"Subscription-State"头,有三个可选的值:"active", "pending", "terminated". 当值是"active"或"pending"时,应该也包含一个”expires“参数,显示订阅剩余时间。

GB/T28181-2016针对MobilePosition描述

<elementname="TargetID"type="tg:deviceIDType"/>移动设备位置数据通知
<! -- 命令类型:移动设备位置数据通知(必选)-->
<elementname="CmdType"fixed="MobilePosition"/>
<! -- 命令序列号(必选)-->
<elementname="SN" type="integer"minInclusivevalue= "1"/>
<! -- 产生通知时间(必选)--> 
<elementname="Time" type="dateTime"/> 
<! --经度(必选)--> <elementname="Longitude"type="double"/> 
<! -- 纬度(必选)--> <elementname="Latitude"type="double"/> 
<! --速度,单位:km/h(可选)--> 
<elementname="Speed"type="double"/> 
<!--方向,取值为当前摄像头方向与正北方的顺时针夹角,取值范围0°~360°,单位:(°)(可选)-->
<elementname="Direction"type="double"/>
<! --海拔高度,单位:m(可选)-->
<elementname="Altitude"type="tg:deviceIDType"/>

技术实现

Android平台GB28181设备接入端,启动GB28181后,调用InitGB28181Agent()的时候,添加设备:

 相关代码如下:

   /*
    * Camera2Activity.java
    * Author: daniusdk.com
    */ 
   private boolean initGB28181Agent() {
        if ( gb28181_agent_ != null )
            return  true;

        getLocation(context_);

        String local_ip_addr = IPAddrUtils.getIpAddress(context_);
        Log.i(TAG, "initGB28181Agent local ip addr: " + local_ip_addr);

        if ( local_ip_addr == null || local_ip_addr.isEmpty() ) {
            Log.e(TAG, "initGB28181Agent local ip is empty");
            return  false;
        }

        gb28181_agent_ = GBSIPAgentFactory.getInstance().create();
        if ( gb28181_agent_ == null ) {
            Log.e(TAG, "initGB28181Agent create agent failed");
            return false;
        }

        gb28181_agent_.addListener(this);
        gb28181_agent_.addPlayListener(this);
		
        gb28181_agent_.addTalkListener(this);
        gb28181_agent_.addAudioBroadcastListener(this);
        gb28181_agent_.addDeviceControlListener(this);
        gb28181_agent_.addQueryCommandListener(this);

        // 必填信息
        gb28181_agent_.setLocalAddress(local_ip_addr);
        gb28181_agent_.setServerParameter(gb28181_sip_server_addr_, gb28181_sip_server_port_, gb28181_sip_server_id_, gb28181_sip_domain_);
        gb28181_agent_.setUserInfo(gb28181_sip_username_, gb28181_sip_password_);

        // 可选参数
        gb28181_agent_.setUserAgent(gb28181_sip_user_agent_filed_);
        gb28181_agent_.setTransportProtocol(gb28181_sip_trans_protocol_==0?"UDP":"TCP");

        // GB28181配置
        gb28181_agent_.config(gb28181_reg_expired_, gb28181_heartbeat_interval_, gb28181_heartbeat_count_);

        com.gb.ntsignalling.Device gb_device = new com.gb.ntsignalling.Device("34020000001310000001", "安卓测试设备", Build.MANUFACTURER, Build.MODEL,
                    "宇宙","火星1","火星", true);

        if (mLongitude != null && mLatitude != null) {
            com.gb.ntsignalling.DevicePosition device_pos = new com.gb.ntsignalling.DevicePosition();

            device_pos.setTime(mLocationTime);
            device_pos.setLongitude(mLongitude);
            device_pos.setLatitude(mLatitude);
            gb_device.setPosition(device_pos);

            gb_device.setSupportMobilePosition(true); // 设置支持移动位置上报
        }

        gb28181_agent_.addDevice(gb_device);


        if (!gb28181_agent_.createSipStack()) {
            gb28181_agent_ = null;
            Log.e(TAG, "initGB28181Agent gb28181_agent_.createSipStack failed.");
            return  false;
        }

        boolean is_bind_local_port_ok = false;

        // 最多尝试5000个端口
        int try_end_port = gb28181_sip_local_port_base_ + 5000;
        try_end_port = try_end_port > 65536 ?65536: try_end_port;

        for (int i = gb28181_sip_local_port_base_; i < try_end_port; ++i) {
            if (gb28181_agent_.bindLocalPort(i)) {
                is_bind_local_port_ok = true;
                break;
            }
        }

        if (!is_bind_local_port_ok) {
            gb28181_agent_.releaseSipStack();
            gb28181_agent_ = null;
            Log.e(TAG, "initGB28181Agent gb28181_agent_.bindLocalPort failed.");
            return  false;
        }

        if (!gb28181_agent_.initialize()) {
            gb28181_agent_.unBindLocalPort();
            gb28181_agent_.releaseSipStack();
            gb28181_agent_ = null;
            Log.e(TAG, "initGB28181Agent gb28181_agent_.initialize failed.");
            return  false;
        }

        return true;
    }

Android平台GB28181设备接入端DevicePosition设计如下:

/*
 * DevicePosition.java
 * Author: daniusdk.com
 */
public class DevicePosition {
    private String mTime; // 产生位置信息的时间,格式如:2022-03-16T10:37:21, yyyy-MM-dd'T'HH:mm:ss
    private String mLongitude; // 经度
    private String mLatitude; //纬度
    private String mSpeed; // 速度,单位:km/h
    private String mDirection; // 方向,取值为当前摄像头方向与正北方的顺时针夹角,取值范围0°~360°,单位:(°)
    private String mAltitude; // 海拔高度,单位:m
 
    public String getTime() {
        return mTime;
    }
 
    public void setTime(String time) {
        this.mTime = time;
    }
 
    public String getLongitude() {
        return mLongitude;
    }
 
    public void setLongitude(double longitude) {
        this.mLongitude = String.valueOf(longitude);
    }
 
    public void setLongitude(String longitude) { this.mLongitude =longitude; }
 
    public String getLatitude() {
        return mLatitude;
    }
 
    public void setLatitude(double latitude) {
        this.mLatitude = String.valueOf(latitude);
    }
 
    public void setLatitude(String latitude) { this.mLatitude = latitude;}
 
    public String getSpeed() {
        return mSpeed;
    }
 
    public void setSpeed(double speed) {
        this.mSpeed = String.valueOf(speed);
    }
 
    public String getDirection() {
        return mDirection;
    }
 
    public void setDirection(double direction) {
        this.mDirection = String.valueOf(direction);
    }
 
    public String getAltitude() {
        return mAltitude;
    }
 
    public void setAltitude(double altitude) {
        this.mAltitude = String.valueOf(altitude);
    }
}

当有SUBSCRIBE request请求位置更新,上层处理如下:

    @Override
    public void ntsOnDevicePositionRequest(String deviceId, int interval) {
        handler_.postDelayed(new Runnable() {
            @Override
            public void run() {
                getLocation(context_);

                Log.v(TAG, "ntsOnDevicePositionRequest, deviceId:" + this.device_id_ + ", Longitude:" + mLongitude
                        + ", Latitude:" + mLatitude + ", Time:" + mLocationTime);


                if (mLongitude != null && mLatitude != null) {
                    com.gb.ntsignalling.DevicePosition device_pos = new com.gb.ntsignalling.DevicePosition();

                    device_pos.setTime(mLocationTime);
                    device_pos.setLongitude(mLongitude);
                    device_pos.setLatitude(mLatitude);

                    if (gb28181_agent_ != null ) {
                        gb28181_agent_.updateDevicePosition(device_id_, device_pos);
                    }
                }
            }

            private String device_id_;
            private int interval_;

            public Runnable set(String device_id, int interval) {
                this.device_id_ = device_id;
                this.interval_ = interval;
                return this;
            }

        }.set(deviceId, interval),0);
    }

总结

国标平台侧获取到Android平台GB28181设备接入端的实时位置信息后,可以非常方便的根据实时经纬度信息,把前端设备位置标注到地图服务上。Android平台获取实时经纬度并无难度,这里不再赘述。

 

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

Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注 的相关文章

  • NV21、NV12、YV12、RGB565、YUV等颜色编码格式区别和接口设计探讨

    NV21 NV12 YV12 RGB565 YUV扫盲 NV21 NV12 YV12 RGB565 YUV分别是不同的颜色编码格式 这些颜色编码格式各有特点 适用于不同的应用场景 选择合适的颜色编码格式取决于具体的需求和环境 NV21 NV
  • 如何开发一个音视频播放器(ffmpeg3.2+sdl2.0)

    如何开发一个音视频播放器 ffmpeg3 2 SDL2 0 前言 创建一个音视频播放器的步骤 一 播放音频 二 播放视频 三 音视频同步 源码分析 一 正式开始前的准备工作 二 配置音视频基本参数 获取文件基本信息 初始化音频参数 初始化视
  • Android平台GB28181接入端如何对接UVC摄像头?

    我们在对接Android平台GB28181接入的时候 有公司提出这样的需求 除了采集执法记录仪摄像头自带的数据外 还想通过执法记录仪采集外接UVC摄像头 实际上 这块对我们来说有点炒冷饭了 不算新的诉求 大牛直播SDK 在2016年对接RT
  • FFmpeg入门详解之92:Live555学习之(一)-------Live555的基本介绍

    Live555学习之 一 Live555的基本介绍 前一阵子 因为项目需要 研究了一下Live555开源框架 研究的不是很深入 基本上把Live555当做API用了一下 但是毕竟也是本人看的第一个开源框架 在此记录总结一下 Live555是
  • Android平台如何高效率实现GB28181对接?

    技术背景 GB28181协议是一种用于设备状态信息报送的协议 可以在不同设备之间进行通信和数据传输 在安卓系统上实现GB T 28181非常必要 GB28181协议实现分两部分 一部分是信令 另外一部分就是媒体数据的编码 信令主要包括SIP
  • RTSP和RTP、RTCP协议介绍

    一 RTSP 1 简介 RTSP Real Time Stream Protocol 协议是一个基于文本的多媒体播放控制协议 属于应用层 RTSP以客户端方式工作 对流媒体提供播放 暂停 后退 前进等操作 它主要用来控制具有实时特性的数据的
  • WebRTC建立会话流程分析

    WebRTC建立会话流程总结 了解如何运行PeerConnection Demo后 熟悉运行流程可以做为深入学习WebRTC的切入点 本节重点解释客户端双方建立会话时交互的主要信令 控制会话的文本协议 和与信令相关的 WebRTC API
  • librtmp ssl 1.0.0 到 ssl 1.1.1

    openssl 版本更新了 导致 librtmp 库不能使用 于是查查资料 Compiler errors dereferencing pointer to incomplete type DH aka struct dh st 根据上面的
  • 如何快速实现Android平台前端设备接入能力

    技术背景 SIP 会话初始化协议 是在 IP网络上进行多媒体通信的应用层控制协议 以几种RFC的形式提供 其中最重要的是包含核心协议规范的RFC3261 该协议用于创建 修改和终止与一个或多个参与者的会话 通过会话 我们了解了一组进行通信的
  • 海康、大华网络摄像机RTSP URL格式组成及参数配置

    经常有开发者咨询我们关于海康 大华网络摄像机RTSP url拼接规则和相关参数配置 虽然很简单 考虑到资料不全 写个博客记录下 1 海康摄像机 在IE浏览器输入网络摄像机的IP地址 输入配置的用户名 密码 登陆 视频 1 码率类型 主码流和
  • 国家开源软件资源库

    http yp oss org cn software show cat php cat id 5 基本信息 成熟度 Dimdim 2009 05 19 1 2 3 4 5 6 7
  • 6款真正好用的播放器推荐

    GOM player GOM player 是一款本身装有视频播放所需的解码 及占用系统资源少 并且能以最优秀的画质来观看多种格式影片的播放程序 可以支持播放大多数当前流行的视频格式 如 MP4 AVI WMV MKV MOV FLV 等
  • GB28181平台如何接入无人机实现智能巡检?

    大家都知道 无人机巡检系统 有效解决了传统巡查工作空间和时间局限问题 降低人力工作成本 有效替代人工巡检工作模式 智能巡检系统通过人工智能技术和机械智能技术完美结合 在工业等场景下 应用非常广泛 本文旨在讲如何实现无人机 如大疆无人机 数据
  • [轻量级RTSP服务]Linux

    背景 随着国产操作系统的推进 传统行业对Linux平台的呼声和需求越来越大 之前几年 我们发布了Linux平台运营商级的RTSP转RTMP推送模块 RTMP推送模块和RTSP RTMP播放模块 前段时间 有开发者问我们 是不是可以在Linu
  • Android平台GB28181设备接入端如何调节实时音量?

    我们在对接Android平台GB28181设备接入端的时候 有开发者提出这样的疑惑 如何调整设备接入端的实时音量 实际上 这块我们前几年在做RTMP直播推送模块的时候 已经发布了相关的接口 这里再回顾下 SmartPublisherJniV
  • GB/T28181-2022针对H.265、AAC的说明和技术实现

    GB T28181 2022规范说明 GB T28181 2022相对来GB T28181 2016针对H 265 AAC的更新如下 更改了 联网系统通信协议结构图 媒体流通道增加了 H 265 G 722 1 AAC 见 4 3 1 20
  • GB/T28181-2022图像抓拍规范解读及技术实现

    规范解读 GB28181 2022相对2016 增加了设备软件升级 图像抓拍信令流程和协议接口 我们先回顾下规范说明 图像抓拍基本要求 源设备向目标设备发送图像抓拍配置命令 携带传输路径 会话ID等信息 目标设备完成图像传输后 发送图像抓拍
  • Android平台GB28181设备接入模块相关博客概览

    Android平台GB28181设备接入模块 可实现不具备国标音视频能力的 Android终端 通过平台注册接入到现有的GB T28181 2016服务 可用于如智能监控 智慧零售 智慧教育 远程办公 生产运输 智慧交通 车载或执法记录仪等
  • GB/T28181-2022相对2016版“基于TCP协议的视音频媒体传输要求“规范解读和技术实现

    规范解读 GB T28181 2022和GB T28181 2016规范 有这么一条 更改了附录 D 基于 TCP 协议的视音频媒体传输要求 见附录 D 2016 年版的附录 L 本文主要是针对GB T28181 2022里面提到的 基于
  • RTP/RTCP/RTSP负载H264的一些问题小结

    以下内容都是基于rfc3984 RTP负载H264时的参数配置 1 在TCP传输时 Transport头中的interleaved参数必须设置 比如0 1 或者2 3 海康的流中出现了4 但是没有配置 所以wireshark也无法解析cha

随机推荐

  • 剑指 Offer 58 - II. 左旋转字符串(java+python)

    字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部 请定义一个函数实现字符串左旋转操作的功能 比如 输入字符串 abcdefg 和数字2 该函数将返回左旋转两位得到的结果 cdefgab 示例 1 输入 s abcdefg k
  • python-爬虫初识-自动登录(二)

    目录 一 BeautifulSoup模块详细介绍 二 自动登录github 一 BeautifulSoup模块详细介绍 BeautifulSoup是一个模块 该模块用于接收一个HTML或XML字符串 然后将其进行格式化 之后遍可以使用他提供
  • 自定义一个类加载器

    为什么要自定义类加载器 类加载机制 http www cnblogs com xrq730 p 4844915 html 类加载器 http www cnblogs com xrq730 p 4845144 html 这两篇文章已经详细讲解
  • HKPCA Show携手电巢直播开启“云”观展!掀起一场电子人的顶级狂欢!

    近日 国际电子电路 深圳 展览会 HKPCA Show 已于深圳国际会展中心圆满举办 本次展览划分七大主题专区 面积超50 000平方米 展位超2500个 汇聚众多行业知名 有影响力的参展商 引用现场观众的一句话讲 这种规模的电子展览会真是
  • 北欧--2022年Python爬虫心得

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 前言 网络爬虫也称为 蜘蛛 它可以在海量的互联网信息爬取需要的信息 简单地说它是模拟人类请求网站的行为 即自动请求网页 抓取数据 然后从中提取有价值的数据 具体步骤如下 首先
  • oracle主键约束删除,oracle删除主键查看主键约束及创建联合主键

    oracle删除主键查看主键约束及创建联合主键 1 主键的删除 ALTER TABLE TABLENAME DROP PRIMARY KEY 执行上面的SQL可以删除主键 如果不成功可以用 ALTER TABLE TABLENAME DRO
  • C/C++访问MySQL数据库

    C C 访问MySQL数据库 VS2019配置 打开mysql的安装目录 默认安装目录如下 C Program Files MySQL MySQL Server 8 0 确认 lib 目录和include 目录是否存在 打开VS2019 新
  • 如何将自己的项目jar包打包成docker 镜像

    首先将自己的项目打包成jar 并在自己本地先用java jar xxx jar启动下 看是否可以启动 随后将自己的jar包同级目录创建一个Dockerfile文件 并用notepad打开 文件无后缀 FROM kdvolder jdk8 V
  • linux下手动安装编译的通用步骤

    手动安装编译的通用步骤 在自己的下载目录中 1 在官网下载压缩包 wget xxx 2 解压文件 tar zxf xxx 3 开始编译安装 查看解压的目录下的文件 是config还是autogen之类的 来决定使用 autogen sh还是
  • 如何使用memset函数

    如何使用memset函数 memset用处 memset使用方法 memset用处 memset函数是主要用于初始化字符串的一个函数 也可以用于初始化自定义类型数组 结构体数组和其他类型数组 memset使用方法 memset函数原型如下
  • 机器学习19:反卷积算法

    机器学习19 反卷积算法 转载和整理 在整理全卷积网络的过程中 被反卷积的概念困扰很久 于是将反卷积算法单独整理为一篇博客 本文主要转载和整理自知乎问题如何通俗易懂地解释反卷积 中的高票答案 1 反卷积概述 应用在计算机视觉的深度学习领域
  • java将本地图片复制添加水印并导出到本地

    模板信息 package com example demo ChartGraphics import com sun image codec jpeg JPEGCodec import com sun image codec jpeg JP
  • Mybatis动态公用sql

  • 文件夹自动同步工具

    这是我之前开发的文件夹自动同步工具 主要实现开发机和服务器之间的文件夹同步 项目地址 https github com mike zhang autoSync 问题描述 在windows下修改代码 到服务器上去编译 但每次都要通过winsc
  • JAR 文件揭密

    JAR 文件揭密 探索 JAR 文件格式的强大功能 转载 原文地址 http www ibm com developerworks cn java j jar 简介 大多数 Java 程序员都熟悉对 JAR 文件的基本操作 但是只有少数程序
  • 【c++ 之 多态】

    目录 前言 多态 认识多态 多态的定义与实现 构成多态的条件 虚函数 1 协变 基类与派生类虚函数返回值不同 2 析构函数的重写 c 11 两个虚函数修饰关键字 final override 重载 重写 重定义再理解 抽象类 抽象类的概念
  • 飞书“蒙冤”,还是舆论有噪声?

    飞书遭微信大范围屏蔽 添加好友 共享文档等功能遭禁 初次看到这个消息的时候并没有过于惊讶 毕竟头条系和腾讯的 摩擦 早已是公关圈老生常谈的话题 双方的较量从2017年底至今 已是3年持久战 这次的较量又有些不同 有人大肆渲染飞书在帮助中小企
  • python绘制三维图

    作者 桂 时间 2017 04 27 23 24 55 链接 http www cnblogs com xingshansi p 6777945 html 本文仅仅梳理最基本的绘图方法 一 初始化 假设已经安装了matplotlib工具包
  • Hadoop集群的9870页面,DataNode启动不了的解决办法

    原因 多次格式化hdfs namenode format的操作 配置文件错误或者说修改过master配置没有进行格式化后续操作
  • Android平台GB28181设备接入端如何实时更新经纬度实现国标平台侧电子地图位置标注

    技术背景 我们在做GB28181设备接入端的时候 其中有个功能 不难但非常重要 那就是GB28181实时位置的订阅 mobileposition subscribe 和上报 notify 特别是执法记录仪 智能安全帽 车载终端等场景下 现场