显示位置地址
一旦有了Location对象,就可以使用Geocoder.getFromLocation()方法来获取给定纬度和经度的地址。此方法是同步的,可能需要很长时间才能完成工作,因此您应该从AsyncTask类的doInBackground()方法中调用该方法。该AsyncTask必须被继承使用和子类将覆盖doInBackground(参数...)方法在后台执行任务onPostExecute(结果)方法被调用的后台计算结束后的UI线程,并在时间显示结果。AyncTask中还有一个更重要的方法execute(Params ... params),该方法使用指定的参数执行任务。
以下示例以实用方式向您展示了如何在应用中使用定位服务来获取当前位置及其等效地址等。
要尝试此示例,您将需要配备最新Android OS的实际移动设备,否则,您将不得不使用可能无法工作的仿真器。
- 您将使用Android Studio IDE创建一个Android应用程序,并在com.example.demo包下将其命名为Demo。
- 添加src/GPSTracker.java文件并添加所需的代码。
- 修改src/MainActivity.java文件如下所示,以确保获取当前位置及其等效地址。
- 修改布局XML文件res/layout/activity_main.xml添加所有GUI组件,其中包括三个按钮和两个文本视图以显示位置/地址。
- 运行该应用程序以启动Android模拟器并验证在该应用程序中所做更改的结果。
以下是修改后的主要活动文件src/com.jc2182.demo/MainActivity.java的内容。该文件可以包括每个基本生命周期方法。
package com.jc2182.demo;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
public class MainActivity extends Activity {
Button btnShowLocation;
private static final int REQUEST_CODE_PERMISSION = 2;
String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;
// GPSTracker 类
GPSTracker gps;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{mPermission}, REQUEST_CODE_PERMISSION);
// 如果用户不允许以上任何权限,此条件将每次执行,否则您的其他部分将正常工作
}
} catch (Exception e) {
e.printStackTrace();
}
btnShowLocation = (Button) findViewById(R.id.button);
// 显示位置按钮单击事件
btnShowLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// create class object
gps = new GPSTracker(MainActivity.this);
// 检查 GPS 是否可用
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
Toast.makeText(getApplicationContext(), "您的位置是 - \n纬度: "
+ latitude + "\n经度: " + longitude, Toast.LENGTH_LONG).show();
}else{
// 不能获取位置
// GPS 或者网络 不可用
// 要求用户在设置中启用GPS /网络
gps.showSettingsAlert();
}
}
});
}
}
以下是文件src/com.jc2182.demo/GPSTracker.java
package com.jc2182.demo;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// GPS 状态标识
boolean isGPSEnabled = false;
// 网络状态标识
boolean isNetworkEnabled = false;
// 位置状态标识
boolean canGetLocation = false;
Location location; // 位置
double latitude; // 纬度
double longitude; // 经度
// 更改的最小距离更新以米为单位
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 米
// 更新之间的最短时间(以毫秒为单位)
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 一分钟
// 声明位置管理器
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// 获取 GPS 状态
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// 获取网络状态
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
//没有启用网络提供商
} else {
this.canGetLocation = true;
// 首先从网络提供商获取位置
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null) {
location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// 如果启用GPS,则使用GPS服务获取经纬度
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null) {
location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* 获取纬度
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
return latitude;
}
/**
* 获取经度
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* 检查GPS/WIFI是否可用
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* 显示设置警报对话框的功能按下“设置”按钮将启动“设置选项”
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS设置");
// Setting Dialog Message
alertDialog.setMessage("GPS未启用。 您要进入设置菜单吗?");
// On pressing Settings button
alertDialog.setPositiveButton("设置", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
以下是res/layout/activity_main.xml文件的内容-
<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"
android:orientation = "vertical" >
<Button
android:id = "@+id/button"
android:layout_width = "fill_parent"
android:layout_height = "wrap_content"
android:text = "获取位置"/>
</LinearLayout>
让我们尝试运行刚刚修改的应用程序。我假设您在进行环境设置时已创建了AVD。要从Android Studio运行该应用,请打开您项目的活动文件之一,然后工具栏中单击“运行”图标。Android studio将应用程序安装在您的AVD上并启动它,如果设置和应用程序一切正常,它将显示在“模拟器”窗口下面-
点击“获取位置”按钮,看到如下(您应该在真机中测试该Demo)。