当前位置: 首页 > article >正文

Android telephony | supl PDN建立和定位信息获取

在Android系统中,SUPL(Secure User Plane Location)是一种用于辅助GPS定位的技术,它通过建立特定的APN(Access Point Name)连接来传输定位数据。
以下介绍Android Telephony发起SUPL APN的PDN(Packet Data Network)建立的详细过程。

一、定位PDN建立流程

1. 【前置条件】SUPL APN的配置

SUPL APN通常由运营商在SIM卡中配置,或者在设备的APN设置中手动配置。
APN配置包括以下关键信息:

  • APN名称:例如 supl
  • APN类型:通常为 supl
  • APN协议:IPv4、IPv6或两者都支持。

2. 【文字流程】发起SUPL APN的PDN建立

2.1 应用层请求

当应用需要使用SUPL服务时(例如,使用GPS定位),Android的定位服务(如LocationManager)会请求建立SUPL连接。

2.2 Telephony层的处理

Telephony层是Android系统中负责管理电话功能的核心模块,包括SIM卡管理、网络连接、通话状态等。

Telephony层负责处理APN的连接请求。主要流程描述如下:

  1. 检查当前网络状态

    • 如果设备已经连接到互联网,Telephony会检查是否已经存在一个合适的APN连接(例如,default APN)。
    • 如果不存在合适的APN连接,Telephony会发起一个新的APN连接请求。
  2. 创建APN连接请求

    • Telephony会创建一个DataConnection对象,用于管理APN连接。
    • 该对象会包含APN的配置信息,如APN名称、类型、协议等。
  3. 发送连接请求到RIL(Radio Interface Layer)

    • Telephony通过RIL与基带处理器通信,发送建立PDN连接的请求。
    • RIL会将请求转换为基带处理器可以理解的指令,并发送给基带处理器。
2.3 RIL层的处理

RIL层负责与基带处理器通信,执行实际的PDN连接建立过程。

  1. 发送PDN连接请求

    • RIL向基带处理器发送RIL_REQUEST_SETUP_DATA_CALL请求,包含APN配置信息。
    • 基带处理器根据APN配置信息,与网络进行协商,建立PDN连接。
  2. 处理基带处理器的响应

    • 基带处理器在成功建立PDN连接后,会返回一个DataCallResponse对象,包含连接的相关信息(如IP地址、DNS服务器等)。
    • RIL将这些信息传递给Telephony层。
2.4 Telephony层的响应处理

Telephony层接收到RIL的响应后,会进行以下处理:

  1. 更新连接状态

    • Telephony会更新DataConnection对象的状态,标记为已连接。
    • 同时,Telephony会通知上层应用,SUPL APN连接已建立。
  2. 配置网络路由

    • Telephony会配置设备的网络路由,确保SUPL数据通过正确的APN连接传输。

3. 【流程图】时序图

以下是一个简化的时序图,展示了SUPL APN的PDN建立过程:

应用层 -> Telephony层: 请求建立SUPL连接
Telephony层 -> RIL层: 发送PDN连接请求 (RIL_REQUEST_SETUP_DATA_CALL)
RIL层 -> 基带处理器: 发送PDN连接请求
基带处理器 -> 网络: 协商建立PDN连接
网络 -> 基带处理器: 返回PDN连接响应
基带处理器 -> RIL层: 返回DataCallResponse
RIL层 -> Telephony层: 返回PDN连接响应
Telephony层 -> 应用层: 通知SUPL连接已建立

4. 【功能实现】关键代码示例

以下是一些关键代码示例,展示了如何在Android Telephony中发起SUPL APN的PDN建立:

4.1 发起PDN连接请求(Telephony层响应处理)
4.1.1 关键类
  • TelephonyManager:提供访问设备电话功能的接口。
  • SubscriptionManager:管理设备的SIM卡订阅信息。
  • DataConnection:管理数据连接(如APN连接)的状态和配置。
  • Phone:表示一个电话实例,管理通话、数据连接等功能。
  • DcTracker:数据连接跟踪器,负责管理数据连接的建立、断开等操作。
4.1.2 代码逻辑

以下是Telephony层处理SUPL APN建立的主要步骤:

  1. 获取TelephonyManager实例

    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    
  2. 检查设备是否支持双卡

    if (telephonyManager.getPhoneCount() > 1) {// 设备支持双卡
    }
    
  3. 获取SubscriptionManager实例

    SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
    
  4. 获取所有活跃的订阅信息

   List<SubscriptionInfo> subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();
  1. 创建APN配置
// 创建APN配置
ApnSetting apnSetting = new ApnSetting(id,                     // ID"supl",                 // APN名称null,                   // Proxy-1,                     // Portnull,                   // MMSCnull,                   // MMS Proxy-1,                     // MMS Port"supl",                 // APN类型ApnSetting.PROTOCOL_IP, // 协议ApnSetting.PROTOCOL_IP, // 漫游协议true,                   // 启用状态0,                      // 网络类型true,                   // 可承载false,                  // 漫游时启用0,                      // 用户可见null,                   // 用户null,                   // 密码0                       // 认证类型
);
  1. 发起数据连接请求
// 发起PDN连接请求
DataConnection dataConnection = new DataConnection(context, phone, apnSetting);
dataConnection.connect();

Note:在旧版本的Android上,是在DcTracker中,调用setupDataCall方法发起数据连接请求。(Android T/U已经不使用)

DcTracker dcTracker = phone.getDcTracker();
dcTracker.setupDataCall(apnSetting);
  1. 处理数据连接状态
  • DcTracker会监听数据连接的状态变化,并通过回调通知上层应用。

    dcTracker.registerForDataStateChanged(handler, EVENT_DATA_STATE_CHANGED);
    
  • 新版本在 DataNetwork 中注册监听(以下是Android V的代码案例)

    • frameworks/opt/telephony/src/java/com/android/internal/telephony/data/DataNetwork.java
            for (int transport : mAccessNetworksManager.getAvailableTransports()) {mDataServiceManagers.get(transport).registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);}
4.2 处理PDN连接响应(RIL层处理)

RIL层是Android系统中负责与基带处理器通信的模块。它将Telephony层的请求转换为基带处理器可以理解的指令,并处理基带处理器的响应。

4.2.1 关键类
  • RIL:实现与基带处理器的通信。
  • RILRequest:表示一个RIL请求。
  • RILConstants:定义RIL请求和响应的常量。
  • DataCallResponse:表示数据连接的响应。
4.2.2 代码逻辑

以下是RIL层处理SUPL APN建立的主要步骤:

  1. 创建RIL请求
    • RIL中,创建一个RIL_REQUEST_SETUP_DATA_CALL请求。
    RILRequest rr = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
    
  2. 发送RIL请求
    • 将请求发送到基带处理器。
    rr.mParcel.writeInt(radioTechnology);
    rr.mParcel.writeString(apn);
    rr.mParcel.writeString(protocol);
    send(rr);
    
  3. 处理基带处理器的响应
  • 基带处理器返回一个DataCallResponse对象,包含连接的相关信息。
DataCallResponse response = new DataCallResponse();
response.status = parcel.readInt();
response.suggestedRetryTime = parcel.readInt();
response.cid = parcel.readInt();
response.active = parcel.readInt();
response.type = parcel.readString();
response.ifname = parcel.readString();
response.addresses = parcel.readStringArray();
response.dnses = parcel.readStringArray();
response.gateways = parcel.readStringArray();
  1. 返回响应给Telephony层
  • DataCallResponse对象返回给Telephony层。
if (rr.mResult != null) {AsyncResult.forMessage(rr.mResult, response, null);rr.mResult.sendToTarget();
}
  1. Telephony 收到回调
// 上层处理PDN连接响应
void onDataCallResponse(DataCallResponse response) {if (response.status == DataCallResponse.STATUS_SUCCESS) {// 更新连接状态updateConnectionState(ConnectionState.CONNECTED);// 配置网络路由configureNetworkRouting(response);// 通知上层应用notifySuplConnectionEstablished();} else {// 处理连接失败handleConnectionFailure(response);}
}

5. 注意事项

  • 权限:在AndroidManifest.xml中需要声明相关权限,如ACCESS_FINE_LOCATIONINTERNET等。
  • API级别:部分API可能需要较高的Android版本支持,需注意兼容性。
  • 运营商配置:不同运营商的SUPL APN配置可能不同,需确保配置正确。

通过以上步骤,Android Telephony可以成功发起SUPL APN的PDN建立,从而支持SUPL定位服务。

6. 总结

  • Telephony层负责管理数据连接的逻辑,包括APN配置、连接请求和状态管理。
// 获取TelephonyManager实例
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);// 检查设备是否支持双卡
if (telephonyManager.getPhoneCount() > 1) {// 获取SubscriptionManager实例SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);// 获取所有活跃的订阅信息List<SubscriptionInfo> subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();// 创建APN配置ApnSetting apnSetting = new ApnSetting(id,                     // ID"supl",                 // APN名称null,                   // Proxy-1,                     // Portnull,                   // MMSCnull,                   // MMS Proxy-1,                     // MMS Port"supl",                 // APN类型ApnSetting.PROTOCOL_IP, // 协议ApnSetting.PROTOCOL_IP, // 漫游协议true,                   // 启用状态0,                      // 网络类型true,                   // 可承载false,                  // 漫游时启用0,                      // 用户可见null,                   // 用户null,                   // 密码0                       // 认证类型);// 发起数据连接请求DcTracker dcTracker = phone.getDcTracker();dcTracker.setupDataCall(apnSetting);
}
  • RIL层负责与基带处理器通信,将Telephony层的请求转换为基带指令,并处理基带处理器的响应。
// 创建RIL请求
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);// 发送RIL请求
rr.mParcel.writeInt(radioTechnology);
rr.mParcel.writeString(apn);
rr.mParcel.writeString(protocol);
send(rr);// 处理基带处理器的响应
DataCallResponse response = new DataCallResponse();
response.status = parcel.readInt();
response.suggestedRetryTime = parcel.readInt();
response.cid = parcel.readInt();
response.active = parcel.readInt();
response.type = parcel.readString();
response.ifname = parcel.readString();
response.addresses = parcel.readStringArray();
response.dnses = parcel.readStringArray();
response.gateways = parcel.readStringArray();// 返回响应给Telephony层
if (rr.mResult != null) {AsyncResult.forMessage(rr.mResult, response, null);rr.mResult.sendToTarget();
}
  • 通过Telephony层和RIL层的协作,Android系统可以成功建立SUPL APN连接,并支持SUPL定位服务。

二、定位信息获取

在Android系统中,SUPL(Secure User Plane Location)协议的主要目的是辅助GPS定位,以提高定位的速度和精度。当SUPL APN的PDN建立成功后,设备可以通过SUPL协议从网络获取辅助数据(A-GPS数据),并结合GPS模块获取精确的定位信息。以下是详细的解释:


1. SUPL PDN建立后的定位信息来源

SUPL PDN建立后,设备可以通过以下方式获取定位信息:

1.1 A-GPS辅助数据
  • 作用:A-GPS(Assisted GPS)数据用于加速GPS定位过程,尤其是在冷启动(Cold Start)情况下。
  • 内容
    • 卫星星历(Ephemeris Data):提供GPS卫星的精确位置信息。
    • 粗略时间(Coarse Time):帮助设备快速锁定卫星信号。
    • 粗略位置(Coarse Position):基于网络小区(Cell ID)或Wi-Fi的粗略位置。
  • 获取方式:通过SUPL协议从运营商的位置服务器(如SUPL服务器)下载。
1.2 GPS定位信息
  • 作用:GPS模块通过接收卫星信号计算设备的精确位置。
  • 内容
    • 经纬度(Latitude and Longitude):设备的精确地理位置。
    • 海拔高度(Altitude):设备的海拔高度(如果支持)。
    • 速度(Speed):设备的移动速度(如果支持)。
    • 方向(Bearing):设备的移动方向(如果支持)。
  • 获取方式:GPS模块直接接收卫星信号并计算。
1.3 网络小区信息
  • 作用:在网络辅助定位(如A-GPS或基于网络的定位)中,网络小区信息用于提供设备的粗略位置。
  • 内容
    • 小区ID(Cell ID):设备当前连接的基站小区。
    • 位置区码(LAC):基站的位置区域。
    • 信号强度(Signal Strength):设备的信号强度。
  • 获取方式:通过Telephony API获取。

2. 定位信息的获取流程

以下是SUPL PDN建立后,设备获取定位信息的典型流程:

  1. SUPL PDN建立

    • 设备通过SUPL APN连接到运营商的位置服务器(SUPL服务器)。
  2. 请求A-GPS辅助数据

    • 设备向SUPL服务器发送请求,获取A-GPS辅助数据(如卫星星历、粗略时间等)。
  3. GPS模块初始化

    • 设备使用A-GPS辅助数据初始化GPS模块,加速卫星信号的锁定。
  4. GPS定位计算

    • GPS模块接收卫星信号,计算设备的精确位置(经纬度、海拔等)。
  5. 返回定位信息

    • 设备将GPS定位信息返回给应用层,供应用使用。

3. 定位信息的类型

根据定位方式的不同,设备可能返回以下类型的定位信息:

3.1 GPS定位信息
  • 数据类型:经纬度、海拔、速度、方向等。
  • 精度:高(通常在几米以内)。
  • 获取方式:通过LocationManagerGPS_PROVIDER获取。
3.2 网络定位信息
  • 数据类型:基于网络小区(Cell ID)或Wi-Fi的粗略位置。
  • 精度:低(通常在几百米到几公里)。
  • 获取方式:通过LocationManagerNETWORK_PROVIDER获取。
3.3 混合定位信息
  • 数据类型:结合GPS和网络定位的混合数据。
  • 精度:中等(通常在几十米到几百米)。
  • 获取方式:通过LocationManagerFUSED_PROVIDER获取(需要Google Play服务支持)。

4. 代码示例

以下是通过LocationManager获取定位信息的代码示例:

4.1 获取GPS定位信息
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 监听GPS定位
LocationListener gpsListener = new LocationListener() {@Overridepublic void onLocationChanged(Location location) {double latitude = location.getLatitude();  // 纬度double longitude = location.getLongitude(); // 经度double altitude = location.getAltitude();   // 海拔float speed = location.getSpeed();          // 速度float bearing = location.getBearing();      // 方向Log.d("GPS Location", "Lat: " + latitude + ", Lon: " + longitude);}@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}@Overridepublic void onProviderEnabled(String provider) {}@Overridepublic void onProviderDisabled(String provider) {}
};// 请求GPS定位更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, gpsListener);
4.2 获取网络定位信息
LocationListener networkListener = new LocationListener() {@Overridepublic void onLocationChanged(Location location) {double latitude = location.getLatitude();  // 纬度double longitude = location.getLongitude(); // 经度Log.d("Network Location", "Lat: " + latitude + ", Lon: " + longitude);}@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}@Overridepublic void onProviderEnabled(String provider) {}@Overridepublic void onProviderDisabled(String provider) {}
};// 请求网络定位更新
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, networkListener);

5. 时序图

以下是SUPL PDN建立后,设备获取定位信息的时序图:

设备 -> SUPL服务器: 建立SUPL PDN连接
设备 -> SUPL服务器: 请求A-GPS辅助数据
SUPL服务器 -> 设备: 返回A-GPS辅助数据
设备 -> GPS模块: 初始化GPS模块
GPS模块 -> 卫星: 接收卫星信号
GPS模块 -> 设备: 计算并返回GPS定位信息
设备 -> 应用层: 返回定位信息(经纬度等)

6. 总结

  • SUPL PDN建立后,设备主要通过GPS模块获取精确的定位信息(如经纬度、海拔等)。
  • A-GPS辅助数据用于加速GPS定位过程,但不会直接提供定位信息。
  • 网络小区信息通常用于粗略定位,精度较低。
  • 最终的定位信息通常是经纬度,这是GPS定位的核心输出。

通过SUPL协议和GPS模块的结合,Android设备可以快速、准确地获取设备的精确位置信息。

相关文章:

Android telephony | supl PDN建立和定位信息获取

在Android系统中&#xff0c;SUPL&#xff08;Secure User Plane Location&#xff09;是一种用于辅助GPS定位的技术&#xff0c;它通过建立特定的APN&#xff08;Access Point Name&#xff09;连接来传输定位数据。 以下介绍Android Telephony发起SUPL APN的PDN&#xff08;P…...

ip地址是手机号地址还是手机地址

在数字化生活的浪潮中&#xff0c;IP地址、手机号和手机地址这三个概念如影随形&#xff0c;它们各自承载着网络世界的独特功能&#xff0c;却又因名称和功能的相似性而时常被混淆。尤其是“IP地址”这一术语&#xff0c;经常被错误地与手机号地址或手机地址划上等号。本文旨在…...

【react】react面试题

react面试题 1.对 React 的理解、特性 2.react18有哪些更新 3.JSX是什么 4.解释为什么浏览器不能读取jsx 6.ReactNative中&#xff0c;如何解决8081端口被占用而提示无法访问的问题&#xff1f; 7. React 生命周期 8.react事件机制 9.react 组件传值 10.React改…...

zephyr devicetree

Syntax and structure — Zephyr Project Documentation Input files There are four types of devicetree input files: sources (.dts) includes (.dtsi) overlays (.overlay) bindings (.yaml) The devicetree files inside the zephyr directory look like this: …...

学习笔记:机器学习中的数学原理(一)

1. 集合 集合分为有限集和无限集&#xff1b; 对于有限集&#xff0c;两集合元素数相等即为等势&#xff1b; 对于无限集&#xff0c;两集合元素存在一一映射关系即为等势&#xff1b; 无限集根据是否与正整数集等势分为可数集和不可数集。 2. sigmoid函数&#xff08;也叫…...

鼠标滚轮冒泡事件@wheel.stop

我有一个页面,是在画布上的组件,但是组件中有一个table,table中数据多了,就会出现滚动条,正常情况下,滚动条用鼠标滚轮就可以滑动,但是这个table是在画布上,滚动滚轮会让画布缩放 在table外层的div上加上 wheel.stop,就生效了 wheel.stop 用途&#xff1a;这个修饰符用于处理鼠…...

Unity DoTween使用文档

DoTween 使用文档 DoTween 是 Unity 中非常流行的动画补间插件。它通过链式调用方式&#xff0c;让开发者可以快速创建平滑、自然的动画效果。本文将介绍 DoTween 的基础用法、缓动曲线原理&#xff08;包含常见缓动曲线的数学公式与参数说明&#xff09;、案例演示以及一些常…...

C语言中的共用体(Union):嵌入式开发中的节省内存利器

在进行嵌入式开发时&#xff0c;我们常常会听到这样一句话&#xff1a;“内存就是金钱。” 在嵌入式系统中&#xff0c;内存资源通常是非常稀缺的&#xff0c;尤其是在一些微控制器&#xff08;如STM32、ESP32等&#xff09;的开发中&#xff0c;我们需要尽可能地精打细算&…...

Java 线程池:7参数配置、4拒绝策略与执行流程详解

1. 为什么需要线程池&#xff1f; 在 Java 并发编程中&#xff0c;线程的创建和销毁是一项昂贵的操作。频繁地创建和销毁线程会带来较高的系统开销&#xff0c;甚至可能因线程数过多而导致 OOM&#xff08;OutOfMemoryError&#xff09; 或 CPU 过载。 线程池&#xff08;Thre…...

代码随想录算法【Day38】

Day38 322. 零钱兑换 思路 完全背包 代码 class Solution { public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount 1, INT_MAX);dp[0] 0;for (int i 0; i < coins.size(); i) { // 遍历物品for (int j coins[i]; j <…...

c# Lazy<T>单例模式 - 延迟初始化单例实例示例与详解

Lazy 延迟初始化单例实例示例与详解 Lazy<T> 是 C# 中用于延迟初始化的类&#xff0c;它允许你在第一次访问对象时才创建实例&#xff0c;而不是在程序启动时就创建实例。这在单例模式中非常有用&#xff0c;因为它可以避免不必要的资源消耗。 1. Lazy 的基本用法 Laz…...

51单片机之冯·诺依曼结构

一、概述 8051系列单片机将作为控制应用最基本的内容集成在一个硅片上&#xff0c;其内部结构如图4-1所示。作为单一芯片的计算机&#xff0c;它的内部结构与一台计算机的主机非常相似。其中微处理器相当于计算机中的CPU&#xff0c;由运算器和控制器两个部分构成&#xff1b;…...

Safari常用快捷键

一、书签边栏 1、显示或隐藏书签边栏&#xff1a;Control-Command-1 2、选择下一个书签或文件夹&#xff1a;向上头键或向下头键 3、打开所选书签&#xff1a;空格键 4、打开所选文件夹&#xff1a;空格键或右箭头键 5、关闭所选文件夹&#xff1a;空格键或左箭头键 6、更…...

02.07 TCP服务器与客户端的搭建

一.思维导图 二.使用动态协议包实现服务器与客户端 1. 协议包的结构定义 首先&#xff0c;是协议包的结构定义。在两段代码中&#xff0c;pack_t结构体都被用来表示协议包&#xff1a; typedef struct Pack {int size; // 记录整个协议包的实际大小enum Type type; …...

【CubeMX+STM32】SD卡 文件系统读写 FatFs+SDIO+DMA

本篇&#xff0c;将使用CubeMXKeil&#xff0c;创建一个SD卡的 FatFSSDIODMA 文件系统读写工程。 目录 一、简述 二、CubeMX 配置 FatFSSDIO DMA 三、Keil 编辑代码 四、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、简述 上两篇&#xff0c;已循序渐进讲解了SD、…...

51单片机之使用Keil uVision5创建工程以及使用stc-isp进行程序烧录步骤

一、Keil uVision5创建工程步骤 1.点击项目&#xff0c;新建 2.新建目录 3.选择目标机器&#xff0c;直接搜索at89c52选择&#xff0c;然后点击OK 4.是否添加起吊文件&#xff0c;一般选择否 5.再新建的项目工程中添加文件 6.选择C文件 7.在C文件中右键&#xff0c;添加…...

aws(学习笔记第二十七课) 使用aws API Gateway+lambda体验REST API

aws(学习笔记第二十七课) 使用aws API Gatewaylambda体验REST API 学习内容&#xff1a; 使用aws API Gatewaylambda 1. 使用aws API Gatewaylambda 作成概要 使用api gateway定义REST API&#xff0c;之后再接收到了http request之后&#xff0c;redirect到lambda进行执行。…...

React - jsx 语法

在 React 中&#xff0c;JSX&#xff08;JavaScript XML&#xff09;是一种语法扩展&#xff0c;它允许开发者在 JavaScript 代码中使用类似 HTML 的语法。JSX 提升了代码的可读性和可维护性&#xff0c;使得编写和构建用户界面更加直观。它被广泛应用于 React 组件的定义。 一…...

5 前端系统开发:Vue2、Vue3框架(上):Vue入门式开发和Ajax技术

文章目录 前言一、Vue框架&#xff08;简化DOM操作的一个前端框架&#xff09;&#xff1a;基础入门1 Vue基本概念2 快速入门&#xff1a;创建Vue实例&#xff0c;初始化渲染&#xff08;1&#xff09;创建一个入门Vue实例&#xff08;2&#xff09;插值表达式&#xff1a;{{表…...

快速在wsl上部署学习使用c++轻量化服务器-学习笔记

知乎上推荐的Tinywebserver这个服务器&#xff0c;快速部署搭建&#xff0c;学习c服务器开发 仓库地址 githubhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServerhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServer 在…...

2025年Android NDK超全版本下载地址

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…...

React 设计模式:实用指南

React 提供了众多出色的特性以及丰富的设计模式&#xff0c;用于简化开发流程。开发者能够借助 React 组件设计模式&#xff0c;降低开发时间以及编码的工作量。此外&#xff0c;这些模式让 React 开发者能够构建出成果更显著、性能更优越的各类应用程序。 本文将会为您介绍五…...

B站自研的第二代视频连麦系统(上)

导读 本系列文章将从客户端、服务器以及音视频编码优化三个层面&#xff0c;介绍如何基于WebRTC构建视频连麦系统。希望通过这一系列的讲解&#xff0c;帮助开发者更全面地了解 WebRTC 的核心技术与实践应用。 背景 在文章《B站在实时音视频技术领域的探索与实践》中&#xff…...

centOS8安装MySQL8设置开机自动启动失败

提供一个终极解决方案虽然systemctl 更符合管理预期但是不能用 使用一下命令 修改配置文件、修改mysql.service全是问题 systemctl start mysqld systemctl enable mysqld systemctl daemon-reload完全不生效各种报错 提示配置文件内容有问题 Main process exited, codeexite…...

使用Python实现PDF与SVG相互转换

目录 使用工具 使用Python将SVG转换为PDF 使用Python将SVG添加到现有PDF中 使用Python将PDF转换为SVG 使用Python将PDF的特定页面转换为SVG SVG&#xff08;可缩放矢量图形&#xff09;和PDF&#xff08;便携式文档格式&#xff09;是两种常见且广泛使用的文件格式。SVG是…...

[渗透测试]热门搜索引擎推荐— — shodan篇

[渗透测试]热门搜索引擎推荐— — shodan篇 免责声明&#xff1a;本文仅用于分享渗透测试工具&#xff0c;大家使用时&#xff0c;一定需要遵守相关法律法规。 除了shodan&#xff0c;还有很多其他热门的&#xff0c;比如&#xff1a;fofa、奇安信的鹰图、钟馗之眼等&#xff0…...

基于物联网技术的智能寻车引导系统方案:工作原理、核心功能及系统架构

本文专为IT技术员、软件开发工程师及智能停车领域专业人士打造&#xff0c;旨在深入剖析智能寻车引导系统的构建与优化过程。如需获取详细解决方案可前往文章最下方获取&#xff0c;如有项目需求及技术合作可私信作者。 智能寻车引导系统是一种集智能化、自动化于一体的停车管理…...

【React】合成事件语法

React 合成事件是 React 为了处理浏览器之间的事件差异而提供的一种跨浏览器的事件系统。它封装了原生的 DOM 事件&#xff0c;提供了一致的事件处理机制。 合成事件与原生事件的区别&#xff1a; 合成事件是 React 自己实现的&#xff0c;封装了原生事件。合成事件依然可以通…...

Redis02 - 持久化

Redis持久化 文章目录 Redis持久化一&#xff1a;持久化简介1&#xff1a;Redis为什么要进行持久化2&#xff1a;Redis持久化的方式 二&#xff1a;RDB持久化介绍1&#xff1a;手动触发RDB2&#xff1a;自动触发RDB3&#xff1a;redis.conf中进行RDB的配置4&#xff1a;RDB优缺…...

初始JavaEE篇 —— Spring Web MVC入门(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 RequestMappingg 注解介绍 Postman的介绍与使用 PostMapping 与 GetMapping 注解 构造并接收请求 接收简单参数 接收对象…...