Android手机定位

365bet体育在线网站 📅 2025-07-13 20:06:11 ✍️ admin 👁️ 3369 ❤️ 199
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卡能搜索到周围的哪些基站,手机必然处于它们信号的重叠位置。该功能由定位管理器LocationManager控制。

一、定位功能准备

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

1.申请权限

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

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);

}

@Override

public 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

if(grantResults[i]!=PackageManager.PERMISSION_GRANTED){

requestPermissions(new String[]{"android.permission.ACCESS_FINE_LOCATION"},1);

return;

}

}

beginLocation(MainActivity.this);

}

}

}

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

相关推荐

神武捐装备攻略-神武捐装备捐多少级的好
bt365体育网址

神武捐装备攻略-神武捐装备捐多少级的好

📅 07-10 👁️ 3192
中文界面的EXE文件编辑工具使用指南
bt365体育网址

中文界面的EXE文件编辑工具使用指南

📅 07-07 👁️ 6662
苹果数据线多少钱(苹果数据线价格大比拼,你知道最划算的是哪款?)