Câu trả lời:
Tôi đã tạo một ứng dụng nhỏ với mô tả từng bước để có tọa độ GPS của vị trí hiện tại.
Mã nguồn ví dụ hoàn chỉnh nằm trong tọa độ Vị trí hiện tại, Tên thành phố - trong Android .
Xem làm thế nào nó hoạt động:
Tất cả những gì chúng ta cần làm là thêm quyền này vào tệp kê khai:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Và tạo một cá thể LocationManager như thế này:
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
Kiểm tra xem GPS có được bật hay không.
Và sau đó triển khai LocationListener và nhận tọa độ:
LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
Đây là mã mẫu để làm như vậy
/*---------- 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 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) {}
}
adresses
dòng bắt đầu bằng cityName =
sẽ không có ngoại lệ. Sử dụng niềng răng sẽ sửa chữa nó.
getLastKnownLocation()
là một địa điểm "cũ" hơn - tại sao lại thế này? Có phải cuộc gọi getLastKnownLocation()
không nhận được GPS mới nhất của điện thoại GPS?
Dưới đây là thông tin bổ sung cho các câu trả lời khác.
Vì Android có
GPS_PROVIDER and NETWORK_PROVIDER
bạn có thể đăng ký cả hai và bắt đầu tìm nạp các sự kiện onLocationChanged(Location location)
từ hai người cùng một lúc. Càng xa càng tốt. Bây giờ câu hỏi chúng ta cần hai kết quả hay chúng ta nên làm tốt nhất. Theo tôi biết GPS_PROVIDER
kết quả có độ chính xác tốt hơn NETWORK_PROVIDER
.
Hãy xác định Location
trường:
private Location currentBestLocation = null;
Trước khi chúng tôi bắt đầu lắng nghe về thay đổi vị trí, chúng tôi sẽ thực hiện phương pháp sau. Phương pháp này trả về vị trí đã biết cuối cùng, giữa GPS và mạng. Đối với phương pháp này mới hơn là tốt nhất.
/**
* @return the last know best location
*/
private Location getLastBestLocation() {
Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
long GPSLocationTime = 0;
if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); }
long NetLocationTime = 0;
if (null != locationNet) {
NetLocationTime = locationNet.getTime();
}
if ( 0 < GPSLocationTime - NetLocationTime ) {
return locationGPS;
}
else {
return locationNet;
}
}
Mỗi lần chúng tôi lấy lại một vị trí mới, chúng tôi sẽ so sánh nó với kết quả trước đó của chúng tôi.
...
static final int TWO_MINUTES = 1000 * 60 * 2;
...
Tôi thêm một phương thức mới vào onLocationChanged
:
@Override
public void onLocationChanged(Location location) {
makeUseOfNewLocation(location);
if(currentBestLocation == null){
currentBestLocation = location;
}
....
}
/**
* This method modify the last know good location according to the arguments.
*
* @param location The possible new location.
*/
void makeUseOfNewLocation(Location location) {
if ( isBetterLocation(location, currentBestLocation) ) {
currentBestLocation = location;
}
}
....
/** Determines whether one location reading is better than the current location fix
* @param location The new location that you want to evaluate
* @param currentBestLocation The current location fix, to which you want to compare the new one.
*/
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location,
// because the user has likely moved.
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse.
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
// Checks whether two providers are the same
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
....
private Location currentBestLocation = null;
và thêm phương thức `makeUseOfNewLocation (location);` vào onLocationChanged (..)
Bạn có thể tìm vị trí bằng cách GPS_PROVIDER or NETWORK_PROVIDER
.
Tổng quan về dịch vụ định vị trong Android.
Đây là một ví dụ cố gắng tìm vị trí bằng GPS. Nếu GPS của bạn không khả dụng thì hãy thử sử dụng mạng để tìm vị trí.
GPSTracker.java
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// Flag for GPS status
boolean isGPSEnabled = false;
// Flag for network status
boolean isNetworkEnabled = false;
// Flag for GPS status
boolean canGetLocation = false;
Location location; // Location
double latitude; // Latitude
double longitude; // Longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// Getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// Getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// No network provider is enabled
} 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();
}
}
}
// If GPS enabled, get latitude/longitude using GPS Services
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;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app.
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/Wi-Fi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog.
* On pressing the Settings button it will launch Settings Options.
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS is settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing the Settings button.
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// On pressing the 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;
}
}
Hoạt động -AndroidGPSTrackingActivity.java
public class AndroidGPSTrackingActivity extends Activity {
Button btnShowLocation;
// GPSTracker class
GPSTracker gps;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
// Show location button click event
btnShowLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Create class object
gps = new GPSTracker(AndroidGPSTrackingActivity.this);
// Check if GPS enabled
if(gps.canGetLocation()) {
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// \n is for new line
Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
} else {
// Can't get location.
// GPS or network is not enabled.
// Ask user to enable GPS/network in settings.
gps.showSettingsAlert();
}
}
});
}
}
Bố cục- tệp chính
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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/btnShowLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Location"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
Đã có nhiều câu trả lời ở đó nhưng tôi muốn chỉ ra cách mới nhất để có được vị trí bằng Google API, vì vậy các lập trình viên mới có thể sử dụng phương pháp mới:
Tôi đã viết hướng dẫn chi tiết về vị trí hiện tại trong Android tại blog của tôi demuts.com Bạn cũng có thể tìm thấy mã nguồn đầy đủ được phát triển với studio android.
Trước hết, đặt nó trong tập tin gradle
compile 'com.google.android.gms:play-services:9.0.2'
sau đó thực hiện các giao diện cần thiết
public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener
khai báo
private GoogleApiClient mGoogleApiClient;
private Location mLocation;
private LocationManager locationManager;
private LocationRequest mLocationRequest;
đặt cái này vào onCreate()
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Cuối cùng, ghi đè các phương thức cần thiết
@Override
public void onConnected(Bundle bundle) {
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;
} startLocationUpdates();
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLocation == null){
startLocationUpdates();
}
if (mLocation != null) {
double latitude = mLocation.getLatitude();
double longitude = mLocation.getLongitude();
} else {
// Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
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;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Log.d("reque", "--->>>>");
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
mGoogleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
@Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
public void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
public void onLocationChanged(Location location) {
}
Đừng quên khởi động GPS trong thiết bị của bạn trước khi chạy ứng dụng.
mLocation
luôn luôn cho null. Tôi đã thử giống như đã đề cập
compile 'com.google.android.gms:play-services-location:11.0.4'
thay vì thêm tất cả các dịch vụ google play vào ứng dụng của mình.
Vì tôi không thích một số mã trong các câu trả lời khác, đây là giải pháp đơn giản của tôi. Giải pháp này có nghĩa là có thể sử dụng được trong Hoạt động hoặc Dịch vụ để theo dõi vị trí. Nó đảm bảo rằng nó không bao giờ trả lại dữ liệu quá cũ trừ khi bạn yêu cầu rõ ràng dữ liệu cũ. Nó có thể được chạy trong chế độ gọi lại để nhận các bản cập nhật khi chúng tôi nhận được chúng, hoặc trong chế độ thăm dò ý kiến để thăm dò thông tin gần đây nhất.
Giao diện LocationTracker chung. Cho phép chúng tôi có nhiều loại trình theo dõi vị trí và dễ dàng cắm loại phù hợp:
package com.gabesechan.android.reusable.location;
import android.location.Location;
public interface LocationTracker {
public interface LocationUpdateListener{
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime);
}
public void start();
public void start(LocationUpdateListener update);
public void stop();
public boolean hasLocation();
public boolean hasPossiblyStaleLocation();
public Location getLocation();
public Location getPossiblyStaleLocation();
}
Nhà cung cấpLocationTracker- lớp này sẽ theo dõi vị trí cho GPS hoặc NETWORK.
package com.gabesechan.android.reusable.location;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class ProviderLocationTracker implements LocationListener, LocationTracker {
// The minimum distance to change Updates in meters
private static final long MIN_UPDATE_DISTANCE = 10;
// The minimum time between updates in milliseconds
private static final long MIN_UPDATE_TIME = 1000 * 60;
private LocationManager lm;
public enum ProviderType{
NETWORK,
GPS
};
private String provider;
private Location lastLocation;
private long lastTime;
private boolean isRunning;
private LocationUpdateListener listener;
public ProviderLocationTracker(Context context, ProviderType type) {
lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
if(type == ProviderType.NETWORK){
provider = LocationManager.NETWORK_PROVIDER;
}
else{
provider = LocationManager.GPS_PROVIDER;
}
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//The provider is on, so start getting updates. Update current location
isRunning = true;
lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
lastLocation = null;
lastTime = 0;
return;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
lm.removeUpdates(this);
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
if(lastLocation == null){
return false;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return false; //stale
}
return true;
}
public boolean hasPossiblyStaleLocation(){
if(lastLocation != null){
return true;
}
return lm.getLastKnownLocation(provider)!= null;
}
public Location getLocation(){
if(lastLocation == null){
return null;
}
if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
return null; //stale
}
return lastLocation;
}
public Location getPossiblyStaleLocation(){
if(lastLocation != null){
return lastLocation;
}
return lm.getLastKnownLocation(provider);
}
public void onLocationChanged(Location newLoc) {
long now = System.currentTimeMillis();
if(listener != null){
listener.onUpdate(lastLocation, lastTime, newLoc, now);
}
lastLocation = newLoc;
lastTime = now;
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
Đó là FallbackLocationTracker, sẽ theo dõi bằng cả GPS và NETWORK, và sử dụng bất kỳ vị trí nào chính xác hơn.
package com.gabesechan.android.reusable.location;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener {
private boolean isRunning;
private ProviderLocationTracker gps;
private ProviderLocationTracker net;
private LocationUpdateListener listener;
Location lastLoc;
long lastTime;
public FallbackLocationTracker(Context context) {
gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
}
public void start(){
if(isRunning){
//Already running, do nothing
return;
}
//Start both
gps.start(this);
net.start(this);
isRunning = true;
}
public void start(LocationUpdateListener update) {
start();
listener = update;
}
public void stop(){
if(isRunning){
gps.stop();
net.stop();
isRunning = false;
listener = null;
}
}
public boolean hasLocation(){
//If either has a location, use it
return gps.hasLocation() || net.hasLocation();
}
public boolean hasPossiblyStaleLocation(){
//If either has a location, use it
return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
}
public Location getLocation(){
Location ret = gps.getLocation();
if(ret == null){
ret = net.getLocation();
}
return ret;
}
public Location getPossiblyStaleLocation(){
Location ret = gps.getPossiblyStaleLocation();
if(ret == null){
ret = net.getPossiblyStaleLocation();
}
return ret;
}
public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
boolean update = false;
//We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
if(lastLoc == null){
update = true;
}
else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
update = true;
}
else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
update = true;
}
else if (newTime - lastTime > 5 * 60 * 1000){
update = true;
}
if(update){
if(listener != null){
listener.onUpdate(lastLoc, lastTime, newLoc, newTime);
}
lastLoc = newLoc;
lastTime = newTime;
}
}
}
Vì cả hai đều thực hiện giao diện LocationTracker, bạn có thể dễ dàng thay đổi suy nghĩ về việc nên sử dụng giao diện nào. Để chạy lớp trong chế độ thăm dò ý kiến, chỉ cần gọi start (). Để chạy nó trong chế độ cập nhật, hãy gọi bắt đầu (Listener).
FallbackLocationTracker fallbackLocationTracker = new FallbackLocationTracker(mContext); fallbackLocationTracker.start(); if (fallbackLocationTracker.hasLocation()) { return fallbackLocationTracker.getLocation(); }
Nhận vị trí của gps bằng cách -
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener()
{
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
double latitude = location.getLatitude();
double longitude = location.getLongitude();
double speed = location.getSpeed(); //spedd in meter/minute
speed = (speed*3600)/1000; // speed in km/minute Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show();
}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
location.getSpeed()
trả về tốc độ tính bằng mét / giây (không phải mét / phút).
Bạn cần sử dụng mới nhất / mới nhất
GoogleApiClient Api
Về cơ bản những gì bạn cần làm là:
private GoogleApiClient mGoogleApiClient;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Sau đó
@Override
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
}
}
cho vị trí chính xác và đáng tin cậy nhất. Xem bài viết của tôi ở đây:
https://stackoverflow.com/a/33599228/2644905
Không sử dụng LocationListener không chính xác và có phản hồi chậm. Thành thật mà nói điều này là dễ thực hiện hơn. Đồng thời đọc tài liệu: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled = false;
boolean network_enabled = false;
public boolean getLocation(Context context, LocationResult result) {
// I use LocationResult callback class to pass location value from
// MyLocation to user code.
locationResult = result;
if (lm == null)
lm = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
// Exceptions will be thrown if the provider is not permitted.
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
catch (Exception ex) {
}
try {
network_enabled = lm
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
catch (Exception ex) {
}
// Don't start listeners if no provider is enabled.
if (!gps_enabled && !network_enabled)
return false;
if (gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locationListenerGps);
if (network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,
locationListenerNetwork);
timer1 = new Timer();
timer1.schedule(new GetLastLocation(), 5000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
class GetLastLocation extends TimerTask {
@Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc = null, gps_loc = null;
if (gps_enabled)
gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (network_enabled)
net_loc = lm
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// If there are both values, use the latest one.
if (gps_loc != null && net_loc != null) {
if (gps_loc.getTime() > net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if (gps_loc != null) {
locationResult.gotLocation(gps_loc);
return;
}
if (net_loc != null) {
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult {
public abstract void gotLocation(Location location);
}
}
Tôi hy vọng điều này sẽ giúp bạn...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Bây giờ các dịch vụ vị trí của Google Play đã ở đây, tôi khuyên các nhà phát triển nên bắt đầu sử dụng nhà cung cấp vị trí hợp nhất mới. Bạn sẽ thấy nó dễ sử dụng hơn và chính xác hơn. Vui lòng xem video Google I / O Beyond the Blue Dot: Các tính năng mới trong Vị trí Android của hai người đã tạo API dịch vụ vị trí Google Play mới.
Tôi đã làm việc với các API vị trí trên một số nền tảng di động và tôi nghĩ những gì hai người này đã làm là thực sự mang tính cách mạng. Nó đã thoát khỏi một lượng lớn sự phức tạp của việc sử dụng các nhà cung cấp khác nhau. Stack Overflow tràn ngập các câu hỏi về việc nên sử dụng nhà cung cấp nào, có nên sử dụng vị trí đã biết cuối cùng hay không, cách đặt các thuộc tính khác trên Trình quản lý vị trí, v.v. sử dụng.
Tôi đã viết một ứng dụng Android định kỳ lấy vị trí bằng các dịch vụ định vị của Google Play và gửi vị trí đó đến máy chủ web nơi nó được lưu trữ trong cơ sở dữ liệu và có thể được xem trên Google Maps . Tôi đã viết cả phần mềm máy khách (cho Android, iOS, Windows Phone và Java ME ) và phần mềm máy chủ (cho ASP.NET và SQL Server hoặc PHP và MySQL ). Phần mềm được viết bằng ngôn ngữ bản địa trên mỗi nền tảng và hoạt động chính xác trong nền trên mỗi nền tảng. Cuối cùng, phần mềm có Giấy phép MIT . Bạn có thể tìm thấy ứng dụng khách Android tại đây:
https://github.com/nickfox/GpsTracker/tree/master/phoneClrons/android
Đơn giản nhất bạn có thể tìm thấy
package com.javapapers.android.geolocationfinder;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.widget.TextView;
import android.util.Log;
public class MainActivity extends Activity implements LocationListener{
protected LocationManager locationManager;
protected LocationListener locationListener;
protected Context context;
TextView txtLat;
String lat;
String provider;
protected String latitude,longitude;
protected boolean gps_enabled,network_enabled;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtLat = (TextView) findViewById(R.id.textview1);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
@Override
public void onLocationChanged(Location location) {
txtLat = (TextView) findViewById(R.id.textview1);
txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude());
}
@Override
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
@Override
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
}
LocationManager là lớp cung cấp các phương thức xây dựng để có được vị trí biết cuối cùng
BƯỚC 1: Tạo Đối tượng LocationManager như bên dưới
LocationManager locationManager = (LocationManager) bối cảnh.getSystemService (Context.LOCATION_SERVICE);
BƯỚC 2: Thêm tiêu chí
*Criteria is use for setting accuracy*
Criteria criteria = new Criteria();
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH);
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(true);
criteria.setBearingRequired(true);
criteria.setSpeedRequired(true);
}
BƯỚC 3: NHẬN Nhà cung cấp sẵn có
Threre là hai loại nhà cung cấp GPS và mạng
String provider = locationManager.getBestProvider(criteria, true);
BƯỚC 4: Nhận vị trí cuối cùng
Location location = locationManager.getLastKnownLocation(provider);
BƯỚC 5: Nhận Vĩ độ và Kinh độ
Nếu đối tượng vị trí là null thì đừng cố gọi bên dưới phương thức s
getLatitude and getLongitude is methods which returns double values
Nhận cập nhật vị trí yêu cầu rất nhiều mã bolierplate trong Android, Bạn cần phải chăm sóc
Để giảm bớt tất cả các bước này, tôi đã tạo Android-EasyLocation (thư viện Android nhỏ) sẽ chăm sóc tất cả những thứ này và bạn có thể tập trung vào logic kinh doanh.
Tất cả bạn cần là mở rộng EasyLocationActivity và điều này
requestSingleLocationFix(easyLocationRequest);
hoặc là
requestLocationUpdates(easyLocationRequest);
Thanh toán ứng dụng mẫu và các bước cần thiết tại đây tại https://github.com/akhgupta/Android- EasyLocation
Tôi đã thực hiện một dự án từ đó chúng tôi có thể có được vị trí chính xác bằng cách sử dụng các nhà cung cấp Dịch vụ, GPS và Mạng của Google Play. Dự án này có thể được tìm thấy ở đây .
Chiến lược tìm vị trí tốt nhất là trước tiên hãy lấy vị trí từ dịch vụ google play nếu tìm thấy vị trí sau đó kiểm tra thời tiết có tốt hơn hay không, nếu vị trí được tìm thấy là null khởi động lại dịch vụ google play và thử tìm nạp vị trí từ API vị trí Android. Đăng ký vị trí trên người nghe thay đổi và khi tìm thấy vị trí tốt hơn, cuộc gọi trở lại trả lại cho hoạt động chính.
Nó rất đơn giản để sử dụng và thực hiện trong mã chỉ có hai lớp học chúng ta cần phải nhúng tức LocationManagerInterface
và SmartLocationManager
, LocationActivity
đang triển khai giao diện và sử dụng SmartLocationManager để lấy địa điểm.
/**
* Created by Syed Raza Mehdi Naqvi on 8/10/2016.
*/
public interface LocationManagerInterface {
String TAG = LocationManagerInterface.class.getSimpleName();
void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider);
}
đây là lớp quản lý vị trí
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import java.text.DateFormat;
import java.util.Date;
/**
* Created by Syed Raza Mehdi Naqvi on 8/9/2016.
*/
public class SmartLocationManager implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = SmartLocationManager.class.getSimpleName();
private static final int TWO_MINUTES = 1000 * 60 * 2;
private static final int PERMISSION_REQUEST_CODE = 1000;
private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
// default value is false but user can change it
private String mLastLocationUpdateTime; // fetched location time
private String locationProvider; // source of fetched location
private Location mLastLocationFetched; // location fetched
private Location mLocationFetched; // location fetched
private Location networkLocation;
private Location gpsLocation;
private int mLocationPiority;
private long mLocationFetchInterval;
private long mFastestLocationFetchInterval;
private Context mContext; // application context
private Activity mActivity; // activity context
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private LocationManagerInterface mLocationManagerInterface;
private android.location.LocationManager locationManager;
private android.location.LocationListener locationListener;
boolean isGPSEnabled;
boolean isNetworkEnabled;
private int mProviderType;
public static final int NETWORK_PROVIDER = 1;
public static final int ALL_PROVIDERS = 0;
public static final int GPS_PROVIDER = 2;
// private final double STANDARD_LOCATION_ACCURACY = 100.0;
// private final double STANDARD_LOCATION_SEED_LIMIT = 6.95;
public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1;
public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0;
public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2;
public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3;
private int mForceNetworkProviders = 0;
public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) {
mContext = context;
mActivity = activity;
mProviderType = providerType;
mLocationPiority = locationPiority;
mForceNetworkProviders = forceNetworkProviders;
mLocationFetchInterval = locationFetchInterval;
mFastestLocationFetchInterval = fastestLocationFetchInterval;
mLocationManagerInterface = locationInterface;
initSmartLocationManager();
}
public void initSmartLocationManager() {
// 1) ask for permission for Android 6 above to avoid crash
// 2) check if gps is available
// 3) get location using awesome strategy
askLocationPermission(); // for android version 6 above
checkNetworkProviderEnable(mForceNetworkProviders); //
if (isGooglePlayServicesAvailable()) // if googleplay services available
initLocationObjts(); // init obj for google play service and start fetching location
else
getLocationUsingAndroidAPI(); // otherwise get location using Android API
}
private void initLocationObjts() {
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(mLocationPiority)
.setInterval(mLocationFetchInterval) // 10 seconds, in milliseconds
.setFastestInterval(mFastestLocationFetchInterval); // 1 second, in milliseconds
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
startLocationFetching(); // connect google play services to fetch location
}
@Override
public void onConnected(Bundle connectionHint) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
startLocationUpdates();
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
getLocationUsingAndroidAPI();
} else {
setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
}
}
@Override
public void onLocationChanged(Location location) {
if (location == null) {
getLastKnownLocation();
} else {
setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error
getLocationUsingAndroidAPI(); // try to get location using Android API locationManager
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
private void setNewLocation(Location location, Location oldLocation) {
if (location != null) {
mLastLocationFetched = oldLocation;
mLocationFetched = location;
mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date());
locationProvider = location.getProvider();
mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider());
}
}
private void getLocationUsingAndroidAPI() {
// Acquire a reference to the system Location Manager
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
setLocationListner();
captureLocation();
}
public void captureLocation() {
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
if (mProviderType == SmartLocationManager.GPS_PROVIDER) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
} else {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private void setLocationListner() {
// Define a listener that responds to location updates
locationListener = new android.location.LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
if (location == null) {
getLastKnownLocation();
} else {
setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
// if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if
// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
// } else {
// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);
// }
}
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
}
public void onProviderDisabled(String provider) {
}
};
}
public Location getAccurateLocation() {
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return null;
}
try {
gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Location newLocalGPS, newLocalNetwork;
if (gpsLocation != null || networkLocation != null) {
newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation);
newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation);
setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched);
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
return mLocationFetched;
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
public void startLocationFetching() {
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
}
}
public void pauseLocationFetching() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
public void abortLocationFetching() {
mGoogleApiClient.disconnect();
// Remove the listener you previously added
if (locationManager != null && locationListener != null) {
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
try {
locationManager.removeUpdates(locationListener);
locationManager = null;
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
}
public void resetLocation() {
mLocationFetched = null;
mLastLocationFetched = null;
networkLocation = null;
gpsLocation = null;
}
// Android M Permission check
public void askLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setMessage("Please allow all permissions in App Settings for additional functionality.")
.setCancelable(false)
.setPositiveButton("Allow", new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Deny", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
mActivity.finish();
}
});
final AlertDialog alert = builder.create();
alert.show();
} else
ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION
, Manifest.permission.ACCESS_FINE_LOCATION
}, PERMISSION_REQUEST_CODE);
}
}
}
public void checkNetworkProviderEnable(int enforceActive) {
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel");
} else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) {
buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel");
} else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) {
buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel");
}
// getting network status
if (!isGPSEnabled && !isNetworkEnabled) {
Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert
mActivity.finish();
}
}
private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
builder.setMessage(message)
.setCancelable(false)
.setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(mIntent);
}
})
.setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
mActivity.finish();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
public Location getLastKnownLocation() {
locationProvider = LocationManager.NETWORK_PROVIDER;
Location lastKnownLocation = null;
// Or use LocationManager.GPS_PROVIDER
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return lastKnownLocation;
}
try {
lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
return lastKnownLocation;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return lastKnownLocation;
}
public boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
if (status == ConnectionResult.SUCCESS) {
return true;
} else {
return false;
}
}
/**
* Determines whether one Location reading is better than the current Location fix
*
* @param location The new Location that you want to evaluate
* @param currentBestLocation The current Location fix, to which you want to compare the new one
*/
protected Location getBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return location;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return location;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return currentBestLocation;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return location;
} else if (isNewer && !isLessAccurate) {
return location;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return location;
}
return currentBestLocation;
}
/**
* Checks whether two providers are the same
*/
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
public boolean isLocationAccurate(Location location) {
if (location.hasAccuracy()) {
return true;
} else {
return false;
}
}
public Location getStaleLocation() {
if (mLastLocationFetched != null) {
return mLastLocationFetched;
}
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return null;
}
if (mProviderType == SmartLocationManager.GPS_PROVIDER) {
return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) {
return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} else {
return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
}
}
}
chúng ta có thể sử dụng nó với hoạt động hoặc một đoạn, ở đây tôi đang sử dụng nó với hoạt động
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;
import com.example.raza.locationaware.location.LocationManagerInterface;
import com.example.raza.locationaware.location.SmartLocationManager;
import com.google.android.gms.location.LocationRequest;
public class LocationActivity extends AppCompatActivity implements LocationManagerInterface {
public static final String TAG = LocationActivity.class.getSimpleName();
SmartLocationManager mLocationManager;
TextView mLocalTV, mLocationProviderTV, mlocationTimeTV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager
mLocalTV = (TextView) findViewById(R.id.locationDisplayTV);
mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV);
mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV);
}
protected void onStart() {
super.onStart();
mLocationManager.startLocationFetching();
}
protected void onStop() {
super.onStop();
mLocationManager.abortLocationFetching();
}
@Override
protected void onPause() {
super.onPause();
mLocationManager.pauseLocationFetching();
}
@Override
public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) {
Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show();
mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude());
mLocationProviderTV.setText(locationProvider);
mlocationTimeTV.setText(time);
}
}
Hy vọng nó sẽ giúp, nếu bạn có thể đề nghị bất kỳ cải thiện vui lòng gửi nó trên git . Cảm ơn.
GoogleSamples có ví dụ dài dòng bằng cách sử dụng FuseLocationProviderApi mới nhất. Thật không may, các câu trả lời được đánh giá cao nhất đã hết hạn.
Thực hiện theo các ví dụ dưới đây để triển khai Dịch vụ vị trí bằng cách sử dụng FuseLocationProviderApi
https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates
Nếu bạn đang tạo dự án vị trí mới cho Android, bạn nên sử dụng Google Play mới dịch vụ vị trí . Nó chính xác hơn nhiều và sử dụng đơn giản hơn nhiều.
Tôi đã làm việc trong một dự án theo dõi GPS nguồn mở , GpsTracker, trong vài năm. Gần đây tôi đã cập nhật nó để xử lý các bản cập nhật định kỳ từ điện thoại di động Android, iOS, Windows Phone và Java ME . Nó có đầy đủ chức năng và làm những gì bạn cần và có Giấy phép MIT .
Dự án Android trong GpsTracker sử dụng các dịch vụ Google Play mới và cũng có hai ngăn xếp máy chủ ( ASP.NET và PHP ) để cho phép bạn theo dõi các điện thoại đó.
Để kiểm tra vị trí, bạn có thể sử dụng mã sau đây. Bạn có thể đặt nó trong hộp thoại onStart () của hoạt động chính và hiển thị cảnh báo nếu trả về là sai.
private boolean isLocationAccurate()
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
{
String provider = Settings.Secure
.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (provider != null && !provider.contains("gps"))
{
return false;
}
}
else
{
try
{
int status = Settings.Secure
.getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE);
if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY)
{
return false;
}
}
catch (Settings.SettingNotFoundException e)
{
Log.e(TAG, e.getMessage());
}
}
return true;
}
Tôi đã có được vị trí rất chính xác khi sử dụng FuseLocationProviderClient
( yêu cầu dịch vụ Google Play )
Yêu cầu quyền
ERIC.ACCESS_FINE_LOCATION
ERIC.ACCESS_COARSE_LOCATION
Phụ thuộc
'com.google.android.gms: play-services-location: 15.0.0'
Mã Kotlin
val client = FusedLocationProviderClient(this)
val location = client.lastLocation
location.addOnCompleteListener {
// this is a lambda expression and we get an 'it' iterator to access the 'result'
// it.result.latitude gives the latitude
// it.result.longitude gives the longitude
val geocoder = Geocoder(applicationContext, Locale.getDefault())
val address = geocoder.getFromLocation(it.result.latitude, it.result.longitude, 1)
if (address != null && address.size > 0) {
// Get the current city
city = address[0].locality
}
}
location.addOnFailureListener {
// Some error in getting the location, let's log it
Log.d("xtraces", it.message)
}
Cách tốt nhất để tìm nạp vị trí là dưới đây
// put dependancy
implementation 'com.google.android.gms:play-services-location:11.0.4'
// PUT permissions in Menifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
// create a Java file as below
public class SingleShotLocationProvider {
public static interface LocationCallback {
public void onNewLocationAvailable(GPSCoordinates location);
}
// calls back to calling thread, note this is for low grain: if you want higher precision, swap the
// contents of the else and if. Also be sure to check gps permission/settings are allowed.
// call usually takes <10ms
public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isNetworkEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}, null);
} else {
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
}, null);
}
}
}
// consider returning Location instead of this dummy wrapper class
public static class GPSCoordinates {
public float longitude = -1;
public float latitude = -1;
public GPSCoordinates(float theLatitude, float theLongitude) {
longitude = theLongitude;
latitude = theLatitude;
}
public GPSCoordinates(double theLatitude, double theLongitude) {
longitude = (float) theLongitude;
latitude = (float) theLatitude;
}
}
}
// FILE FINISHED
// FETCH LOCATION FROM ACTIVITY AS BELOW
public void getLocation(Context context) {
MyApplication.log(LOG_TAG, "getLocation() ");
SingleShotLocationProvider.requestSingleUpdate(context,
new SingleShotLocationProvider.LocationCallback() {
@Override
public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates loc) {
location = loc;
MyApplication.log(LOG_TAG, "getLocation() LAT: " + location.latitude + ", LON: " + location.longitude);
}
});
}
Tôi đã xuất bản một thư viện nhỏ có thể giúp bạn dễ dàng lấy dữ liệu vị trí trong Android, thậm chí nó còn chăm sóc các quyền của thời gian chạy Android M.
Bạn có thể kiểm tra nó ở đây: https://github.com/julioromano/RxLocation và sử dụng nó hoặc mã nguồn của nó làm ví dụ cho việc triển khai của bạn.
Tìm mã đơn giản Viết mã theo phương pháp vị trí
public void onLocationChanged(Location location) {
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(18));
PolylineOptions pOptions = new PolylineOptions()
.width(5)
.color(Color.GREEN)
.geodesic(true);
for (int z = 0; z < routePoints.size(); z++) {
LatLng point = routePoints.get(z);
pOptions.add(point);
}
line = mMap.addPolyline(pOptions);
routePoints.add(latLng);
}
Tôi sẽ khuyên bạn nên sử dụng Thư viện vị trí thông minh
Rất đơn giản để sử dụng và nó bao bọc logic vị trí độc đáo.
Để bắt đầu dịch vụ định vị:
SmartLocation.with(context).location()
.start(new OnLocationUpdatedListener() { ... });
Nếu bạn chỉ muốn có được một vị trí (không phải định kỳ), bạn có thể chỉ cần sử dụng công cụ sửa đổi oneFix. Thí dụ:
SmartLocation.with(context).location()
.oneFix()
.start(new OnLocationUpdatedListener() { ... });
Cách đơn giản và dễ dàng
Nhận vị trí bằng cách sử dụng https://github.com/sachinvarma/ EasyLocation .
Bước 1: Chỉ cần gọi
new EasyLocationInit(MainActivity.this, timeInterval, fastestTimeInterval, runAsBackgroundService);
timeInterval -> setInterval (dài) (inMilliSeconds) có nghĩa - đặt khoảng thời gian mà bạn muốn nhận vị trí.
quickTimeInterval -> setFastestInterval (dài) (inMilliSeconds) có nghĩa là - nếu một vị trí có sẵn sớm hơn bạn có thể lấy nó. (tức là một ứng dụng khác đang sử dụng dịch vụ định vị).
runAsBackgroundService = True -> (Dịch vụ sẽ chạy trong Nền và cập nhật thường xuyên (theo timeInterval và quickTimeInterval)) runAsBackgroundService = false -> (Dịch vụ sẽ getDestroyed sau khi cập nhật vị trí thành công)
Bước 2: Chuẩn bị người đăng ký EventBus: Khai báo và chú thích phương thức đăng ký của bạn, tùy chọn chỉ định chế độ luồng:
ví dụ:
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@SuppressLint("SetTextI18n")
@Subscribe
public void getEvent(final Event event) {
if (event instanceof LocationEvent) {
if (((LocationEvent) event).location != null) {
((TextView) findViewById(R.id.tvLocation)).setText("The Latitude is "
+ ((LocationEvent) event).location.getLatitude()
+ " and the Longitude is "
+ ((LocationEvent) event).location.getLongitude());
}
}
}
Đó là tất cả.
Hy vọng nó sẽ giúp được ai đó trong tương lai.
Tháng 4 năm 2020
Các bước đầy đủ để có được vị trí hiện tại và tránh tính vô hiệu của Vị trí đã biết Cuối cùng.
Theo tài liệu chính thức , Địa điểm được biết đến cuối cùng có thể là Null trong trường hợp:
Trong trường hợp này, bạn nên yêu cầuLocationUpdates và nhận vị trí mới trên LocationCallback .
Bằng các bước sau Vị trí được biết đến cuối cùng của bạn không bao giờ null.
Điều kiện tiên quyết: Thư viện EasyPermission
Bước 1: Trong tệp kê khai thêm quyền này
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Bước 2:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Create location callback when it's ready.
createLocationCallback()
//createing location request, how mant request would be requested.
createLocationRequest()
//Build check request location setting request
buildLocationSettingsRequest()
//FusedLocationApiClient which includes location
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
//Location setting client
mSettingsClient = LocationServices.getSettingsClient(this)
//Check if you have ACCESS_FINE_LOCATION permission
if (!EasyPermissions.hasPermissions(
this@MainActivity,
Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermissionsRequired()
}
else{
//If you have the permission we should check location is opened or not
checkLocationIsTurnedOn()
}
}
Bước 3: Tạo các hàm cần thiết được gọi trong onCreate ()
private fun requestPermissionsRequired() {
EasyPermissions.requestPermissions(
this,
getString(R.string.location_is_required_msg),
LOCATION_REQUEST,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
private fun createLocationCallback() {
//Here the location will be updated, when we could access the location we got result on this callback.
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
mCurrentLocation = locationResult.lastLocation
}
}
}
private fun buildLocationSettingsRequest() {
val builder = LocationSettingsRequest.Builder()
builder.addLocationRequest(mLocationRequest!!)
mLocationSettingsRequest = builder.build()
builder.setAlwaysShow(true)
}
private fun createLocationRequest() {
mLocationRequest = LocationRequest.create()
mLocationRequest!!.interval = 0
mLocationRequest!!.fastestInterval = 0
mLocationRequest!!.numUpdates = 1
mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
public fun checkLocationIsTurnedOn() { // Begin by checking if the device has the necessary location settings.
mSettingsClient!!.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(this) {
Log.i(TAG, "All location settings are satisfied.")
startLocationUpdates()
}
.addOnFailureListener(this) { e ->
val statusCode = (e as ApiException).statusCode
when (statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
try {
val rae = e as ResolvableApiException
rae.startResolutionForResult(this@MainActivity, LOCATION_IS_OPENED_CODE)
} catch (sie: IntentSender.SendIntentException) {
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
mRequestingLocationUpdates = false
}
}
}
}
private fun startLocationUpdates() {
mFusedLocationClient!!.requestLocationUpdates(
mLocationRequest,
mLocationCallback, null
)
}
Bước 4:
Xử lý các cuộc gọi lại trong onActivityResult () sau khi đảm bảo vị trí được mở hoặc người dùng chấp nhận mở nó vào.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
LOCATION_IS_OPENED_CODE -> {
if (resultCode == AppCompatActivity.RESULT_OK) {
Log.d(TAG, "Location result is OK")
} else {
activity?.finish()
}
}
}
Bước 5: Nhận vị trí được biết đến cuối cùng từ FuseClientApi
override fun onMapReady(map: GoogleMap) {
mMap = map
mFusedLocationClient.lastLocation.addOnSuccessListener {
if(it!=null){
locateUserInMap(it)
}
}
}
private fun locateUserInMap(location: Location) {
showLocationSafetyInformation()
if(mMap!=null){
val currentLocation = LatLng(location.latitude,location.longitude )
addMarker(currentLocation)
}
}
private fun addMarker(currentLocation: LatLng) {
val cameraUpdate = CameraUpdateFactory.newLatLng(currentLocation)
mMap?.clear()
mMap?.addMarker(
MarkerOptions().position(currentLocation)
.title("Current Location")
)
mMap?.moveCamera(cameraUpdate)
mMap?.animateCamera(cameraUpdate)
mMap?.setMinZoomPreference(14.0f);
}
Tôi hy vọng điều này sẽ giúp.
Mã hóa hạnh phúc