使用带有 GPS 提供程序的 requestLocationUpdates 永远不会调用 onLocationChanged
Posted
技术标签:
【中文标题】使用带有 GPS 提供程序的 requestLocationUpdates 永远不会调用 onLocationChanged【英文标题】:onLocationChanged is never called by using requestLocationUpdates with GPS provider 【发布时间】:2013-09-11 15:52:16 【问题描述】:我正在开发一个应用程序,通过使用服务来跟踪用户的位置并将数据发送到后台的服务器。这是基于 GPS 的应用程序。当我的程序使用 GPS 提供程序调用 requestLocationUpdates 时,永远不会调用 onLocationChanged。但是,requestLocationUpdates 与我的应用程序上的网络提供商一起工作得很好。请看我的代码。
安卓版本:4.1.2 设备:Galaxy nexus S
Tracker.java
private void init()
locationListener = new MyLocationListener();
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NOTIFICATION = R.string.local_service_started;
arrivedStatus = false;
activity = TrackerActivity.getAppActivity();
@Override
public void onCreate()
super.onCreate();
init();
Log.i(tag, "Start Tracking");
showStartNotification();
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.i("LocalService", "Received start id " + startId + ": " + intent);
tripID = intent.getExtras().getInt("tripID") + "";
locationInterval = intent.getExtras().getInt("locationInterval")
* MILLISECONDS_PER_SECOND;
//lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
// locationInterval, 0, locationListener);
getLocation();
return START_STICKY;
@Override
public void onDestroy()
super.onDestroy();
Log.e("STOP_SERVICE", "Service has stopped");
mNM.cancel(R.string.local_service_started);
lm.removeUpdates(locationListener);
stopSelf();
private void getLocation()
lm = (LocationManager) getApplicationContext().getSystemService(
Context.LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = lm
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled)
// no network provider is enabled
Log.e(tag, "Non providers are enabled");
else
if (isGPSEnabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
locationInterval, 0, locationListener);
Log.d(tag, "GPS Enabled");
if (isNetworkEnabled)
if (lm == null)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
locationInterval, 0, locationListener);
Log.d(tag, "Network Enabled");
@Override
public IBinder onBind(Intent intent)
// TODO Auto-generated method stub
return null;
@SuppressWarnings("deprecation")
private void showStartNotification()
// In this sample, we'll use the same text for the ticker and the
// expanded notification
CharSequence text = getText(R.string.local_service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.cameral, text,
System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this
// notification+
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, TrackerActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this,
getText(R.string.local_service_label), text, contentIntent);
// Send the notification.
mNM.notify(NOTIFICATION, notification);
/**
* private void showStopSpecification() CharSequence text =
* getText(R.string.local_service_cancel); Notification notification = new
* Notification(R.drawable.btn_save_dialog, text,
* System.currentTimeMillis()); mNM.notify(NOTIFICATION, notification);
*/
private void checkResult(JSONObject json)
try
if (json.getString(KEY_SUCCESS) != null)
String res = json.getString(KEY_SUCCESS);
if (Integer.parseInt(res) == 1)
Log.v(tag, "Store data successfully");
activity.findViewById(R.id.tracker_info)
.setBackgroundResource(R.color.blue4);
if (json.getInt(ARRIVED_STATUS) == 1)
setArrivedStatus(true);
else
setArrivedStatus(false);
else if (json.getString(KEY_ERROR).equals("1"))
// Error in login
String error_msg = json.getString(KEY_ERROR_MSG);
Log.e(tag, error_msg);
setArrivedStatus(false);
else
Log.e(tag, "Something is wrong");
setArrivedStatus(false);
else
Log.e(tag, "Something is wrong");
setArrivedStatus(false);
catch (JSONException e)
e.printStackTrace();
public void setArrivedStatus(boolean status)
arrivedStatus = status;
public boolean getArrivedStatus()
return arrivedStatus;
private class MyLocationListener implements LocationListener
@Override
public void onLocationChanged(Location location)
// TODO Auto-generated method stub
currentLat = location.getLatitude() + "";
currentLng = location.getLongitude() + "";
Log.v(tag, LOCATION_CHANGED + " lat=" + currentLat + ", lon="
+ currentLng);
try
JSONObject json = new LogInfo().execute(
new String[] tripID, currentLat, currentLng ).get();
checkResult(json);
if (getArrivedStatus() == true)
Log.v(tag, "User has arrived safely");
onDestroy();
catch (InterruptedException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (ExecutionException e)
// TODO Auto-generated catch block
e.printStackTrace();
@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
我也已经在我的清单中添加了权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
谢谢
【问题讨论】:
【参考方案1】:当你调用这个函数时,你看到设备通知栏上的 GPS 图标了吗?如果是这样,这意味着它试图获取一个位置,而你只是在一个没有 GPS 接收的地方。
无论如何,你都可以使用谷歌的方式来获取位置,这里:https://developers.google.com/events/io/sessions/324498944
另外,什么是“Tracker”类?是服务吗?如果是这样,你不应该让它引用一个活动,因为它会导致内存泄漏。而是使用正确的绑定。
您还应该避免调用 "onDestroy" ,因为调用它并不会真正关闭您的服务。而是调用“stopSelf”,并确保没有绑定任何活动。
如果你愿意,我很久以前就问过这类问题(通过服务获取位置)here。
【讨论】:
非常感谢。您的回答和建议对我很有帮助。 但是,绑定服务是否意味着在执行绑定服务方法的过程中服务必须停止一段时间? @user2503808 我不明白这个问题。该服务只有在它自己真正停止后才会被视为停止,并且只有在它没有任何实时绑定后才会发生这种情况。检查此链接:developer.android.com/guide/components/services.html#Lifecycle(如果您愿意,请滚动到图表)或此链接:developer.android.com/reference/android/app/Service.html以上是关于使用带有 GPS 提供程序的 requestLocationUpdates 永远不会调用 onLocationChanged的主要内容,如果未能解决你的问题,请参考以下文章
调用 requestLocation() 时的“线程 1:信号 Sigabrt”
requestLocation() 不请求许可,即使“下次询问”被勾选