【发布时间】:2012-03-01 04:03:46
【问题描述】:
我正在尝试做的是在收到 c2dm 消息时,启动一个服务,在“x”时间内请求位置,然后将该位置交给我们的服务器。 c2dm 消息正确启动服务,并且 GPS 位置打开,但它永远不会更新。它只是在那里停留了我在线程中指定的时间长度(当前为 12 秒)并且什么都不做。我在我的应用程序的其他地方(不是作为服务)使用完全相同的代码,它运行良好。我做错了什么?
这会在收到 c2dm 消息时启动服务。
context.startService(new Intent(context, ServicePingLocation.class));
这是服务本身的代码。所有被调用的都是“onCreate”和“onStart”。
public class ServicePingLocation extends Service implements LocationListener {
private final String DEBUG_TAG = "[GPS Ping]";
private boolean xmlSuccessful = false;
private boolean locationTimeExpired = false;
private LocationManager lm;
private double latitude;
private double longitude;
private double accuracy;
@Override
public void onLocationChanged(Location location) {
Log.d(DEBUG_TAG, "onLocationChanged");
latitude = location.getLatitude();
longitude = location.getLongitude();
accuracy = location.getAccuracy();
}
@Override
public void onProviderDisabled(String provider) {
Log.d(DEBUG_TAG, "onProviderDisabled");
Toast.makeText(
getApplicationContext(),
"Attempted to ping your location, and GPS was disabled.",
Toast.LENGTH_LONG).show();
}
@Override
public void onProviderEnabled(String provider) {
Log.d(DEBUG_TAG, "onProviderEnabled");
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(DEBUG_TAG, "onStatusChanged");
}
@Override
public void onCreate() {
Log.d(DEBUG_TAG, "onCreate");
}
@Override
public void onDestroy() {
Log.d(DEBUG_TAG, "onDestroy");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(DEBUG_TAG, "onBind");
return null;
}
@Override
public void onStart(Intent intent, int startid) {
Log.d(DEBUG_TAG, "onStart");
lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 10f, this);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000,
300f, this);
Log.d(DEBUG_TAG, lm.toString());
new SubmitLocationTask(ServicePingLocation.this).execute();
}
private void locationTimer() {
new Handler().postDelayed(new Runnable() {
// @Override
@Override
public void run() {
locationTimeExpired = true;
}
}, 12000);
}
private class SubmitLocationTask extends AsyncTask<String, Void, Boolean> {
/** application context. */
private Context context;
private Service service;
public SubmitLocationTask(Service service) {
this.service = service;
context = service;
}
@Override
protected void onPreExecute() {
locationTimer(); // Start 12 second timer
}
@Override
protected void onPostExecute(final Boolean success) {
if (success && xmlSuccessful) {
lm.removeUpdates(ServicePingLocation.this);
onDestroy();
} else {
if (!GlobalsUtil.DEBUG_ERROR_MSG.equals(""))
Toast.makeText(getBaseContext(),
GlobalsUtil.DEBUG_ERROR_MSG, Toast.LENGTH_SHORT)
.show();
GlobalsUtil.DEBUG_ERROR_MSG = "";
}
}
@Override
protected Boolean doInBackground(final String... args) {
try {
DateFormat df = null;
df = new SimpleDateFormat("M/d/yy h:mm a");
Date todaysDate = new Date();// get current date time with
// Date()
String currentDateTime = df.format(todaysDate);
while ((accuracy > 100f || accuracy == 0.0)
&& !locationTimeExpired) {
// We just want it to sit here and wait.
}
return xmlSuccessful = SendToServerUtil.submitGPSPing(
0, longitude,
latitude, accuracy, currentDateTime);
} catch (Exception e) {
return false;
}
}
}
}
[编辑] 修复了我遇到的问题。代码实际上正在工作。我添加了网络提供商,调整了 onDestroy() 方法以停止服务,并调整了用于获取 GPS 信号的时间。
感谢您的建议,CommonsWare
【问题讨论】:
-
12 秒可能在所有情况下都不够长。你可以看看我的
LocationPoller,它是为这样的场景设计的。 -
嗨,Ryan,我实际上正在研究类似的东西,但我的代码无法正常工作。我正在使用您的代码对其进行测试,但无法编译。您的代码中的变量“xmlSuccessful”和“SendToServerUtil”、“GlobalsUtil”类是什么?
-
xmlSuccessful 是我在将位置发送到服务器后用于处理 REST 响应的布尔值。 SendToServerUtil 是我拥有的实用程序文件,其中包含我所有的服务器通信调用(例如,“SendLocation”)。 GlobalsUtil 只是一个通用实用程序类,我将所有全局变量都存储在其中。最后一个可能不是好的做法,但它是我的第一个真正的应用程序之一……你生活和学习,对吧?无论哪种方式,您都可以删除所有这些引用,并且不会有任何问题。
标签: android android-service android-c2dm locationmanager