有两种定位的方式:
1.基于GPS定位;
2.基于网络定位。
GPS定位的 好处 :精确度高; 坏处 :仅能在户外使用,获取定位信息速度慢,耗费电池。
网络定位的 好处 :户内户外都能使用,定位速度快,电量耗费低; 坏处 :精确度不太高。
android原生定位框架的核心组件是
LocationManager
系统服务,获取这个组件并不需要实例化,通常是通过函数
getSystemService(Context.LOCATION_SERVICE)
获得,该函数会返回一个LocationManager的实例,示例代码如下:
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
LocationListener
通过回调(callback)来获取用户定位信息
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
// 这个函数中的location就是获取到的位置信息
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
同时我们需要调用函数
requestLocationUpdates
绑定
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
定位功能的使用需要获取定位权限
如果使用 NETWORK_PROVIDER
,那么需要请求
android.permission.ACCESS_COARSE_LOCATION
如果使用 GPS_PROVIDER
或者同时使用上述两种定位方式,那么需要请求
android.permission.ACCESS_FINE_LOCATION
同时,如果你的app的运行环境是Android 5.0(API Level 21)或更高(If your app targets Android 5.0 (API level 21) or higher),那么你还需要显式请求
Geocoder可以将一个地址转变为经纬度,或者将经纬度转变为地址。android.hardware.location.network
或者
android.hardware.location.gps
package com.example.demo;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class LocationActivity extends Activity implements View.OnClickListener {
private static final String TAG = LocationActivity.class.getSimpleName();
private LocationManager locationManager;
private LocationListener locationListener;
private TextView tv;
private Button btnStart;
private Button btnEnd;
private Button btnClean;
private StringBuilder stringBuilder = new StringBuilder();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
setTitle("原生定位");
tv = findViewById(R.id.tv);
btnStart = findViewById(R.id.btnStart);
btnEnd = findViewById(R.id.btnEnd);
btnClean = findViewById(R.id.btnClean);
btnStart.setOnClickListener(this);
btnEnd.setOnClickListener(this);
btnClean.setOnClickListener(this);
//设置文字太长时TextView可以上下滑动
tv.setMovementMethod(ScrollingMovementMethod.getInstance());
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
stringBuilder.append(getTime()).append("\t定位信息:\n");
stringBuilder.append("\t").append(location.getLatitude()).append("\n");
stringBuilder.append("\t").append(location.getLongitude()).append("\n");
stringBuilder.append("\t").append(location.getProvider()).append("\n");
tv.setText(stringBuilder);
Geocoder gc = new Geocoder(LocationActivity.this, Locale.getDefault());
List locationList = null;
try {
locationList = gc.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
Address address = locationList.get(0);//得到Address实例
if (address == null) {
return;
}
stringBuilder.append(getTime()).append("\t地址信息:\n");
String countryName = address.getCountryName();//得到国家名称
if (!TextUtils.isEmpty(countryName)) {
stringBuilder.append(countryName);
}
String adminArea = address.getAdminArea();//省
if (!TextUtils.isEmpty(adminArea)) {
stringBuilder.append(adminArea);
}
String locality = address.getLocality();//得到城市名称
if (!TextUtils.isEmpty(locality)) {
stringBuilder.append(locality);
}
for (int i = 0; address.getAddressLine(i) != null; i++) {
String addressLine = address.getAddressLine(i);
if(!TextUtils.isEmpty(addressLine)) {
if(addressLine.contains(countryName)){
addressLine = addressLine.replace(countryName,"");
}
if(addressLine.contains(adminArea)){
addressLine = addressLine.replace(adminArea,"");
}
if(addressLine.contains(locality)){
addressLine = addressLine.replace(locality,"");
}
if(!TextUtils.isEmpty(addressLine)) {
stringBuilder.append(addressLine);
}
}
}
String featureName = address.getFeatureName();//得到周边信息
if(!TextUtils.isEmpty(featureName)) {
stringBuilder.append(featureName).append("\n");
}
tv.setText(stringBuilder);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
stringBuilder.append(getTime()).append("\t开始定位\n");
tv.setText(stringBuilder);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED) {
return;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
break;
case R.id.btnEnd:
locationManager.removeUpdates(locationListener);
stringBuilder.append(getTime()).append("\t结束定位\n\n");
tv.setText(stringBuilder);
break;
case R.id.btnClean:
stringBuilder.delete(0, stringBuilder.length());
tv.setText(stringBuilder);
break;
default:
break;
}
}
private String getTime() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.getDefault());
return simpleDateFormat.format(new Date(System.currentTimeMillis()));
}
}