如何按经纬度获取android的城市信息
How to get city information in android by longitude and latitude
我正在制作 android 应用程序。我在获取位置方面遇到了一些问题。
在我的代码中,我让我的应用程序通过 GPS 获取经度和纬度。但是,我一直无法通过经度和纬度获取城市名称。我不知道为什么我的代码会出现异常,即使我的代码中没有任何错误。
这是我获取城市名称的代码
ackage org.androidtown.getcurrentlocation;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GetCurrentLocation extends AppCompatActivity implements View.OnClickListener {
private LocationManager locationManager = null;
private LocationListener locationListener = null;
private Button btnGetLocation = null;
private EditText editLocation = null;
private ProgressBar pb = null;
private static final String TAG = "Debug";
private Boolean flag = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_current_location);
pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setVisibility(View.INVISIBLE);
editLocation = (EditText) findViewById(R.id.editTextLocation);
btnGetLocation = (Button) findViewById(R.id.btnLocation);
btnGetLocation.setOnClickListener(this);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
public void onClick(View v) {
flag = displayGpsStatus();
if (flag) {
Log.v(TAG, "onClick");
editLocation.setText("Please!! move your device to see the changes in coordinates.\nWait..");
pb.setVisibility(View.VISIBLE);
locationListener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {return;}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
}
else{
alertbox("GPS Status!!", "Your GPS is : OFF");
}
}
private Boolean displayGpsStatus(){
ContentResolver contentResolver = getBaseContext().getContentResolver();
boolean gpsStatus = Settings.Secure.isLocationProviderEnabled(contentResolver, LocationManager.GPS_PROVIDER);
if(gpsStatus){
return true;
}
else{
return false;
}
}
protected void alertbox(String title, String mymessage){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your Device's GPS is Disable").setCancelable(false).setTitle("**GPS Status**").setPositiveButton("Gps On", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
Intent myIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
startActivity(myIntent);
dialog.cancel();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private class MyLocationListener implements LocationListener{
@Override
public void onLocationChanged(Location loc){
editLocation.setText("");
pb.setVisibility(View.INVISIBLE);
Toast.makeText(getBaseContext(), "Location changed : Lat " + loc.getLatitude() +"Lng: "+loc.getLongitude(),
Toast.LENGTH_SHORT).show();
String longtitude = "Longtitude: "+loc.getLongitude();
Log.v(TAG, longtitude);
String latitude = "Latitude: "+loc.getLatitude();
Log.v(TAG, latitude);
String cityName = "default";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
// addresses
try{
List<Address> addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if(addresses.size()>0) {
System.out.println(addresses.get(0).getLocality());
cityName = addresses.get(0).getLocality();
}
}catch(IOException e){
e.printStackTrace();
}
String s = longtitude + "\n" + latitude +
"\n\nMy Current City is : "+ cityName;
editLocation.setText(s);
}
@Override
public void onProviderDisabled(String provider){
}
@Override
public void onProviderEnabled(String provider){
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
}
}
在上面的代码中,这部分是通过经纬度获取城市名称的主要代码。获取经纬度是没有问题的。唯一的问题是获取城市名称。
String cityName = "default";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
// addresses
try{
List<Address> addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if(addresses.size()>0) {
System.out.println(addresses.get(0).getLocality());
cityName = addresses.get(0).getLocality();
}
}catch(IOException e){
e.printStackTrace();
}
String s = longtitude + "\n" + latitude +
"\n\nMy Current City is : "+ cityName;
editLocation.setText(s);
}
感谢您阅读我的问题。祝你有美好的一天(?)午夜。
First thing you shouldn't call getFromLocation from main thread as this method is synchronous and may take a long time to do its work, so you should not call it from the main, user interface (UI) thread of your app. you should use Intent service class.
Here is code for it:
public class GetAddressService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
protected ResultReceiver mReceiver;
//protected DataEntry.AddressResultReceiver mReceiver;
private static final String TAG = "GetAddressService";
public GetAddressService() {
super("GetAddressService");
}
@Override
protected void onHandleIntent(Intent intent) {
mReceiver = intent.getParcelableExtra(Constants.RECEIVER);
Log.e(TAG,"mReceiver"+mReceiver);
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = null;
String errorMessage = "";
// Get the location passed to this service through an extra.
Location mCurrentLocation = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA);
try {
addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(),
mCurrentLocation.getLongitude(), 1);
} catch (IOException e) {
errorMessage = "Service error: ";
Log.e(TAG, errorMessage, e);
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = "invalid_lat_long_used";
Log.e(TAG, errorMessage + ". " +
"Latitude = " + mCurrentLocation.getLatitude() +
", Longitude = " +
mCurrentLocation.getLongitude(), illegalArgumentException);
}
// Handle case where no address was found.
if (addresses == null || addresses.size() == 0) {
if (errorMessage.isEmpty()) {
errorMessage = "no_address_found";
Log.e(TAG, errorMessage);
}
deliverResultToReceiver(Constants.FAILURE_RESULT,errorMessage);
}else {
String cityName = addresses.get(0).getLocality();
String countryName = addresses.get(0).getCountryName();
String rLocation = cityName + "," + countryName;
Log.e(TAG, "location: " + rLocation);
deliverResultToReceiver(Constants.SUCCESS_RESULT,rLocation);
}
}
//To deliver the result back to the activity which started the service
private void deliverResultToReceiver(int resultCode, String message) {
//mReceiver = new ResultReceiver(this);
Bundle bundle = new Bundle();
bundle.putString(Constants.RESULT_DATA_KEY, message);
mReceiver.send(resultCode, bundle);
Log.e(TAG,"Delivering result"+message);
}
}
//Constant class to store all constants in one place
public final class Constants {
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
public static final String PACKAGE_NAME =
"your package name";
public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
public static final String RESULT_DATA_KEY = PACKAGE_NAME +
".RESULT_DATA_KEY";
public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
".LOCATION_DATA_EXTRA";
}
//call this GetAddressService from your activity
private AddressResultReceiver mResultReceiver;
private class MyLocationListener implements LocationListener{
@Override
public void onLocationChanged(Location loc){
Intent intent = new Intent(this,GetAddressService.class);
intent.putExtra(Constants.RECEIVER,mResultReceiver);
intent.putExtra(Constants.LOCATION_DATA_EXTRA,loc);
startService(intent);
}
//class to receive the address back from the service
class AddressResultReceiver extends ResultReceiver{
/**
* Create a new ResultReceive to receive results. Your
* {@link #onReceiveResult} method will be called from the thread running
* <var>handler</var> if given, or from an arbitrary thread if null.
*
* @param handler
*/
public AddressResultReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
Log.e(TAG,"Address is:"+mAddressOutput);
}
}
我正在制作 android 应用程序。我在获取位置方面遇到了一些问题。
在我的代码中,我让我的应用程序通过 GPS 获取经度和纬度。但是,我一直无法通过经度和纬度获取城市名称。我不知道为什么我的代码会出现异常,即使我的代码中没有任何错误。
这是我获取城市名称的代码
ackage org.androidtown.getcurrentlocation;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GetCurrentLocation extends AppCompatActivity implements View.OnClickListener {
private LocationManager locationManager = null;
private LocationListener locationListener = null;
private Button btnGetLocation = null;
private EditText editLocation = null;
private ProgressBar pb = null;
private static final String TAG = "Debug";
private Boolean flag = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_current_location);
pb = (ProgressBar) findViewById(R.id.progressBar1);
pb.setVisibility(View.INVISIBLE);
editLocation = (EditText) findViewById(R.id.editTextLocation);
btnGetLocation = (Button) findViewById(R.id.btnLocation);
btnGetLocation.setOnClickListener(this);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
@Override
public void onClick(View v) {
flag = displayGpsStatus();
if (flag) {
Log.v(TAG, "onClick");
editLocation.setText("Please!! move your device to see the changes in coordinates.\nWait..");
pb.setVisibility(View.VISIBLE);
locationListener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {return;}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
}
else{
alertbox("GPS Status!!", "Your GPS is : OFF");
}
}
private Boolean displayGpsStatus(){
ContentResolver contentResolver = getBaseContext().getContentResolver();
boolean gpsStatus = Settings.Secure.isLocationProviderEnabled(contentResolver, LocationManager.GPS_PROVIDER);
if(gpsStatus){
return true;
}
else{
return false;
}
}
protected void alertbox(String title, String mymessage){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your Device's GPS is Disable").setCancelable(false).setTitle("**GPS Status**").setPositiveButton("Gps On", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id){
Intent myIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
startActivity(myIntent);
dialog.cancel();
}
}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
private class MyLocationListener implements LocationListener{
@Override
public void onLocationChanged(Location loc){
editLocation.setText("");
pb.setVisibility(View.INVISIBLE);
Toast.makeText(getBaseContext(), "Location changed : Lat " + loc.getLatitude() +"Lng: "+loc.getLongitude(),
Toast.LENGTH_SHORT).show();
String longtitude = "Longtitude: "+loc.getLongitude();
Log.v(TAG, longtitude);
String latitude = "Latitude: "+loc.getLatitude();
Log.v(TAG, latitude);
String cityName = "default";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
// addresses
try{
List<Address> addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if(addresses.size()>0) {
System.out.println(addresses.get(0).getLocality());
cityName = addresses.get(0).getLocality();
}
}catch(IOException e){
e.printStackTrace();
}
String s = longtitude + "\n" + latitude +
"\n\nMy Current City is : "+ cityName;
editLocation.setText(s);
}
@Override
public void onProviderDisabled(String provider){
}
@Override
public void onProviderEnabled(String provider){
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras){
}
}
}
在上面的代码中,这部分是通过经纬度获取城市名称的主要代码。获取经纬度是没有问题的。唯一的问题是获取城市名称。
String cityName = "default";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
// addresses
try{
List<Address> addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1);
if(addresses.size()>0) {
System.out.println(addresses.get(0).getLocality());
cityName = addresses.get(0).getLocality();
}
}catch(IOException e){
e.printStackTrace();
}
String s = longtitude + "\n" + latitude +
"\n\nMy Current City is : "+ cityName;
editLocation.setText(s);
}
感谢您阅读我的问题。祝你有美好的一天(?)午夜。
First thing you shouldn't call getFromLocation from main thread as this method is synchronous and may take a long time to do its work, so you should not call it from the main, user interface (UI) thread of your app. you should use Intent service class.
Here is code for it:
public class GetAddressService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
protected ResultReceiver mReceiver;
//protected DataEntry.AddressResultReceiver mReceiver;
private static final String TAG = "GetAddressService";
public GetAddressService() {
super("GetAddressService");
}
@Override
protected void onHandleIntent(Intent intent) {
mReceiver = intent.getParcelableExtra(Constants.RECEIVER);
Log.e(TAG,"mReceiver"+mReceiver);
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> addresses = null;
String errorMessage = "";
// Get the location passed to this service through an extra.
Location mCurrentLocation = intent.getParcelableExtra(Constants.LOCATION_DATA_EXTRA);
try {
addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(),
mCurrentLocation.getLongitude(), 1);
} catch (IOException e) {
errorMessage = "Service error: ";
Log.e(TAG, errorMessage, e);
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = "invalid_lat_long_used";
Log.e(TAG, errorMessage + ". " +
"Latitude = " + mCurrentLocation.getLatitude() +
", Longitude = " +
mCurrentLocation.getLongitude(), illegalArgumentException);
}
// Handle case where no address was found.
if (addresses == null || addresses.size() == 0) {
if (errorMessage.isEmpty()) {
errorMessage = "no_address_found";
Log.e(TAG, errorMessage);
}
deliverResultToReceiver(Constants.FAILURE_RESULT,errorMessage);
}else {
String cityName = addresses.get(0).getLocality();
String countryName = addresses.get(0).getCountryName();
String rLocation = cityName + "," + countryName;
Log.e(TAG, "location: " + rLocation);
deliverResultToReceiver(Constants.SUCCESS_RESULT,rLocation);
}
}
//To deliver the result back to the activity which started the service
private void deliverResultToReceiver(int resultCode, String message) {
//mReceiver = new ResultReceiver(this);
Bundle bundle = new Bundle();
bundle.putString(Constants.RESULT_DATA_KEY, message);
mReceiver.send(resultCode, bundle);
Log.e(TAG,"Delivering result"+message);
}
}
//Constant class to store all constants in one place
public final class Constants {
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
public static final String PACKAGE_NAME =
"your package name";
public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
public static final String RESULT_DATA_KEY = PACKAGE_NAME +
".RESULT_DATA_KEY";
public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME +
".LOCATION_DATA_EXTRA";
}
//call this GetAddressService from your activity
private AddressResultReceiver mResultReceiver;
private class MyLocationListener implements LocationListener{
@Override
public void onLocationChanged(Location loc){
Intent intent = new Intent(this,GetAddressService.class);
intent.putExtra(Constants.RECEIVER,mResultReceiver);
intent.putExtra(Constants.LOCATION_DATA_EXTRA,loc);
startService(intent);
}
//class to receive the address back from the service
class AddressResultReceiver extends ResultReceiver{
/**
* Create a new ResultReceive to receive results. Your
* {@link #onReceiveResult} method will be called from the thread running
* <var>handler</var> if given, or from an arbitrary thread if null.
*
* @param handler
*/
public AddressResultReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
mAddressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
Log.e(TAG,"Address is:"+mAddressOutput);
}
}