本文共 7141 字,大约阅读时间需要 23 分钟。
在移动应用开发中,定位功能是非常实用的功能之一。现有的定位方式主要有两种:GPS定位和网络定位。
在Android系统中,定位功能的实现主要依赖于以下几个核心组件:
getSystemService(Context.LOCATION_SERVICE)获取LocationManager实例。LocationListener接口,实现对定位事件的响应处理。onLocationChanged(Location location):定位信息更新时的回调。onStatusChanged(String provider, int status, Bundle extras):定位提供商状态变化的回调。onProviderEnabled(String provider):定位提供商启用的回调。onProviderDisabled(String provider):定位提供商禁用的回调。requestLocationUpdates方法请求定位更新。LocationManager.NETWORK_PROVIDER:网络定位提供商。LocationManager.GPS_PROVIDER:GPS定位提供商。在使用定位功能时,需要注意以下几点:
NETWORK_PROVIDER,则需要申请ACCESS_COARSE_LOCATION权限。GPS_PROVIDER或同时使用两种定位方式,则需要申请ACCESS_FINE_LOCATION权限。android.hardware.location.networkandroid.hardware.location.gpsContextCompat.checkSelfPermission检查权限状态,并根据需要申请权限。在定位过程中,需要将获取到的经纬度坐标转换为具体的地址信息,可以使用Geocoder类完成。
Geocoder gc = new Geocoder(this, Locale.getDefault());
List locationList = gc.getFromLocation(latitude, longitude, 1);
以下是一个完整的定位功能实现示例:
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; @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); 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); 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); } // 其他回调方法(onStatusChanged、onProviderEnabled、onProviderDisabled)可以根据需要添加 }; } @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())); }} 通过上述内容可以看出,Android原生定位框架提供了一套完整的API,开发者可以根据实际需求选择合适的定位方式和定位提供商。在实现定位功能时,需要注意权限申请和使用的同时要确保定位服务的稳定性和用户体验的良好。
转载地址:http://dles.baihongyu.com/