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

Android 原生定位开发(解决个别手机定位失败问题)


文章目录

  • 前言
  • 一、实现步骤
  • 二、使用步骤
    • 1.服务启动工具类
    • 2.实现LocationService
  • 总结


前言

在android开发中地图和定位是很多软件不可或缺的内容,这些特色功能也给人们带来了很多方便。定位一般分为三种发方案:即GPS定位、Google网络定位以及基站定位。


本文分别介绍GPS定位、以及基于Google的网络Wifi定位的详细步骤,(小米手机获取位置信息locationManager.getLastKnownLocation(provider)的Location一直为空,查了资料换了种获取手机getProviders的方式就可以了)

一、实现步骤

一般来说我们实现原生定位的流程大概是:先判断有无权限》有权限启动一个LocationSrevice去获取定位》最后携带所需的定位信息返回,进行开发。

二、使用步骤

1.服务启动工具类

代码如下(示例):大概步骤如下,权限请求可自定义开发关键的是LocationService

/*** 获取定位*/
public class MyLocationManager implements LocationService.LocationCallBack {private Activity context;private OnLocationListener onLocationListener;private String[] stringsLocation = new String[]{Permission.ACCESS_FINE_LOCATION, Permission.ACCESS_COARSE_LOCATION};@Overridepublic void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName) {onLocationListener.OnLocation(Location_latitude, Location_longitude, province, city, area, featureName);}public interface OnLocationListener {void OnLocation(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);}public void setOnLocationListener(OnLocationListener onLocationListener) {this.onLocationListener = onLocationListener;}public MyLocationManager(@NonNull Activity context) {this.context = context;if (!XXPermissions.isGranted(context, stringsLocation)) {MessageDialog codeDialog = new MessageDialog(context, "位置信息权限使用说明", "为确保你能在******内使用位置信息******,******需要获取你的位置信息权限。允许后,你可以随时通过手机系统设置对授权进行管理。", "取消", "去授权");codeDialog.setCancelable(false);codeDialog.show();codeDialog.setOnSumbitTextCodeListener(() -> {doMainPermission();codeDialog.dismiss();});codeDialog.setOnCancelListener(() -> {codeDialog.dismiss();});} else {initData();}}private void doMainPermission() {XXPermissions.with(context).permission(stringsLocation).request(new OnPermissionCallback() {@Overridepublic void onGranted(@NonNull List<String> permissions, boolean allGranted) {if (allGranted) {initData();}}@Overridepublic void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {if (doNotAskAgain) {}}});}@SuppressLint("MissingPermission")private void initData() {// 创建 Service 实例LocationService myService = new LocationService();// 设置回调接口myService.setCallback(this);// 启动 Service 并执行操作Intent serviceIntent = new Intent(context, LocationService.class);context.startService(serviceIntent);}
}
/**-------------------------/
不要忘了注册<serviceandroid:name=".utils.LocationService"android:enabled="true"android:exported="false" />

2.实现LocationService

代码如下(示例):

/*** 获取定位服务*/
public class LocationService extends Service {private LocationManager locationManager;private MyLocationListener myLocationListener;public static LocationCallBack mCallBack = null;public interface LocationCallBack {void Location_Return(double Location_latitude, double Location_longitude, String province, String city, String area, String featureName);}public void setCallback(LocationCallBack callback) {this.mCallBack = callback;}@Overridepublic IBinder onBind(Intent intent) {return null;}@SuppressLint("MissingPermission")@Overridepublic void onCreate() {super.onCreate();myLocationListener = new MyLocationListener();locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);try {GPSLocation();} catch (Exception e) {if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务stopSelf();  // 获取到经纬度以后,停止该service}}class MyLocationListener implements LocationListener {// 位置改变时获取经纬度@Overridepublic void onLocationChanged(Location location) {if (ObjectUtils.isNotEmpty(location)) {toGeocoder(location);}}// 状态改变时@Overridepublic void onStatusChanged(String provider, int status, Bundle extras) {}// 提供者可以使用时@Overridepublic void onProviderEnabled(String provider) {}// 提供者不可以使用时@Overridepublic void onProviderDisabled(String provider) {}}@SuppressLint("MissingPermission")private Location getLastKnownLocation(LocationManager locationManager) {List<String> providers = locationManager.getProviders(true);Location bestLocation = null;for (String provider : providers) {Location l = locationManager.getLastKnownLocation(provider);if (l == null) {continue;}if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {bestLocation = l;}}return bestLocation;}@SuppressLint("MissingPermission")private void GPSLocation() {Location location = getLastKnownLocation(locationManager);if (location != null) {//不为空,显示地理位置经纬度String longitude = "Longitude:" + location.getLongitude();String latitude = "Latitude:" + location.getLatitude();LogUtils.e("Location:" + longitude + latitude);toGeocoder(location);} else {LogUtils.e("Location:" + "Location为空");if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务stopSelf();  // 获取到经纬度以后,停止该service}}@SuppressLint("MissingPermission")private void toGeocoder(Location location) {String province = "";String city = "";String area = "";String featureName = "";try {Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);if (ObjectUtils.isNotEmpty(addresses) && 0 < addresses.size()) {Address address = addresses.get(0);if (ObjectUtils.isNotEmpty(address)) {// 获取省份(province)province = address.getAdminArea();// 获取城市(City)city = address.getLocality();// 获取区县(area)area = address.getSubLocality();//  获取详细地址featureName = address.getFeatureName();// 获取街道地址String addressLine = address.getAddressLine(0);// 打印详细地址信息LogUtils.e("AddressInfo", "province: " + province);LogUtils.e("AddressInfo", "City: " + city);LogUtils.e("AddressInfo", "area: " + area);LogUtils.e("AddressInfo", "FeatureName: " + featureName);LogUtils.e("AddressInfo", "Address Line: " + addressLine);}mCallBack.Location_Return(location.getLatitude(), location.getLongitude(), province, city, area, featureName);}if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务stopSelf();  // 获取到经纬度以后,停止该service} catch (Exception e) {if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务stopSelf();  // 获取到经纬度以后,停止该servicee.printStackTrace();}}@SuppressLint("MissingPermission")@Overridepublic void onDestroy() {super.onDestroy();if (ObjectUtils.isNotEmpty(locationManager) && ObjectUtils.isNotEmpty(myLocationListener))locationManager.removeUpdates(myLocationListener); // 停止所有的定位服务stopSelf();}}

该处使用原生定位获取经纬度、省市县等数据的详细步骤。


总结

以上就是今天要讲的使用Android原生获取定位内容,本文详细展现了完整流程,希望对大家会有帮助,公司如果有实力大可不必如此,直接给第三方地图交钱就好了,毕竟人家又快又准(本文仅仅适用于只需经纬度或者地址信息的同学,有地图展现需求的只能想别的方法了哈哈)。

相关文章:

Android 原生定位开发(解决个别手机定位失败问题)

文章目录 前言一、实现步骤二、使用步骤1.服务启动工具类2.实现LocationService 总结 前言 在android开发中地图和定位是很多软件不可或缺的内容&#xff0c;这些特色功能也给人们带来了很多方便。定位一般分为三种发方案&#xff1a;即GPS定位、Google网络定位以及基站定位。…...

uni-app 中如何实现数据组件间传递?

在 uni-app 中&#xff0c;实现数据组件间传递可以使用 Props 或 Vuex。 Props 是一种组件通信的方式&#xff0c;通过向子组件传递数据来实现组件间的数据传递。下面是一个示例&#xff1a; 父组件&#xff1a; <template><child :message"hello">&l…...

SpringBoot整合自签名SSL证书,转变HTTPS安全访问(单向认证服务端)

前言 HTTP 具有相当优秀和方便的一面,然而 HTTP 并非只有好的一面&#xff0c;事物皆具两面性&#xff0c;它也是有不足之处的。例如&#xff1a; 通信使用明文&#xff08;不加密&#xff09;&#xff0c;内容可能会被窃听。不验证通信方的身份&#xff0c;因此有可能会遭遇…...

k8s:endpoint

在 Kubernetes 中&#xff0c;Endpoint 是一种 API 对象&#xff0c;它用于表示集群内某个 Service 的具体网络地址。换句话说&#xff0c;它连接到一组由 Service 选择的 Pod&#xff0c;从而使它们能够提供服务。每个 Endpoint 对象都与相应的 Service 对象具有相同的名称&am…...

最新版星火官方搬运工具6.0,高级搬运,100%过原创,短视频上热门搬运软件黑科技【搬运脚本+使用技术教程】

软件介绍&#xff1a; 高级搬运&#xff0c;条条过原创 短视频暴力热门搬运黑科技 自研摄像头内录突破性技术6.0 无需任何繁琐准备工作安装即用 无需复杂售后培训看教程即可学会 直装直用自研技术更好卖 无需root 无需框架 更方便 无需xposed 无需vcam更安全 适配99%以…...

轧钢厂安全生产方案:AI视频识别安全风险智能监管平台的设计

一、背景与需求 轧钢厂一般都使用打包机对线材进行打包作业&#xff0c;由于生产需要&#xff0c;人员需频繁进入打包机内作业&#xff0c;如&#xff1a;加护垫、整包、打包机检修、调试等作业。在轧钢厂生产过程中&#xff0c;每个班次生产线材超过300件&#xff0c;人员在一…...

Linux Dotnet 程序堆栈监控

# 查看进程 dotnet-stack ps #显示如下2014067 dotnet /usr/share/dotnet/dotnet k1 --LogLevel4 2014087 dotnet /usr/share/dotnet/dotnet --LogLevel4 2014089 dotnet /usr/share/dotnet/dotnet --LogLevel4 # 根据PID查看这个进程每个线程的堆栈 dotnet-stack repor…...

后端设计PG liberty的作用和增量式生成

Liberty&#xff08;俗称LIB和DB&#xff09;&#xff0c;是后端设计中重要的库逻辑描述文件&#xff0c;这里边包含了除过physical&#xff08;当然也有一点点涉及&#xff09;以外所有的信息&#xff0c;对整个后端设计实现有非常大的作用。借此机会&#xff0c;一起LIB做一个…...

Linux 安装 RocketMq

RocketMq是阿里出品&#xff08;基于MetaQ&#xff09;的开源中间件&#xff0c;已捐赠给Apache基金会并成为Apache的顶级项目。基于java语言实现&#xff0c;十万级数据吞吐量&#xff0c;ms级处理速度&#xff0c;分布式架构&#xff0c;功能强大&#xff0c;扩展性强。 官网…...

大数据Doris(十六):Doris表的数据划分

文章目录 Doris表的数据划分 一、Partition 二、 Bucket 三、PROPERTIES 四、 ENGINE Doris表的数据划分 Doris支持单分区和复合分...

管理文件:文件批量重命名,轻松删除文件名中的空格

在文件管理中&#xff0c;我们经常会遇到文件名中带有空格的情况。这些空格可能会使文件在某些情况下难以被正确识别或使用&#xff0c;因此我们需要掌握一些技巧来轻松删除文件名中的空格。现在使用云炫文件管理器批量重命名进行批量处理。以下是如何操作的步骤详解&#xff1…...

Docker容器技术实战3

8、docker原生网络 Docker原生网络基于Linux桥接技术和虚拟网络接口&#xff0c;使用了Linux内核的网络功能。每个Docker容器都有自己的网络命名空间&#xff0c;这使得容器之间可以使用独立的IP地址&#xff0c;并隔离了容器的网络栈。 当创建一个Docker原生网络时&#xff…...

数字处理-第10届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第3讲。 数字处理&#xff…...

Go并发编程

一、goroutine 和 通道 在Go语言中&#xff0c;每一个并发执行的活动成为goroutine。通道则是每一个goroutine之间传递消息的工具。 1、Goroutine 在一个Go程序中&#xff0c;只有一个主Goroutine来调用main函数。生成新的goroutine也十分简单&#xff0c;例如有一个函数&…...

Nignx及负载均衡动静分离

核心要点&#xff1a;部署后台项目 1.配置jdk环境 1.先将jdk的Linux版本的压缩包上传虚拟机中服务器 2.解压上传的jdk压缩包 tar -zxvf jdk.gz 3.先进入jdk的解压目录&#xff0c;再通过pwd查看当前解压包的路径 4.将 解压包路径 配置到 /etc/profile 5…...

HDFS架构介绍

数新网络_让每个人享受数据的价值浙江数新网络有限公司是一家开源开放、专注于云数据智能操作系统和数据价值流通的服务商。公司自主研发的DataCyber云数据智能操作系统&#xff0c;主要包括数据平台CyberData、人工智能平台CyberAI、数据智能引擎CyberEngine、数据安全平台Cyb…...

微信小程序提示确认框 wx.showModal

核心实现代码如下 wx.showModal({ title: 确认, content: 确定要删除吗&#xff1f;, success (res) { if (res.confirm) { console.log(用户点击确定) } else if (res.cancel) { console.log(用户点击取消) } } })title 是确认框的标题&#xff0c;content 是确认…...

如何设置OBS虚拟摄像头给钉钉视频会议使用

环境&#xff1a; OBS Studio 29.1.3 Win10 专业版 钉钉7.1.0 问题描述&#xff1a; 如何设置OBS虚拟摄像头给钉钉视频会议使用 解决方案&#xff1a; 1.打开OBS 底下来源这添加视频采集设备 选择OBS虚拟摄像头 2.源那再建一个图像&#xff0c;随便选一张图片 3.点击虚…...

SpringCloud 微服务全栈体系(十一)

第十章 RabbitMQ 三、SpringAMQP SpringAMQP 是基于 RabbitMQ 封装的一套模板&#xff0c;并且还利用 SpringBoot 对其实现了自动装配&#xff0c;使用起来非常方便。 SpringAmqp 的官方地址&#xff1a;https://spring.io/projects/spring-amqp SpringAMQP 提供了三个功能&…...

45基于matlab的ARIMA:AutoregressiveIntegratedMovingAverage model。

基于matlab的ARIMA&#xff1a;AutoregressiveIntegratedMovingAverage model。自回归差分移动平均模型(p,d,q)&#xff0c;AR自回归模型&#xff0c;MA移动平均模型&#xff0c;时间序列模型步骤包括&#xff1a;1. 数据平稳性检验&#xff1b;2. 确定模型参数&#xff1b;3. …...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...