我试图每30分钟记录一次用户的gps信号。我正在使用警报并且正在调用该服务,但是当警报调用此函数时,它似乎似乎不更新gps位置,它使用之前的值。
这是我更新我的位置的代码,请注意,在底部,我为同一个功能设置了另一个警报,以便再次调用它。
package com.cellphone;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import com.cellphone.astralweb.R;
public class UpdateLocation extends IntentService {
public static final String id = "";
public UpdateLocation() {
super("UpdateLocation");
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences prefs = getSharedPreferences("Settings", 0);
final String id = prefs.getString("ID", "");
HttpParams httpParams = new BasicHttpParams();
// 30seconds and it stops
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
HttpConnectionParams.setSoTimeout(httpParams, 30000);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httpost = new HttpPost(
"http://iphone-radar.com/gps/gps_locations");
JSONObject holder = new JSONObject();
try {
holder.put("id", id);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
LocationListener loc_listener = 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
}
};
String bestProvider = locationManager.getBestProvider(criteria,
false);
try {
Looper.prepare();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
loc_listener);
} catch (Exception e) {
e.printStackTrace();
}
Location location = locationManager
.getLastKnownLocation(bestProvider);
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"hh:mmaa MM-dd-yyyy");
holder.put("time", sdf.format(c.getTime()));
holder.put("time_since_epoch",
System.currentTimeMillis() / 1000);
try {
holder.put("lat", location.getLatitude());
holder.put("lon", location.getLongitude());
} catch (NullPointerException e) {
try {
holder.put("lat", -1.0);
holder.put("lon", -1.0);
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
StringEntity se = new StringEntity(holder.toString());
httpost.setEntity(se);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httpost, responseHandler);
org.json.JSONObject obj;
obj = new org.json.JSONObject(response);
SimpleDateFormat sdf2 = new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ssaa");
try {
History.addHistory(sdf2.format(c.getTime()), "GPS",
"Latitude: " + location.getLatitude() + "\n"
+ "Longitude: " + location.getLongitude());
} catch (NullPointerException e) {
History.addHistory(sdf2.format(c.getTime()), "GPS",
"Latitude: " + -1.0 + "\n" + "Longitude: " + -1.0);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent setAlarm = new Intent(UpdateLocation.this,
UpdateLocation.class);
PendingIntent pendingIntent = PendingIntent.getService(
UpdateLocation.this, 0, setAlarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int UPDATE_TIME = prefs.getInt("Update_time", 30);
calendar.add(Calendar.MINUTE, UPDATE_TIME);
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), pendingIntent);
}
}
这是我放在名为更新位置的按钮内的功能。此功能可以正常工作并正确更新位置。代码是一样的,所以我想知道它为什么不在服务中更新。
public class updateloc extends AsyncTask<Void, Void, Void> {
protected void onPostExecute(String response) {
if (response != null) {
// check if this does anything later
}
progressDialog.dismiss();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(ImTracking.this, "",
"Updating Data...");
}
@Override
protected Void doInBackground(Void... arg0) {
SharedPreferences prefs = getSharedPreferences("Settings", 0);
final String id = prefs.getString("ID", "");
HttpParams httpParams = new BasicHttpParams();
// 30seconds and it stops
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
HttpConnectionParams.setSoTimeout(httpParams, 30000);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httpost = new HttpPost(
"http://iphone-radar.com/gps/gps_locations");
JSONObject holder = new JSONObject();
try {
holder.put("id", id);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
LocationListener loc_listener = 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
}
};
String bestProvider = locationManager.getBestProvider(criteria,
false);
try {
Looper.prepare();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
loc_listener);
} catch (Exception e) {
e.printStackTrace();
}
Location location = locationManager
.getLastKnownLocation(bestProvider);
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(
"hh:mmaa MM-dd-yyyy");
holder.put("time", sdf.format(c.getTime()));
holder.put("time_since_epoch",
System.currentTimeMillis() / 1000);
try {
holder.put("lat", location.getLatitude());
holder.put("lon", location.getLongitude());
} catch (NullPointerException e) {
try {
holder.put("lat", -1.0);
holder.put("lon", -1.0);
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
StringEntity se = new StringEntity(holder.toString());
httpost.setEntity(se);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httpost, responseHandler);
org.json.JSONObject obj;
obj = new org.json.JSONObject(response);
SimpleDateFormat sdf2 = new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ssaa");
try {
History.addHistory(sdf2.format(c.getTime()), "GPS",
"Latitude: " + location.getLatitude() + "\n"
+ "Longitude: " + location.getLongitude());
} catch (NullPointerException e) {
History.addHistory(sdf2.format(c.getTime()), "GPS",
"Latitude: " + -1.0 + "\n" + "Longitude: " + -1.0);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
progressDialog.dismiss();
return null;
}
}
由于
答案 0 :(得分:0)
我认为你的AsyncTask只发送最后一个位置的原因是因为你没有正确使用LocationListener接口,或者实际上根本没有。
我认为您需要在onLocationChanged方法中添加一些代码来对该位置执行某些操作,例如可能将其放入您的活动的成员var中,这样您就可以使用它。
UI通过按钮更新的原因实际上只是注册一个监听器的副作用(当它听到一个新位置时实际上没有任何东西)导致LocationManger继续并更新lastKnownLocation,你的按钮他们从中获取价值。因此,聋人监听器会导致LocationManager轮询更新,并更新它自己的lastKnown,单击处理程序依赖它。
这在AsyncTask中不起作用的原因是任务运行一次然后死掉。因此,当你注册另一个监听器时,它将永远不会有机会获得一个事件,因为它的父(任务)将一直运行到doInBackground的末尾然后死掉。所以,它在它获得位置更改事件之前就已经死了......在你的任务内部实际上不会做任何事情(没有onLocationChanged方法的主体)。
我认为您需要退回原型代码并重新考虑您的设计。
使用AsyncTask来处理http帖子是一个好主意,但拥有它并且Activity本身是一个监听器是行不通的。特别是在onLocationChanged事件中没有实现有用的东西。
考虑让您的Activity成为侦听器,并为Location设置成员var。在onLocationChanged事件中,将您从事件中获得的位置克隆到memeber var,然后您可以先使用新位置更新UI,然后开始将任务发送到您的网站。
您可以继续将任务声明为Task<Void,Void,Void>
,只需从任务中访问活动的成员var,或者更正确地将其传递给声明为Task<Location,Void,Void>
的成员。
此外,我认为你需要考虑检查一个任务当前是否已经在运行,然后再开始新任务,就像registerForLocationUpdates(provider,0,0)一样,你将比你的网站更快地获得它们。可能能够接收它们,特别是连接时超时30秒。
您可以在开始新任务之前测试任务当前是否正在运行,或者在onPreExecute中设置为true的活动中使用布尔成员var,在onPostExecute中使用false,然后在开始新任务之前检查
即使这可能是对网站的喋喋不休。您可能想要创建一个数据结构来容纳许多位置,然后,一旦您累积了一些数量,就可以将它们全部一批地发送到网站。
希望有所帮助。