如何在Android地图中获得连续的位置更新?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Android地图中获得连续的位置更新?相关的知识,希望对你有一定的参考价值。
我正在建立一个跟踪android应用的朋友。当我的朋友激活应用程序并随着他的GPS和手机数据一起离开时,我需要在我的设备上跟踪他。这就是概念。
我已经实现了LocationListener类,现在我可以从Gps或网络获取最后更新的位置,但除非我启动Google Maps并返回我的应用程序,否则不会更新。在谷歌搜索后,我了解到位置缓存仅由GMaps更新。
- 是否有另一种方法可以持续更新位置?
- 如果我需要在没有使用Wakelock的情况下锁定设备后继续定位怎么办?
这是我的位置监听器类:
package com.amazinginside;
/** AMAZING LOCATION SUPPORT CLASS, Devoloped By SANGEETH NANDAKUMAR */
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
public class AmazingLocation extends Service implements LocationListener
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude=0.0;
double longitude=0.0;
//MINIMUM DISTANCE FOR UPDATE (meters)
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 Meters
//MINIMUM TIME BETWEEN UPDATES
private static final long MIN_TIME_BW_UPDATES = 1000 * 0; // 0 Seconds
//LOCATION MANAGER
protected LocationManager locationManager;
//CONSTRUCTOR
public AmazingLocation(Context context)
this.mContext = context;
getLocation();
//LOCATION PROVISION
public Location getLocation()
try
//GET LOCATION MANAGER
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//CHECK GPS STATE
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//CHECK NETWORK STATE
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled)
//NO LOCATION PROVIDERS
else
this.canGetLocation = true;
/** GET LOCATION FROM NETWORK */
//FIRST GET LOCATION FROM NETWORK
if (isNetworkEnabled)
//REQUEST LOCATION
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
//START WITH LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//EXTRACT LOCATION
if (location != null)
latitude = location.getLatitude();
longitude = location.getLongitude();
/** GET LOCATION FROM GPS SENSOR */
//THEN GET LOCATION FROM GPS
if (isGPSEnabled)
if (location == null)
//REQUEST GPS LOCATION
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
//EXTRACT LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//RETURN LOCATION
if (location != null)
latitude = location.getLatitude();
longitude = location.getLongitude();
catch (Exception e)
e.printStackTrace();
return location;
//STOP GPS SENSOR
public void stopUsingGPS()
if(locationManager != null)
locationManager.removeUpdates(AmazingLocation.this);
//EXTRACT LATTITUDE
public double getLatitude()
if(location != null)
latitude = location.getLatitude();
// return latitude
return latitude;
//EXTACT LONGITUDE
public double getLongitude()
if(location != null)
longitude = location.getLongitude();
// return longitude
return longitude;
//CAN I GET THE LOCATION.?
public AmazingStatus canGetLocation()
AmazingStatus status=new AmazingStatus();
if(this.canGetLocation)
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
else
status.setStatus(false);
status.setErrorcode(145);
status.setErrormsg("Please turn on GPS access manually");
return status;
//SHOW LOCATION SETTINGS
public AmazingStatus showSettingsAlert()
final AmazingStatus status=new AmazingStatus();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("REQUIRES LOCATION ACCESS");
alertDialog.setMessage("Please allow GPS access to this app");
//POSSITIVE REPLY
alertDialog.setPositiveButton("Allow", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog,int which)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
);
//NEGATIVE REPLY
alertDialog.setNegativeButton("Deny", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int which)
status.setStatus(false);
status.setErrorcode(408);
status.setErrormsg("User denied permission");
dialog.cancel();
);
// Showing Alert Message
alertDialog.show();
return status;
//UNUSED OVERRIDE METHORDS...
@Override
public void onLocationChanged(Location location)
getLocation();
@Override
public void onProviderDisabled(String provider)
@Override
public void onProviderEnabled(String provider)
getLocation();
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
getLocation();
@Override
public IBinder onBind(Intent arg0)
return null;
这是我的onCreate()
方法:
@Override protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//CREATE A BUTTON HANDLER
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
//ON BUTTON CLICK EVENT
start_btn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
//REPEAT A METHORD AT SPECIFIC INTERVALS
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask()
@Override
public void run()
TimerMethod();
, 0, 8000);
);
这些是其他方法:
private void TimerMethod()
//START METHORD
this.runOnUiThread(Timer_Tick);
//LOCATION REPORTING METHORD
private Runnable Timer_Tick = new Runnable()
public void run()
Toast.makeText(MainActivity.this, "Current latitude : "+Double.toString(getLocation().latitude), Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Current longitude : "+Double.toString(getLocation().longitude), Toast.LENGTH_SHORT).show();
;
private LatLng getLocation()
//CREATE A LOCATION CLASS INSTANCE
AmazingLocation gps = new AmazingLocation(this);
//RETRIVE LOCATION
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
//RETURN LOCATION
LatLng loc=new LatLng(latitude,longitude);
return loc;
现在的问题是,吐司只是显示以前知道的位置而不是更新,除非我打开谷歌地图并返回。
任何帮助对我来说都很棒。
在Android中使用融合位置提供程序设置您的间隔:
举个例子,像这样创建你的活动:
public class LocationActivity extends Activity implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
Button btnFusedLocation;
TextView tvLocation;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
protected void createLocationRequest()
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate ...............................");
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable())
finish();
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_main);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
btnFusedLocation.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View arg0)
updateUI();
);
@Override
public void onStart()
super.onStart();
if (mGoogleApiClient.isConnected())
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
@Override
public void onStop()
super.onStop();
Log.d(TAG, "onStop fired ..............");
mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
private boolean isGooglePlayServicesAvailable()
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status)
return true;
else
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
@Override
public void onConnected(Bundle bundle)
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
protected void startLocationUpdates()
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
@Override
public void onConnectionSuspended(int i)
@Override
public void onConnectionFailed(ConnectionResult connectionResult)
Log.d(TAG, "Connection failed: " + connectionResult.toString());
@Override
public void onLocationChanged(Location location)
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
private void updateUI()
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation)
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
"Latitude: " + lat + "\n" +
"Longitude: " + lng + "\n" +
"Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
"Provider: " + mCurrentLocation.getProvider());
else
Log.d(TAG, "location is null ...............");
@Override
protected void onPause()
super.onPause();
stopLocationUpdates();
protected void stopLocationUpdates()
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
@Override
public void onResume()
super.onResume();
if (mGoogleApiClient.isConnected())
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
需要Google Play服务:
我相信,不是重新发明轮子,你可以使用易于实现的第三方库之一,在这种情况下,电池效率。我发现的其中一个图书馆是SmartLocation。您可以在build.gradle(app)中添加以下依赖项以开始使用该库。
compile 'io.nlopez.smartlocation:library:3.2.9'
添加依赖项后,您应该重建项目以获取引用。
例如,您可以在Activity中尝试以下代码。
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
Context context = start_btn.getContext();
Handler handler = new Handler();
start_btn.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
SmartLocation.with(context).location().start(locationListener);
);
OnLocationUpdatedListener locationListener = new OnLocationUpdatedListener(
@Override
public void onLocationUpdated(Location location)
double lat = location.getLatitude();
double lng = location.getLongitude();
handler.postDelayed(locationRunnable,8000);
);
Runnable locationRunnable = new Runnable(
@Override
public void run()
SmartLocation.with(context).location().start(locationListener);
);
您可以在onStop()方法中停止位置跟踪
@Override
public void onStop()
SmartLocation.with(context).location().stop();
super.onStop();
SmartLocation库将为您提供超出预期的功能,只需尝试一次。
注意:确保您的应用程序具有ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION(两者)以获得准确的结果。不要忘记在Android 6.0及更高版本的运行时请求权限。
您应该使用Android服务,而不是应用程序本身。这样,您将在后台连续运行代码,即使应用程序关闭,您也会收到该位置。
https://www.tutorialspoint.com/android/android_services.htm
这个库可能会派上用场。它具有您需要为位置更新执行的所有操作,例如请求权限和设置间隔时间。
https://github.com/bikcrum/LocationUpdate
以上是关于如何在Android地图中获得连续的位置更新?的主要内容,如果未能解决你的问题,请参考以下文章
android-如何在不打开地图/导航应用程序的情况下更新位置