我正在尝试为android创建一个跟踪应用程序,但问题似乎是当调用onLocationChanged时它会在不同的线程中发送几个位置,所以我无法阻止它发送2-4甚至几十个每秒的位置数。
似乎在经过一段时间每隔20秒发送一次(如MINTIME参数指定),该函数在同一秒发送多个位置。我试图验证它,因此它只允许发送1,但它不起作用,因为所有线程(我猜)同时操纵所有变量,所有位置最终显示为有效。
它并不总是发生,有时候位置监听器实际上每次MINTIME只会发送1次更新,但它会突然开始发送越来越多,直到它每秒发送10次以上。
到目前为止,我已经尝试在函数上使用synchronized关键字并使用atomicboolean来防止一次运行超过1次,但没有任何区别,我之前从未使用任何这些东西,所以我没有&#39我知道我做错了吗。
以下是调用验证坐标
的函数我如何确保每个线程都尊重变量,并且每个位置都经过适当的验证?
非常感谢任何帮助。
public synchronized void onLocationChanged(Location location) {
proc_loc(location);
}
private synchronized void proc_loc(Location location) {
if(run.compareAndSet(false,true)) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
String str;
float lat = (float) latitude;
float lon = (float) longitude;
float dist = 0;
String s_lat = "";
String s_lon = "";
String fecha = "";
String l_time = "";
String lati = "";
String longi = "";
db = openOrCreateDatabase("Camion", Context.MODE_PRIVATE, null);
Cursor c = db.rawQuery("SELECT * FROM Loci", null);
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
buffer.append("ID: " + c.getString(0) + "\n");
buffer.append("l_time: " + c.getString(1) + "\n");
buffer.append("lat: " + c.getString(2) + "\n\n");
buffer.append("longi: " + c.getString(3) + "\n\n");
buffer.append("fecha: " + c.getString(4) + "\n\n");
l_time = c.getString(1);
lati = c.getString(2);
longi = c.getString(3);
}
valido = false;
if (!lati.equals("-") && !lati.equals("")) {
l = Long.parseLong(l_time); // Prev stored time
float t_lat = Float.valueOf(lati);
float t_longi = Float.valueOf(longi);
long c_t = System.currentTimeMillis();
t_span = c_t- l;
dist = distFrom(t_lat, t_longi, lat, lon);
if (dist > 5 && dist < 10000 && (t_span > 60000)) {
valido = true;
if (!s_lat.equals("")) {
db.execSQL("UPDATE Loci SET l_time = '" + Long.toString(System.currentTimeMillis()) + "', lat = '" + s_lat + "', longi ='" + s_lon + "', fecha = '" + fecha + "';");
}
}
} else if (lati.equals("-")) {
/****Remplazar default '-' por nuevas coord***/
fecha = getDate(); //obt fecha
s_lat = Float.toString(lat);
s_lon = Float.toString(lon);
db.execSQL("UPDATE Loci SET l_time = '" + Long.toString(System.currentTimeMillis()) + "', lat = '" + s_lat + "', longi ='" + s_lon + "', fecha = '" + fecha + "';");
valido = true;
c = db.rawQuery("SELECT * FROM Loci", null);
buffer.setLength(0);
/*Si existen registros*/
while (c.moveToNext()) {
buffer.append("ID: " + c.getString(0) + "\n");
buffer.append("l_time: " + c.getString(1) + "\n");
buffer.append("lat: " + c.getString(2) + "\n\n");
buffer.append("longi: " + c.getString(3) + "\n\n");
buffer.append("fecha: " + c.getString(4) + "\n\n");
}
str = "Remp default " + buffer.toString();
Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
}
if (valido) {
String s_latit = "";
buffer.setLength(0);
/*Si existen registros*/
c = db.rawQuery("SELECT * FROM Loci", null);
while (c.moveToNext()) {
buffer.append("ID: " + c.getString(0) + "\n");
buffer.append("l_time: " + c.getString(1) + "\n");
buffer.append("lat: " + c.getString(2) + "\n\n");
buffer.append("longi: " + c.getString(3) + "\n\n");
buffer.append("fecha: " + c.getString(4) + "\n\n");
}
str = "VALIDO!!! \n D: " + Float.toString(dist) +"\n" + "\n" + Long.toString(l)+ "\n" + Long.toString(System.currentTimeMillis()) + "\n" + Long.toString(t_span) + "\n" + "\n" + buffer.toString();
Toast.makeText(getBaseContext(), str, Toast.LENGTH_LONG).show();
Runnable r = new SendUDP(9001, lat, lon);
new Thread(r).start();
cont++;
}
valido = false;
run.set(false);
}
}
答案 0 :(得分:0)
您正在使用旧的Location API。新的使用请求构建器。看一下教程here。
另请注意,您可以询问最后的已知位置。如果这就足够了,您甚至不必设置监听器。
如果您确实进入了回调序列,那么当您拥有一个满意的位置时,您只需隐藏听众。