如何在 Android 中使用 gps 获取当前位置(街道、城市等)
Posted
技术标签:
【中文标题】如何在 Android 中使用 gps 获取当前位置(街道、城市等)【英文标题】:How to get Current Location(Street,City, etc,..) using gps in Android 【发布时间】:2017-01-06 05:32:32 【问题描述】:我想创建一个应用程序来跟踪安装我的应用程序的用户,所以我有一个跟踪代码,此代码运行良好,但它只会返回城市名称。但我需要完整的详细信息,如街道名称、城市等。
public class GetCurrentLocation extends Activity
implements OnClickListener
private LocationManager locationMangaer = 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
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//if you want to lock screen for always Portrait mode
setRequestedOrientation(ActivityInfo
.SCREEN_ORIENTATION_PORTRAIT);
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);
locationMangaer = (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)
// 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;
locationMangaer.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
else
alertbox("Gps Status!!", "Your GPS is: OFF");
/*----Method to Check GPS is enable or disable ----- */
private Boolean displayGpsStatus()
ContentResolver contentResolver = getBaseContext()
.getContentResolver();
boolean gpsStatus = Settings.Secure
.isLocationProviderEnabled(contentResolver,
LocationManager.GPS_PROVIDER);
if (gpsStatus)
return true;
else
return false;
/*----------Method to create an AlertBox ------------- */
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)
// finish the current activity
// AlertBoxAdvance.this.finish();
Intent myIntent = new Intent(
Settings.ACTION_SECURITY_SETTINGS);
startActivity(myIntent);
dialog.cancel();
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
// cancel the dialog box
dialog.cancel();
);
AlertDialog alert = builder.create();
alert.show();
/*----------Listener class to get coordinates ------------- */
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 longitude = "Longitude: " +loc.getLongitude();
Log.v(TAG, longitude);
String latitude = "Latitude: " +loc.getLatitude();
Log.v(TAG, latitude);
/*----------to get City-Name from coordinates ------------- */
String cityName=null;
Geocoder gcd = new Geocoder(getBaseContext(),
Locale.getDefault());
List<Address> addresses;
try
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 = longitude+"\n"+latitude +
"\n\nMy Currrent City is: "+cityName;
editLocation.setText(s);
@Override
public void onProviderDisabled(String provider)
// TODO Auto-generated method stub
@Override
public void onProviderEnabled(String provider)
// TODO Auto-generated method stub
@Override
public void onStatusChanged(String provider,
int status, Bundle extras)
// TODO Auto-generated method stub
【问题讨论】:
【参考方案1】:试试这个:
public void setCurrentLocation()
if (UtilityMethods.isGPSEnabled(mContext))
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
// return;
else
getCurrentAddress();
else
alertbox("Gps Status", "Your Device's GPS is Disable", mContext);
使用位置管理器
public void getCurrentAddress()
// Get the location manager
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager != null)
try
if (Build.VERSION.SDK_INT >= 23 && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
// TODO: Consider calling
// public void requestPermissions(@NonNull String[] permissions, int requestCode)
// 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 Activity#requestPermissions for more details.
return;
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
catch (Exception ex)
Log.i("msg", "fail to request location update, ignore", ex);
if (locationManager != null)
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Geocoder gcd = new Geocoder(getBaseContext(),
Locale.getDefault());
List<Address> addresses;
try
addresses = gcd.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
if (addresses.size() > 0)
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
String locality = addresses.get(0).getLocality();
String subLocality = addresses.get(0).getSubLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
if (subLocality != null)
currentLocation = locality + "," + subLocality;
else
currentLocation = locality;
current_locality = locality;
catch (Exception e)
e.printStackTrace();
Toast.makeText(HomeActivity.this, Constants.ToastConstatnts.ERROR_FETCHING_LOCATION, Toast.LENGTH_SHORT).show();
【讨论】:
我试过“地理编码器”,它不会给我当前位置的确切当前地址。它给了我所有附近位置的地址数组。我想获得确切的当前位置。我有我当前位置的经度和纬度。 非常有帮助。我用你的技术返回一个字符串,效果更好【参考方案2】:使用fused Location Provider获取当前设备的经纬度。
借助经纬度,您可以获得城市名称和地址。
要获取完整的街道名称,请使用getMaxAddressLineIndex()。
在 onLocationChanged 中,检查您是否获取当前位置。
编辑:
String strAdd = "";
@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 longitude = "Longitude: " +loc.getLongitude();
Log.v(TAG, longitude);
String latitude = "Latitude: " +loc.getLatitude();
Log.v(TAG, latitude);
/*----------to get City-Name from coordinates ------------- */
String cityName=null;
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(TabClubActivity.this, Locale.getDefault());
try
addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (!addresses.isEmpty())
Address returnedAddress = addresses.get(0);
StringBuilder strReturnedAddress = new StringBuilder("");
for (int i = 0; i < returnedAddress.getMaxAddressLineIndex(); i++)
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append(" ");
strAdd = strReturnedAddress.toString();
textview.setText(strAdd);
Log.e("MyCurrentLoctionAddress", "" + strReturnedAddress.toString());
cityName=addresses.get(0).getLocality();
else
// Log.e("MyCurrentLoctionAddress", "No Address returned!");
catch (IOException e)
e.printStackTrace();
String s = longitude+"\n"+latitude +
"\n\nMy Currrent City is: "+cityName;
editLocation.setText(s);
【讨论】:
@T.KarthikeyanT.Karthikeyan 在你的 onlocationchanged 中使用我的 try and catch 块 @T.KarthikeyanT.Karthikeyan 只需复制并粘贴 onLocationchanged()。我进行了更改。addresses = geocoder.getFromLocation(latitude, longitude, 1);
中的错误
@T.KarthikeyanT.Karthikeyan 你没有得到纬度和经度。这就是您收到错误消息的原因。请按照此javapapers.com/android/android-location-fused-provider 获取经度和纬度。
@T.KarthikeyanT.Karthikeyan 你在 MyCurrentLoctionAddress.debug 中获得了什么价值并告诉我【参考方案3】:
我尝试了Geocoder
,但结果不可靠。所以最好去附近搜索 googleapi 的结果。它直接提供城市名称。这是我的实现版本。
interface Api
String BASE_URL = "https://maps.googleapis.com";
@GET("/maps/api/place/nearbysearch/json")
Call<List<ResultDO>> getPlaceDetailByLatLong(@Query("location") String type,@Query("radius") String radius,@Query("key")String key);
在主要活动或片段中。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
API service = retrofit.create(API.class);
service.getCityResults(types, input, location, radius, key).enqueue(new Callback<List<ResultDO>>()
@Override
public void onResponse(Call<List<ResultDO>> call, Response<List<ResultDO>> response)
tvCity.setText(response.body().get(0).getVicinity());// first object gives me the city name
@Override
public void onFailure(Call<List<ResultDO>> call, Throwable t)
);
【讨论】:
【参考方案4】:您可以通过将地理位置(例如纬度、经度)转换为地址来获取地址(街道名称、城市、国家/地区等)。这个过程称为Reverse Geocoding
this doc。
您可以使用 FusedLocationProviderApi()
,但它已被弃用 (here)。另一种方法是,您可以使用FusedLocationProviderClient()
从 LastKnownLocation 对象(包含纬度和经度)中获取 LastKnownLocation,因此我们可以使用 Geocoder
获取街道名称、城市、国家等地址。 The sample doc 同步执行。但在这里我正在使用AsyncTask
进行异步操作。希望对您有所帮助。
获取当前位置:
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.tasks.OnCompleteListener;
public class MainActivity extends AppCompatActivity
//before public class MainActivity extends AppCompatActivity implements LocationListener,...,...
private static final String TAG = "MainActivity";
public static final int MY_PERMISSIONS_REQUEST_FINE_LOCATION = 101;
private FusedLocationProviderClient mFusedLocationClient;
private Location mGetedLocation;
private double currentLat, currentLng;
private void getLastLocation()
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
requestPermissions(new String[] Manifest.permission.ACCESS_FINE_LOCATION, MY_PERMISSIONS_REQUEST_FINE_LOCATION);
return;
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(this, new OnCompleteListener<Location>()
@Override
public void onComplete(@NonNull Task<Location> task)
if (task.isSuccessful() && task.getResult() != null)
mGetedLocation = task.getResult();
//currentLat = mGetedLocation.getLatitude();
//currentLng = mGetedLocation.getLongitude();
//start reverse geocoding
//little different with the doc
(new GetAddressTask(this)).execute(mGetedLocation);
else
Log.e(TAG, "no location detected");
Log.w(TAG, "getLastLocation:exception", task.getException());
);
从 LastKnownLocation 获取地址
//sorry, I forgot where I got this asyncTask code. So I did not mention the source.
//If anyone feels that making this code please comment.
private class GetAddressTask extends AsyncTask<Location, Void, String>
Context mContext;
GetAddressTask(Context context)
super();
mContext = context;
@Override
protected String doInBackground(Location... params)
Geocoder geocoder =
new Geocoder(mContext, Locale.getDefault());
// Get the current location from the input parameter list
Location loc = params[0];
// Create a list to contain the result address
List<Address> addresses;
try
addresses = geocoder.getFromLocation(loc.getLatitude(),
loc.getLongitude(), 1);
catch (IOException e1)
Log.e("LocationSampleActivity",
"IO Exception in getFromLocation()");
e1.printStackTrace();
return ("IO Exception trying to get address");
catch (IllegalArgumentException e2)
// Error message to post in the log
String errorString = "Illegal arguments " +
Double.toString(loc.getLatitude()) +
" , " +
Double.toString(loc.getLongitude()) +
" passed to address service";
Log.e("LocationSampleActivity", errorString);
e2.printStackTrace();
return errorString;
// If the reverse geocode returned an address
if (addresses != null && addresses.size() > 0)
Address address = addresses.get(0);
/*
address.getLocality(),
address.getCountryName());
*/
return address.getLocality();
else
return "No address found";
@Override
protected void onPostExecute(String address)
if (address != null)
mtextView.setText(address);//=============================> GOT THIS
【讨论】:
【参考方案5】:在Activity Class中自定义方法:
private void getTheUserPermission()
ActivityCompat.requestPermissions(this, new String[]
Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_LOCATION);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationGetter locationGetter = new LocationGetter(FreshMenuSearchActivity.this, REQUEST_LOCATION, locationManager);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
locationGetter.OnGPS();
else
locationGetter.getLocation();
创建一个 UserDefined 类名 LocationGetter:-
public class LocationGetter
private int REQUEST_LOCATION;
private FreshMenuSearchActivity mContext;
private LocationManager locationManager;
private Geocoder geocoder;
public LocationGetter(FreshMenuSearchActivity mContext, int requestLocation, LocationManager locationManager)
this.mContext = mContext;
this.locationManager = locationManager;
this.REQUEST_LOCATION = requestLocation;
public void getLocation()
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(mContext, new String[]
Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_LOCATION);
else
Location LocationGps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location LocationNetwork = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location LocationPassive = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
if (LocationGps != null)
double lat = LocationGps.getLatitude();
double longi = LocationGps.getLongitude();
getTheAddress(lat, longi);
else if (LocationNetwork != null)
double lat = LocationNetwork.getLatitude();
double longi = LocationNetwork.getLongitude();
getTheAddress(lat, longi);
else if (LocationPassive != null)
double lat = LocationPassive.getLatitude();
double longi = LocationPassive.getLongitude();
getTheAddress(lat, longi);
else
Toast.makeText(mContext, "Can't Get Your Location", Toast.LENGTH_SHORT).show();
private void getTheAddress(double latitude, double longitude)
List<Address> addresses;
geocoder = new Geocoder(mContext, Locale.getDefault());
try
addresses = geocoder.getFromLocation(latitude, longitude, 1);
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
Log.d("neel", address);
catch (IOException e)
e.printStackTrace();
public void OnGPS()
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage("Enable GPS").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
mContext.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
).setNegativeButton("NO", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.cancel();
);
final AlertDialog alertDialog = builder.create();
alertDialog.show();
【讨论】:
以上是关于如何在 Android 中使用 gps 获取当前位置(街道、城市等)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中使用 gps 获取当前位置(街道、城市等)
Android:如何使用 GPS 提供程序获取离线当前位置?