无法在后台服务中使用 LocationManager 获取位置
Posted
技术标签:
【中文标题】无法在后台服务中使用 LocationManager 获取位置【英文标题】:Can't Get Location using LocationManager in Background Service 【发布时间】:2014-07-23 10:50:33 【问题描述】:我创建了一个应用程序,它在后台服务中定期将您的位置存储在数据库中,但是它没有获取位置。我的代码是...
public class LocationService extends Service
private Double myLat, myLong;
private Location location;
private LocationManager locManager;
private LocationListener locationListener;
private boolean NETWORK_ENABLED, GPS_ENABLED, PASSIVE_ENABLED;
@Override
public IBinder onBind(Intent intent)
return null;
@Override
public void onCreate()
Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_LONG).show();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
super.onStartCommand(intent, flags, startId);
myLat = 0.00;
myLong = 0.00;
locationListener = new LocationListener()
@Override
public void onLocationChanged(Location location)
LocationService.this.location = location;
LocationService.this.myLat = location.getLatitude();
LocationService.this.myLong = location.getLongitude();
Toast.makeText(getApplicationContext(), "onLocationChanged", Toast.LENGTH_LONG).show();
insertToDatabase();
@Override
public void onProviderDisabled(String provider)
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status,
Bundle extras)
;
getMyCurrentLocation();
private void getMyCurrentLocation()
location = null;
locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
NETWORK_ENABLED = false; GPS_ENABLED = false; PASSIVE_ENABLED = false;
NETWORK_ENABLED = locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (NETWORK_ENABLED)
Toast.makeText(getApplicationContext(), "Network Provider", Toast.LENGTH_LONG).show();
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 45 * 1000l, 1f, locationListener);
if (location == null)
//setGPSOn();
GPS_ENABLED = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(GPS_ENABLED)
Toast.makeText(getApplicationContext(), "GPS Provider", Toast.LENGTH_LONG).show();
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0l, 1f, locationListener);
//setGPSOff();
if (location == null)
PASSIVE_ENABLED = locManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER);
if(PASSIVE_ENABLED)
Toast.makeText(getApplicationContext(), "Passive Provider", Toast.LENGTH_LONG).show();
locManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0l, 1f, locationListener);
try
location = locManager.getLastKnownLocation(locManager.getBestProvider(new Criteria(), true));
catch(NullPointerException e)
if (location != null)
myLat = location.getLatitude();
myLong = location.getLongitude();
insertToDatabase();
else
Location loc = null;
try
loc = getLastKnownLocation(this);
catch(NullPointerException e)
if (loc != null)
myLat = loc.getLatitude();
myLong = loc.getLongitude();
insertToDatabase();
locManager.removeUpdates(locationListener);
private Location getLastKnownLocation(Context context)
Location location = null;
LocationManager locationmanager = (LocationManager)context.getSystemService("location");
List<?> list = locationmanager.getAllProviders();
boolean i = false;
Iterator<?> iterator = list.iterator();
do
if(!iterator.hasNext())
break;
String s = (String)iterator.next();
if(i != false && !locationmanager.isProviderEnabled(s))
continue;
Location location1 = locationmanager.getLastKnownLocation(s);
if(location1 == null)
continue;
else
float f = location.getAccuracy();
float f1 = location1.getAccuracy();
if(f >= f1)
long l = location1.getTime();
long l1 = location.getTime();
if(l - l1 <= 600000L)
continue;
location = location1;
i = locationmanager.isProviderEnabled(s);
while (true);
return location;
这没有给我任何位置....而且我的应用程序也没有崩溃或给出任何异常。
我已经在 Manifest 文件中正确注册了所有权限... ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION
我找不到该怎么办? 任何帮助将不胜感激 在此先感谢您的帮助...
【问题讨论】:
toasts 是否显示“网络提供商”或“GPS 提供商”? 是的!当我运行应用程序时,会显示所有 3 个祝酒词。但是,没有一个提供商将数据存储在我的数据库中。 尝试只启用一个,最好是网络提供商之一并检查。 我尝试只使用网络提供商,但没有任何反应 在得到任何东西之前不要移除监听器,看我的回答 【参考方案1】: //Use this class in your project:
package com.example.location;
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;
import android.util.Log;
public class LocationTracker 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 LocationTracker(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 lat/long 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();
Log.i("Error", e.getMessage());
return location;
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS()
if(locationManager != null)
locationManager.removeUpdates(LocationTracker.this);
/**
* Function to get latitude
* */
public double getLatitude()
if(location != null)
latitude = location.getLatitude();
return latitude;
/**
* Function to get longitude
* */
public double getLongitude()
if(location != null)
longitude = location.getLongitude();
return longitude;
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation()
return this.canGetLocation;
@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;
//and in your main class(Activity), call this class as follows :
double latitude = 0.0, longitude = 0.0;
Geocoder geocoder = new Geocoder(this,Locale.getDefault());
LocationTracker locationTracker = new LocationTracker(this);
if(locationTracker.canGetLocation())
latitude = locationTracker.getLatitude();
longitude = locationTracker.getLongitude();
Log.i("LocationTracker", "LatLong: " + latitude + ", " + longitude);
try
List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
if (addresses.size() > 0)
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getAddressLine(1);
String country = addresses.get(0).getAddressLine(2);
String completeAddress = address + ", " + city + ", "+country;
Log.i("Complete Address", completeAddress);
catch (Exception e)
Log.i("Error", e.getMessage());
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
else
Log.i("LocationTracker", "Unable to get location");
// Make sure to include following permissions in your manifest file:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
【讨论】:
工作中...谢谢,但是,我想每 10 分钟后调用一次此服务。那么,这在您的代码中是否可行。如果可能的话,请告诉我! @KasimRangwala 您可以通过更改 LocationTracker.java 中的 MIN_TIME_BW_UPDATES 值来更改时间间隔。然后,定位服务将在您提供的时间间隔内获取位置更新。【参考方案2】:我认为您的问题是您立即删除了侦听器:
locManager.removeUpdates(locationListener); // comment this one out
在getMyCurrentLocation()
;
你应该尝试在其他一些地方移除你的监听器。
【讨论】:
你是对的!删除 locManager.removeUpdates(locationListener);它工作正常!我的数据库中也有纬度和经度...但是,问题是应用程序仍然显示所有 3 个供应商 toast!所以,很难确定我从哪个供应商获得位置?以上是关于无法在后台服务中使用 LocationManager 获取位置的主要内容,如果未能解决你的问题,请参考以下文章
Android:isProviderEnabled(LocationManager.NETWORK_PROVIDER) 不起作用。只有 isProviderEnabled(LocationManage