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

Android获取经纬度的最佳实现方式

Android中获取定位信息的方式有很多种,系统自带的LocationManager,以及第三方厂商提供的一些定位sdk,都能帮助我们获取当前经纬度,但第三方厂商一般都需要申请相关的key,且调用量高时,还会产生资费问题。这里采用LocationManager + FusedLocationProviderClient 的方式进行经纬度的获取,以解决普通场景下获取经纬度和经纬度转换地址的功能。

一,添加定位权限

<!--允许获取精确位置,精准定位必选-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--后台获取位置信息,若需后台定位则必选-->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!--用于申请调用A-GPS模块,卫星定位加速-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

二,添加依赖库

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'implementation 'com.google.android.gms:play-services-location:21.0.1'

三,使用LocationManager获取当前经纬度

获取经纬度时,可根据自己的诉求进行参数自定义,如果对经纬度要求不是很精确的可以自行配置Criteria里面的参数。

获取定位前需要先判断相关的服务是否可用,获取定位的服务其实有很多种选择,因为个人项目对经纬度准确性要求较高,为了保证获取的成功率和准确性,只使用了GPS和网络定位两种,如果在国内还会有基站获取等方式,可以自行修改。

import android.Manifest.permission
import android.location.*
import android.os.Bundle
import android.util.Log
import androidx.annotation.RequiresPermission
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeout
import kotlin.coroutines.resumeobject LocationManagerUtils {val TAG = "LocationManagerUtils"/*** @mLocationManager 传入LocationManager对象* @minDistance  位置变化最小距离:当位置距离变化超过此值时,将更新位置信息(单位:米)* @timeOut 超时时间,如果超时未返回,则直接使用默认值*/@RequiresPermission(anyOf = [permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION])suspend  fun getCurrentPosition(mLocationManager: LocationManager,timeOut: Long = 3000,):Location{var locationListener : LocationListener?=nullreturn  try {//超时未返回则直接获取失败,返回默认值withTimeout(timeOut){suspendCancellableCoroutine {continuation ->//获取最佳定位方式,如果获取不到则默认采用网络定位。var bestProvider = mLocationManager.getBestProvider(createCriteria(),true)if (bestProvider.isNullOrEmpty()||bestProvider == "passive"){bestProvider = "network"}Log.d(TAG, "getCurrentPosition:bestProvider:${bestProvider}")locationListener = object : LocationListener {override fun onLocationChanged(location: Location) {Log.d(TAG, "getCurrentPosition:onCompete:${location.latitude},${location.longitude}")if (continuation.isActive){continuation.resume(location)mLocationManager.removeUpdates(this)}}override fun onProviderDisabled(provider: String) {}override fun onProviderEnabled(provider: String) {}}//开始定位mLocationManager.requestLocationUpdates(bestProvider,1000,0f,locationListener!!)}}}catch (e:Exception){try {locationListener?.let {mLocationManager.removeUpdates(it)}}catch (e:Exception){Log.d(TAG, "getCurrentPosition:removeUpdate:${e.message}")}//超时直接返回默认的空对象Log.d(TAG, "getCurrentPosition:onError:${e.message}")return createDefaultLocation()}}@RequiresPermission(anyOf = [permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION])suspend fun repeatLocation(mLocationManager: LocationManager):Location{return  suspendCancellableCoroutine {continuation ->//获取最佳定位方式,如果获取不到则默认采用网络定位。var bestProvider = mLocationManager.getBestProvider(createCriteria(),true)if (bestProvider.isNullOrEmpty()||bestProvider == "passive"){bestProvider = "network"}Log.d(TAG, "getCurrentPosition:bestProvider:${bestProvider}")val locationListener = object : LocationListener {override fun onLocationChanged(location: Location) {Log.d(TAG, "getCurrentPosition:onCompete:${location.latitude},${location.longitude}")if (continuation.isActive){continuation.resume(location)}mLocationManager.removeUpdates(this)}override fun onProviderDisabled(provider: String) {}override fun onProviderEnabled(provider: String) {}}//开始定位mLocationManager.requestLocationUpdates(bestProvider,1000, 0f, locationListener)}}@RequiresPermission(anyOf = [permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION])fun getLastLocation( mLocationManager: LocationManager): Location {//获取最佳定位方式,如果获取不到则默认采用网络定位。var currentProvider = mLocationManager.getBestProvider(createCriteria(), true)if (currentProvider.isNullOrEmpty()||currentProvider == "passive"){currentProvider = "network"}return mLocationManager.getLastKnownLocation(currentProvider) ?: createDefaultLocation()}//创建定位默认值fun createDefaultLocation():Location{val location = Location("network")location.longitude = 0.0location.latitude = 0.0return location}private fun createCriteria():Criteria{return  Criteria().apply {accuracy = Criteria.ACCURACY_FINEisAltitudeRequired = falseisBearingRequired = falseisCostAllowed = truepowerRequirement = Criteria.POWER_HIGHisSpeedRequired = false}}///定位是否可用fun checkLocationManagerAvailable(mLocationManager: LocationManager):Boolean{return mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)||mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)}
}

二,使用FusedLocationProviderClient

在获取经纬度时会出现各种异常的场景,会导致成功的回调一直无法触发,这里使用了协程,如果超过指定超时时间未返回,则直接默认为获取失败,进行下一步的处理。

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.location.Geocoder
import android.location.Location
import android.location.LocationManager
import android.provider.Settings
import android.util.Log
import androidx.annotation.RequiresPermission
import com.google.android.gms.location.LocationServices
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import java.io.IOException
import java.util.*
import kotlin.coroutines.resumeobject FusedLocationProviderUtils {val TAG = "FusedLocationUtils"@RequiresPermission(anyOf = ["android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"])suspend  fun checkFusedLocationProviderAvailable(fusedLocationClient: FusedLocationProviderClient):Boolean{return  try {withTimeout(1000){suspendCancellableCoroutine { continuation ->fusedLocationClient.locationAvailability.addOnFailureListener {Log.d(TAG, "locationAvailability:addOnFailureListener:${it.message}")if (continuation.isActive){continuation.resume(false)}}.addOnSuccessListener {Log.d(TAG, "locationAvailability:addOnSuccessListener:${it.isLocationAvailable}")if (continuation.isActive){continuation.resume(it.isLocationAvailable)}}}}}catch (e:Exception){return false}}///获取最后已知的定位信息@RequiresPermission(anyOf = ["android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"])suspend fun getLastLocation(fusedLocationClient: FusedLocationProviderClient):Location{return  suspendCancellableCoroutine {continuation ->fusedLocationClient.lastLocation.addOnSuccessListener {if (continuation.isActive){Log.d(TAG, "current location success:$it")if (it != null){continuation.resume(it)}else{continuation.resume(createDefaultLocation())}}}.addOnFailureListener {continuation.resume(createDefaultLocation())}}}/*** 获取当前定位,需要申请定位权限**/@RequiresPermission(anyOf = ["android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"])suspend fun getCurrentPosition(fusedLocationClient: FusedLocationProviderClient): Location {return suspendCancellableCoroutine {continuation ->fusedLocationClient.getCurrentLocation(createLocationRequest(),object : CancellationToken(){override fun onCanceledRequested(p0: OnTokenCanceledListener): CancellationToken {return CancellationTokenSource().token}override fun isCancellationRequested(): Boolean {return false}}).addOnSuccessListener {if (continuation.isActive){Log.d(TAG, "current location success:$it")if (it != null){continuation.resume(it)}else{continuation.resume(createDefaultLocation())}}}.addOnFailureListener {Log.d(TAG, "current location fail:$it")if (continuation.isActive){continuation.resume(createDefaultLocation())}}.addOnCanceledListener {Log.d(TAG, "current location cancel:")if (continuation.isActive){continuation.resume(createDefaultLocation())}}}}//创建当前LocationRequest对象private fun createLocationRequest():CurrentLocationRequest{return CurrentLocationRequest.Builder().setDurationMillis(1000).setMaxUpdateAgeMillis(5000).setPriority(Priority.PRIORITY_HIGH_ACCURACY).build()}//创建默认值private fun createDefaultLocation():Location{val location = Location("network")location.longitude = 0.0location.latitude = 0.0return location}
}

三,整合LocationManager和FusedLocationProviderClient

在获取定位时,可能会出现GPS定位未开启的情况,所以不管是LocationManager或FusedLocationProviderClient都需要判断当前服务是否可用,获取定位时,如果GPS信号较弱等异常情况下,就需要考虑到获取定位超时的情况,这里使用了协程,如FusedLocationProviderClient超过3秒未获取成功,则直接切换到LocationManager进行二次获取,这是提升获取经纬度成功的关键。

在实际项目中,如果对获取经纬度有较高的考核要求时,通过结合LocationManager和FusedLocationProviderClient如果还是获取不到,可考虑集成第三方的进行进一步获取,可以考虑使用华为的免费融合定位服务,因为我们使用过百度地图的sdk,每天会出现千万分之五左右的定位错误和定位漂移问题。

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.location.Geocoder
import android.location.Location
import android.location.LocationManager
import android.provider.Settings
import android.util.Log
import androidx.annotation.RequiresPermission
import com.google.android.gms.location.LocationServices
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import java.io.IOException
import java.util.*
import kotlin.coroutines.resumeobject LocationHelper {fun getLocationServiceStatus(context: Context):Boolean{return (context.getSystemService(LOCATION_SERVICE) as LocationManager).isProviderEnabled(LocationManager.GPS_PROVIDER)}/*** 打开定位服务设置*/fun openLocationSetting(context: Context):Boolean{return try {val settingsIntent = Intent()settingsIntent.action = Settings.ACTION_LOCATION_SOURCE_SETTINGSsettingsIntent.addCategory(Intent.CATEGORY_DEFAULT)settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)settingsIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)context.startActivity(settingsIntent)true} catch (ex: java.lang.Exception) {false}}/*** 获取当前定位*/@RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])suspend fun getLocation(context: Activity,timeOut: Long = 2000):Location{val location = getLocationByFusedLocationProviderClient(context)//默认使用FusedLocationProviderClient 如果FusedLocationProviderClient不可用或获取失败,则使用LocationManager进行二次获取Log.d("LocationHelper", "getLocation:$location")return  if (location.latitude == 0.0){getLocationByLocationManager(context, timeOut)}else{location}}@RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])private suspend fun getLocationByLocationManager(context: Activity,timeOut: Long = 2000):Location{Log.d("LocationHelper", "getLocationByLocationManager")val locationManager =  context.getSystemService(LOCATION_SERVICE) as LocationManager//检查LocationManager是否可用return  if (LocationManagerUtils.checkLocationManagerAvailable(locationManager)){//使用LocationManager获取当前经纬度val location = LocationManagerUtils.getCurrentPosition(locationManager, timeOut)if (location.latitude == 0.0){LocationManagerUtils.getLastLocation(locationManager)}else{location}}else{//获取失败,则采用默认经纬度LocationManagerUtils.createDefaultLocation()}}@RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])private suspend fun getLocationByFusedLocationProviderClient(context: Activity):Location{Log.d("LocationHelper", "getLocationByFusedLocationProviderClient")//使用FusedLocationProviderClient进行定位val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)return if (FusedLocationProviderUtils.checkFusedLocationProviderAvailable(fusedLocationClient)){withContext(Dispatchers.IO){//使用FusedLocationProviderClient获取当前经纬度val location = FusedLocationProviderUtils.getCurrentPosition(fusedLocationClient)if (location.latitude == 0.0){FusedLocationProviderUtils.getLastLocation(fusedLocationClient)}else{location}}}else{LocationManagerUtils.createDefaultLocation()}}
}
注:因为获取定位是比较耗电的操作,在实际使用时,可增加缓存机制,比如2分钟之内频繁,则返回上一次缓存的数据,如果超过2分钟则重新获取一次,并缓存起来。

四,获取当前经纬度信息或经纬度转换地址

1,获取当前经纬度
 @RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION])fun getCurrentLocation(activity:Activity){if (activity != null){val exceptionHandler = CoroutineExceptionHandler { _, exception ->}viewModelScope.launch(exceptionHandler) {val location = LocationHelper.getLocation(activity!!)val map = HashMap<String,String>()map["latitude"] ="${location.latitude}"map["longitude"] = "${location.longitude}"}}}
2,经纬度转换地址
 /*** @param latitude 经度* @param longitude 纬度* @return 详细位置信息*/suspend fun convertAddress(context: Context, latitude: Double, longitude: Double): String {return try {withTimeout(3000){suspendCancellableCoroutine {  continuation ->try {val mGeocoder = Geocoder(context, Locale.getDefault())val mStringBuilder = StringBuilder()if (Geocoder.isPresent()){val mAddresses = mGeocoder.getFromLocation(latitude, longitude, 1)if (mAddresses!= null &&mAddresses.size >0) {val address = mAddresses[0]Log.d("LocationUtils", "convertAddress()--->$address")mStringBuilder.append(address.getAddressLine(0)?:"").append(",").append(address.adminArea?:address.subAdminArea?:"").append(",").append(address.locality?:address.subLocality?:"").append(",").append(address.thoroughfare?:address.subThoroughfare?:"")}}if (continuation.isActive){continuation.resume(mStringBuilder.toString())}} catch (e: IOException) {Log.d("LocationUtils", "convertAddress()--IOException->${e.message}")if (continuation.isActive){continuation.resume("")}}}}}catch (e:Exception){Log.d("LocationUtils", "convertAddress()--->timeout")return ""}}

调用时:

fun covertAddress(latitude:double,longitude:double){if (activity != null){val exceptionHandler = CoroutineExceptionHandler { _, exception ->}viewModelScope.launch(exceptionHandler) {val hashMap = argument as HashMap<*, *>withContext(Dispatchers.IO){val address = LocationHelper.convertAddress(activity!!,"${hashMap["latitude"]}".toDouble(),"${hashMap["longitude"]}".toDouble())}}}}

注:经纬度转换地址时,需要开启一个线程或者协程进行转换,不然会阻塞主线程,引发异常。

相关文章:

Android获取经纬度的最佳实现方式

Android中获取定位信息的方式有很多种&#xff0c;系统自带的LocationManager&#xff0c;以及第三方厂商提供的一些定位sdk&#xff0c;都能帮助我们获取当前经纬度&#xff0c;但第三方厂商一般都需要申请相关的key&#xff0c;且调用量高时&#xff0c;还会产生资费问题。这…...

芒果YOLOv8改进137:主干篇CSPNeXt,小目标检测专用,COCO数据集验证,协调参数量和计算量的均衡,即插即用 | 打造高性能检测

该专栏完整目录链接: 芒果YOLOv8深度改进教程 芒果专栏 本篇基于 CSPNeXt 的改进结构,改进源码教程 | 详情如下🥇 本博客 CSPNeXt 改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 即插即用 结构,博客包括改进所需的 核心结构代码 文件 重点:🔥🔥🔥YOLOv8 …...

【测试开发学习历程】认识Python + 安装Python

目录 1 认识 Python 1.1 Python 的起源 1.2 Python的组成 1.2.1 解释器 1.1.2 Python 的设计目标 1.1.3 Python 的设计哲学 1.2 为什么选择 Python 测试人员选择Python的理由 1.3 Python 特点 面向对象的思维方式 1.4 Python 的优缺点 1.4.1 优点 1.4.2 缺点 3. 安…...

webpack proxy工作原理?为什么能解决跨域?

一、是什么 webpack proxy&#xff0c;即webpack提供的代理服务 基本行为就是接收客户端发送的请求后转发给其他服务器 其目的是为了便于开发者在开发模式下解决跨域问题&#xff08;浏览器安全策略限制&#xff09; 想要实现代理首先需要一个中间服务器&#xff0c;webpac…...

ArkTS编写的HarmonyOS原生聊天UI框架

简介 ChatUI&#xff0c;是一个ArkTS编写的HarmonyOS原生聊天UI框架&#xff0c;提供了开箱即用的聊天对话组件。 下载安装 ohpm install changwei/chatuiOpenHarmony ohpm 环境配置等更多内容&#xff0c;请参考如何安装 OpenHarmony ohpm 包 接口和属性列表 接口列表 接…...

uni-app中web-view的使用

1. uni-app中web-view的使用 uni-app中的web-view是一个 web 浏览器组件&#xff0c;可以用来承载网页的容器&#xff0c;uni-app开发的app与web-view实现交互的方式相关简单&#xff0c;应用通过属性message绑定触发事件&#xff0c;然后在web-view的网页向应用 postMessage 触…...

前端跨域概念及解决方法

文章目录 前端跨域概念及解决方法什么是跨域跨域的解决方法JSONP跨域CORS简单请求 非简单请求 Nginx反向代理 前端跨域概念及解决方法 什么是跨域 同源指&#xff1a;两个页面域名、协议、端口均相同。 同源策略是浏览器的一个安全限制&#xff0c;跨域是由浏览器的同源策略造…...

Redis中的事务机制

Redis中的事务机制 概述。 事务表示一组动作&#xff0c;要么全部执行&#xff0c;要么全部不执行。例子如下。 Redis提供了简单的事务功能&#xff0c;讲一组需要一起执行的命令放到multi和exec两个命令之间。multi命令代表事务开始&#xff0c;exec命令代表事务结束&#x…...

从零到一构建短链接系统(八)

1.git上传远程仓库&#xff08;现在才想起来&#xff09; git init git add . git commit -m "first commit" git remote add origin OLiyscxm/shortlink git push -u origin "master" 2.开发全局异常拦截器之后就可以简化UserController 拦截器可以…...

缺省和重载。引用——初识c++

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 C输入&输出cout 和cin<<>> 缺省参数全缺省半缺省应用场景声明和定义分离的情况 函数重载1.参数的类型不同2.参数的个数不同3.参数的顺…...

java常用IO流功能——字符流和缓冲流概述

前言&#xff1a; 整理下学习笔记&#xff0c;打好基础&#xff0c;daydayup! 之前说了下了IO流的概念&#xff0c;并整理了字节流&#xff0c;有需要的可以看这篇 java常用应用程序编程接口&#xff08;API&#xff09;——IO流概述及字节流的使用 字符流 FileReader(文件字…...

Python中模块的定义、用法

在Python中&#xff0c;模块是一个包含了Python代码的文件。模块可以包含变量定义、函数、类等&#xff0c;并且可以在其他Python脚本中被导入和使用。模块的定义和用法如下所示&#xff1a; 模块的定义&#xff1a; 创建模块文件&#xff1a;在Python中&#xff0c;一个模块就…...

【vscode 常用扩展插件】

vscode 常用扩展插件 常用插件部分插件使用技巧1、eslint 保存自动格式化2、代码片段的使用3、最后是关于引入文件路径提示的 常用插件 记录vscode方便开发的扩展插件&#xff0c;方便换电脑时&#xff0c;快速部署所需环境。 部分插件 1、Auto Close Tag html自动闭合标签插…...

Retelling|Facebook2

录音 Facebook 2 Retelling|Facebook2 复述转写 Hi, Im Helen Campbell, from DJ interpretation, European Commission, Im going to talk about Facebook. You Im sure that you are more familiar with Facebook, a lot, a lot more familiar than I than me. But Ive read…...

读3dsr代码①测试

前置任务 首先是作者不公开checkpoints&#xff0c;需要自己训练一遍 这里先不载入模型单纯过一遍流程 而且因为没有说明是否需要去背景&#xff08;之后再过一下论文&#xff09;&#xff0c;所以反正先用去过背景的数据debug一下 3DSR/geo_utils.py:61: RuntimeWarning: inv…...

Vant Weapp小程序 van-uploader 文件上传点击无反应,删除无反应

Vant Weapp 1.0 版本开始支持van-uploader组件&#xff0c;请先确认好版本号和引用路径正确&#xff01;&#xff01; <van-uploader file-list"{{ fileList }}" deletable"{{ true }}" />1. 上传无反应 微信小程序用了van-uploader&#xff0c;但是…...

【力扣】55.跳跃游戏、45.跳跃游戏Ⅱ

55.跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&a…...

038—pandas 重采样线性插补

前言 在数据处理时&#xff0c;由于采集数据量有限&#xff0c;或者采集数据粒度过小&#xff0c;经常需要对数据重采样。在本例中&#xff0c;我们将实现一个类型超分辨率的操作。 思路&#xff1a; 首先将原始数据长度扩展为 3 倍&#xff0c;可以使用 loc[] 方法对索引扩…...

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示(PC端、手机端、平板端)

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示&#xff08;PC端、手机端、平板端&#xff09; 智慧工地系统多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三…...

深度学习Top10算法之深度神经网络DNN

深度神经网络&#xff08;Deep Neural Networks&#xff0c;DNN&#xff09;是人工神经网络&#xff08;Artificial Neural Networks&#xff0c;ANN&#xff09;的一种扩展。它们通过模仿人脑的工作原理来处理数据和创建模式&#xff0c;广泛应用于图像识别、语音识别、自然语…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...