Android手机定位

目录

一、定位功能准备

1.申请权限

2.开启定位所需功能

(1)定位

(2)WiFi

(3)移动数据连接(基站)

二、获取定位信息

1.定位条件器 Criteria

2.定位管理器 LocationManager

3.定位监听器 LocationListener

三、解析定位信息 Location

四、案例代码一览


Android的手机定位一般由卫星定位WiFi定位基站定位实现。卫星定位由几个全球卫星导航系统提供,主要包括美国GPS、俄罗斯格洛纳斯、中国北斗。WiFi定位一般通过接入公共WiFi,通过WiFi的MAC地址与电信网络宽带的网络IP,查询WiFi位置获取接入该WiFi的大致位置。基站定位是监测手机SIM卡能搜索到周围的哪些基站,手机必然处于它们信号的重叠位置。

一、定位功能准备

定位需要手机开启对应的功能;定位、无线网络(WiFi)、数据连接。

1.申请权限

定位操作需要获取权限;部分权限涉及用户隐私,需要动态申请。

<!--定位-->
<!--精准定位,一般通过卫星定位,需要动态申请权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--粗略定位,一般通过基站定位或WiFi定位,需要动态申请权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><!--查看网络状态-->
<!--数据网络状态,无需动态申请-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--WiFi网络状态,无需动态申请-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/><!--查看手机状态,需要动态申请-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

2.开启定位所需功能

(1)定位

使用LocationManager(定位管理器)获取定位功能状态。

//获取定位功能状态
public static boolean getGPSState(Context context){//获取定位管理器LocationManager locationManager= (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}//确认定位功能是否开启,未开启则跳转至定位功能设置界面
public static void checkGPSIsOpen(Context context){//未开启定位功能if(!getGPSState(context)){//跳转至定位功能设置界面Intent intent=new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);context.startActivity(intent);}
}

(2)WiFi

使用WiFiManager(WiFi管理器)获取WiFi状态及设置WiFi状态。

//获取WiFi状态
public static boolean getWiFiState(Context context){WifiManager wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);return wifiManager.isWifiEnabled();
}//设置WiFi状态
public static void setWiFiState(Context context,boolean state){WifiManager wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);wifiManager.setWifiEnabled(state);
}

(3)移动数据连接(基站)

使用ConnectivityManager(连接管理器)获取移动数据连接状态及设置连接状态;请注意因为是隐藏方法,需要通过反射调用。

//获取移动数据连接开关的状态
public static boolean getMobileDataState(Context context){//获取连接管理器ConnectivityManager connectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);boolean isOpen=false;try {//该方法为隐藏方法,需要通过反射调用String methodName="getMobileDataEnable";Method method=connectivityManager.getClass().getMethod(methodName);isOpen= (boolean) method.invoke(connectivityManager);}catch (Exception e){e.printStackTrace();}return isOpen;
}//设置移动数据连接开关的状态
public static void setMobileDataState(Context context,boolean state){//获取连接管理器ConnectivityManager connectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);try{//该方法为隐藏方法,需要通过反射调用String methodName="setMobileDataEnable";Method method=connectivityManager.getClass().getMethod(methodName);method.invoke(connectivityManager,state);}catch (Exception e){e.printStackTrace();}
}

二、获取定位信息

开启定位相关功能只是将定位的前提条件准备好,若想获得手机当前所处的位置信息,还要依靠一系列定位工具。与定位信息获取有关的工具有定位条件器Criteria定位管理器LocationManager定位监听器LocationListener

简单来说就是,通过设置好条件的定位条件器(Criteria)获取到最佳的定位信息提供者(String型数据),再向定位管理器添加定位监听器(LocationListener)及定位信息提供者。

下面对这3个工具分别进行介绍。

1.定位条件器 Criteria

定位条件器用于设置定位的前提条件,比如精度、速度、海拔、方位等信息。

有以下6个常用方法:

setAccuracy:设置定位精确度。有两个取值:

  • Criteria.ACCURACY_FINE 表示精度高。
  • Criteria.ACCURACY_COARSE表示精度低。

setSpeedAccuracy:设置速度精确度。速度精确度的取值如下:

  • ACCURACY_HIGH 精度高,误差小于100米
  • ACCURACY_MEDIUM 精度中等,误差在100米到500米之间
  • ACCURACY_LOW 精度低,误差大于500米

setAltitudeRequired:设置是否需要海拔信息。取值true表示需要,false表示不需要。

setBearingRequired:设置是否需要方位信息。取值true表示需要,false表示不需要。

setCostAllowed:设置是否允许运营商收费。取值true表示允许,false表示不允许。

setPowerRequirement:设置对电源的需求。有3个取值:

  • Criteria.POWER_LOW 耗电低
  • Criteria.POWER_MEDIUM 耗电中等
  • Criteria.POWER_HIGH 耗电高

2.定位管理器 LocationManager

定位管理器用于获取定位信息的提供者、设置监听器,并获取最近一次的位置信息。定位管理器的对象从系统服务LOCATION_SERVICE获取。常用方法有以下7个:

getBestProvider:获取最佳的定位提供者(String型数据)第一个参数为定位条件器Criteria的实例,第二个参数取值true表示只要可用的;在第二参数取true时,无有效定位提供者将返回null。建议第二参数参数false与监听器的onProviderDisabled和onProviderEnabled方法配合使用。定位提供者的取值(名称)说明如下:

  • gps 卫星定位,开启GPS功能
  • network 网络定位,开启数据连接或WLAN功能
  • passive 无法定位,未开启定位相关功能
  • fused 自动选择最佳定位方法

isProviderEnabled:判断指定的定位提供者是否可用。

getLastKnownLocation:获取最近一次的定位地点,返回值为Location对象,如无有效定位信息将返回null

requestLocationUpdates:设置定位监听器。其中,第一个参数为定位提供者(String型),第二个参数为位置更新的最小间隔时间,第三个参数为位置更新的最小距离,第四个参数为定位监听器实例。

removeUpdates:移除定位监听器。

addGpsStatusListener:添加定位状态的监听器。该监听器需实现GpsStatus.Listener 接口的onGpsStatusChanged方法

removeGpsStatusListener:移除定位状态的监听器。

3.定位监听器 LocationListener

定位监听器用于监听定位信息的变化事件,如定位提供者的开关、位置信息发生变化等。该监听器可使用以下4种方法。
onLocationChanged:在位置地点发生变化时调用。在此可获取最新的位置信息。
onProviderDisabled:在定位提供者被用户关闭时调用。

onProviderEnabled:在定位提供者被用户开启时调用。
onStatusChanged:在定位提供者的状态变化时调用。定位提供者的状态取值如下:

  • OUT_OF_SERVICE 在服务范围外
  • TEMPORARILY_UNAVAILABLE 暂时不可用
  • AVAILABLE 可用状态
//获取权限
int i=ActivityCompat.checkSelfPermission(MainActivity.this,"android.permission.ACCESS_FINE_LOCATION");
if(i!= PackageManager.PERMISSION_GRANTED){//无权限,请求权限requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"},1234);
}//创建定位条件器
Criteria criteria=new Criteria();
//设置精度,Criteria.ACCURACY_FINE表示精确,Criteria.ACCURACY_COARSE表示粗略
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//设置是否需要海拔信息
criteria.setAltitudeRequired(true);
//设置是否需要方位信息
criteria.setBearingRequired(true);
//设置是否允许运营商扣费
criteria.setCostAllowed(true);
//设置对电源的需求
criteria.setPowerRequirement(Criteria.POWER_LOW);//获取定位管理者
LocationManager locationManager= (LocationManager) getSystemService(LOCATION_SERVICE);
//获取最佳定位提供者;第二个参数表示是否只取可用的内容提供者
String locationProvider=locationManager.getBestProvider(criteria,true);//判断定位提供者是否有效
if(locationProvider!=null){//设置定位监听器;第一个参数为定位提供者,第二个参数为最小更新时间,第三个参数为最小更新距离,第四个参数为定位监听器locationManager.requestLocationUpdates(locationProvider, 300, 0, new LocationListener() {//定位发生变化时触发public void onLocationChanged(@NonNull Location location) {//解析Location对象中的数据}//定位提供者不可用时触发public void onProviderDisabled(@NonNull String provider) {}//定位提供者可用时触发public void onProviderEnabled(@NonNull String provider) {}//状态变更时触发public void onStatusChanged(String provider, int status, Bundle extras) {}});//获取最后的位置Location location=locationManager.getLastKnownLocation(locationProvider);}
else{//无有效定位提供者
}

三、解析定位信息 Location

通过LoactionManager对象使用getLastKnownLocation方法以及定位变化监听器可获取到Location型数据。

Location对象可使用以下方法解析数据:

  • getLatitude(): 返回位置的纬度。
  • getLongitude(): 返回位置的经度。
  • getAltitude(): 返回位置的海拔高度,如果没有海拔信息,则返回 0。
  • getAccuracy(): 返回位置的精确度。
  • getProvider(): 返回提供位置信息的服务的名称。
  • getTime(): 返回位置信息的时间戳。
  • hasAltitude(): 检查位置是否包含海拔信息。
  • hasSpeed(): 检查位置是否包含速度信息。
  • hasBearing(): 检查位置是否包含方向信息。
  • hasAccuracy(): 检查位置是否包含精确度信息。
  • distanceTo(Location dest): 计算当前位置到目标位置之间的距离。
  • bearingTo(Location dest): 计算当前位置到目标位置的方向。
  • setLatitude(double latitude): 设置位置的纬度。
  • setLongitude(double longitude): 设置位置的经度。
  • setAltitude(double altitude): 设置位置的海拔高度。
textView.setText("经度:"+location.getLongitude()+"纬度:"+location.getLatitude());

四、案例代码一览

public class MainActivity extends AppCompatActivity {private TextView textView = null;private Handler handler = null;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取控件textView = findViewById(R.id.textView);handler = new Handler(new Handler.Callback() {@SuppressLint("SetTextI18n")public boolean handleMessage(@NonNull Message message) {if (message.what == 123) {Bundle bundle = (Bundle) message.obj;//textView.setText("经度:" + bundle.getDouble("a1") + "纬度:" + bundle.getDouble("a2"));textView.setText("经度:"+bundle.getDouble("a1")+"\n纬度:"+bundle.getDouble("a2")+"\n海拔:"+bundle.getDouble("a3")+"\n方向:"+bundle.getFloat("a4")+"\nfrom: "+bundle.getString("a5")+"\n"+bundle.getLong("a6")+"\n"+bundle.getString("a7"));return true;}return false;}});//确认权限int i1 = ActivityCompat.checkSelfPermission(MainActivity.this, "android.permission.ACCESS_FINE_LOCATION");if (i1 != PackageManager.PERMISSION_GRANTED) {//无权限,申请权限requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"}, 1);} else {//有权限beginLocation(MainActivity.this);}}@SuppressLint("SetTextI18n")public void beginLocation(Context context) {//准备定位条件器Criteria criteria = new Criteria();criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度criteria.setPowerRequirement(Criteria.POWER_HIGH);criteria.setCostAllowed(true);criteria.setAltitudeRequired(true);//海拔criteria.setBearingRequired(true);//方向//获取定位管理器LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);//获取最佳定位提供者String provider = locationManager.getBestProvider(criteria, true);if (provider != null) {//添加监听器if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {// TODO: Consider calling//    ActivityCompat#requestPermissions// here to request the missing permissions, and then overriding//   public void onRequestPermissionsResult(int requestCode, String[] permissions,//                                          int[] grantResults)// to handle the case where the user grants the permission. See the documentation// for ActivityCompat#requestPermissions for more details.return;}Log.d("OK","定位提供者为"+provider);locationManager.requestLocationUpdates(provider, 300, 0, new LocationListener() {Location oldLocation=null;public void onLocationChanged(@NonNull Location location) {if (location != null) {oldLocation=location;Message message = new Message();message.what = 123;Bundle bundle = new Bundle();bundle.putDouble("a1", location.getLongitude());bundle.putDouble("a2", location.getLatitude());bundle.putDouble("a3",location.getAltitude());bundle.putFloat("a4",location.getBearing());bundle.putString("a5",location.getProvider());bundle.putLong("a6",location.getTime());SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date=f.format(location.getTime());bundle.putString("a7",date);message.obj = bundle;handler.sendMessage(message);}}public void onProviderDisabled(@NonNull String provider) {textView.setText("定位关停 - "+provider);}@Overridepublic void onProviderEnabled(@NonNull String provider) {textView.setText("定位启动 - "+provider);onLocationChanged(oldLocation);}});//获取最后结果Location location=locationManager.getLastKnownLocation(provider);if(location!=null){SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String date=f.format(location.getTime());textView.setText("经度:"+location.getLongitude()+"\n纬度:"+location.getLatitude()+"\n海拔:"+location.getAltitude()+"\n方向:"+location.getBearing()+"\nfrom: "+location.getProvider()+"\n"+date);}else{textView.setText("无定位信息");}}else {textView.setText("定位功能未开启");}}public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if(requestCode==1){for(int i=0;i<permissions.length;i++){if(grantResults[i]!=PackageManager.PERMISSION_GRANTED){requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"},1);return;}}beginLocation(MainActivity.this);}}
}

tag:定位;Location;基站定位;WiFi定位

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/739737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv5目标检测学习(4):YOLOV5源码的文件结构解析

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言①py、cpp、java后缀的文件②md、txt、yml后缀的文件③yaml后缀的文件 一、.github文件夹1.1 workflows文件夹&#xff1a;该文件夹通常包含GitHub Actions 的工…

Python基础语法:基本数据类型(列表)

现实世界中总是存在一组一组的事物。"组"的概念作为基本数据类型的一种&#xff0c;它也是来源于我们去解决现实生活中的一些问题而产生的。它需要有“组”这样的一个数据类型来丰富我们的基本数据类型。 那么在Python中如何来表示“组”的概念呢&#xff1f; 在Py…

RHEL9 DNF/YUM仓库管理软件包

DNF/YUM仓库管理软件包 一个基于RPM包的软件包管理器能够从指定的服务器自动下载RPM包并且安装&#xff0c;自动处理依赖性关系&#xff0c;并且一次性安装所有依赖的软件包C/S模式 Server服务端提供RPM软件包与数据库文件repodataClient客户端使用dnf仓库 常用组合 组合参…

解决Klipper下位机ID获取失败问题

使用硬件&#xff1a; 上位机&#xff1a;必趣派&#xff0c;版本CB1_Debian11_Klipper_kernel5.16_20230303 下位机&#xff1a;八爪鱼STM32F407 问题&#xff1a;上位机获取下位机ID失败。 解决&#xff1a;咨询DIY群友&#xff0c;也对这个问题不太了解。我调试过程中&…

Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 4-1、线条平滑曲面(原始图形)

环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 代码: import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata fro…

SPI学习笔记

总线介绍 SPI&#xff0c;是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外设接口。SPI协议主要作为主控芯片去配置外围芯片的接口协议。SPI接口主要应用在 EEPROM&#xff0c;FLASH&#xff0c;实时时钟&#xff0c;AD转换器&#xff0c;还有数字信号…

【vivado】 clock wizard 时钟IP

一、前言 MMCM和PLL是在FPGA设计中不可避免需要使用到的时钟资源&#xff0c;对于其功能及使用方法的理解是正确进行FPGA设计的前提。 二、Xilinx 时钟 IP配置 vivado中使用时钟向导(Clocking Wizard)配置时钟IP核&#xff0c;其框图如下&#xff1a; clk_in 输入时钟&#…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的的商品标签识别系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发商品标签识别系统在提升零售业运营效率和顾客购物体验中发挥着关键作用。本篇博客详细阐述了如何应用深度学习技术构建此类系统&#xff0c;并提供了完整的代码实现。该系统基于高效的YOLOv8算法&#xff0c;并与YOLOv7、YOLOv6、YOLOv5进行了性能对比&…

*Javaweb -- MyBatis*

一:介绍: 1.MyBatis是一个优秀的 ①持久层 ②框架,用于简化JDBC的开发! ①:JAVAEE有三层的结构:表现层, 业务层, 持久层. 表现层代表的是页面的展示,业务层则指的是对于相关逻辑的处理, 而持久层, 指的则是对于数据进行持久化,保存在数据库当中. 持久层具体的来说就是负责…

数字孪生+工业互联网标识解析,打造智能工厂新标杆!

当前&#xff0c;工业4.0浪潮愈发澎湃&#xff0c;加快数字化、网络化、智能化发展成为了制造业转型升级的必然要求。 51WORLD基于数字孪生技术与工业互联网标识解析体系&#xff0c;打造了一个集协同化供应、个性化定制、智能化生产于一体的全连接产线孪生平台&#xff08;以…

antv L7结合高德地图使用dome1

antv L7结合高德地图使用 一、设置底图二 、添加antv L7 中要使用的dome1. 安装L7 依赖2. 使用的dome 、以下使用的是浮动功能3. 运行后显示 自定义样式修改1. 设置整个中国地图浮动起来 自定义标注点1. 静态标注点2. 动态标注点&#xff08;点位置需要自己改&#xff09;3. 完…

Python笔记:函数

Python函数定义规则&#xff1a; 函数代码块以def关键词开头&#xff0c;后接函数标识符名称和圆括号()。任何传入参数和自变量必须放在圆括号中间&#xff0c;圆括号之间可以用于定义参数。return [表达式] 结束函数&#xff0c;选择性地返回一个值给调用方&#xff0c;不带表…

Windows系统中安装docker及镜像加速的配置

文章目录 一.安装wsl二.下载docker desktop三.更换Docker镜像引用出处 一.安装wsl 在安装wsl之前&#xff0c;先在Windows中配置WSL环境,步骤很简单&#xff0c;按照以下文章进行 Windows10/11配置WSL(Ubuntu)环境 以管理员身份打开Windows PowerShell&#xff0c;执行以下命…

模型驱动架构MDA

MDE 模型驱动工程&#xff08;MDE, Model-Driven Engineering&#xff09;是软件工程的一个分支&#xff0c;它将模型与建模拓展到软件开发的所有方面&#xff0c;形成一个多维建模空间&#xff0c;从而将工程活动建立在这些模型的映射和转换之上。[1] MDE的基本原则是将模型视…

2.Windows平台Python的下载、安装和配置环境变量——跟老吕学Python编程

2.Windows平台Python的下载、安装和配置环境变量——跟老吕学Python编程 一、下载Windows版Python1.Python官网2.Windows版Python下载网址 二、在Windows安装Python1.全自动安装Python&#xff08;不推荐&#xff09;1.1 启动安装1.2 安装进度1.3 安装完成1.4 查看版本 2.自定义…

Python sort从大到小排序面试题

在Python中&#xff0c;你可以使用内置的sorted()函数或者列表的sort()方法来对列表中的元素进行从大到小的排序。 使用sorted()函数&#xff1a; numbers [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] sorted_numbers sorted(numbers, reverseTrue) # 设置reverseTrue实现从大到小排…

基于单片机的智能水位监控识别系统设计

摘 要:本文通过描述以STC12C5A60S2单片机作为MCU的智能水位监控系统的设计进行分析,对系统中的各电路原理进行简单概述,将系统通过液晶进行人机交互,并可通过按键对水位上下限进行调整,采用超声波检测模块对水位检测并具有水位情况预警功能。系统经过智能化的排水和注水操…

【GO】HTTP标准库1 - http协议基础知识

目录 一 http协议 1 http协议 2 http request 3 请求方法 4 URL 5 协议版本 6 请求头 7 Content-type 9 POST与GET区别 10 HTTP Response 11 常见的状态与话术 12 HTTP 响应头 13 完整的HTTP响应 14 HTTPS 一 http协议 1 http协议 HTTP&#xff08;HyperText Tra…

Kubeadm部署K8s

Kubeadm部署K8s 集群规划&#xff1a; Master节点规划: Node节点规划: 安装要求 在开始之前&#xff0c;部署Kubernetes集群机器需要满足以下几个条件&#xff1a; 操作系统 CentOS7.x-86_x64 硬件配置&#xff1a;2GB或更多RAM&#xff0c;2个CPU或更多CPU&#xff0c;硬盘…

CANopen转Profinet网关连接西门子PLC与变流器通讯

CANopen转Profinet网关&#xff08;XD-COPNm20&#xff09;在智能领域&#xff0c;变流器的应用非常广泛&#xff0c;变流器一般会采用CANopen协议。现场采用台达的变流器&#xff08;支持CANopen协议&#xff09;作为CANopen从站&#xff0c;S7-1500系列PLC做主站&#xff0c;…