3

我正在尝试定期提取位置并通过网络发送。在此之前,我觉得验证我是否正确拉动位置很重要!为此,我尝试提取该位置并向在屏幕上显示的处理程序发送一条消息。我到处搜索,实际上在堆栈溢出时使用了一个非常有用的代码段(非常感谢!)在 Android 上获取用户当前位置的最简单、最可靠的方法是什么?

继承人一些代码:

MyLocation(来自示例):

package com.Locator;

import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled=false;
boolean network_enabled=false;

public boolean getLocation(Context context, LocationResult result)
{
    //I use LocationResult callback class to pass location value from MyLocation to user code.
    locationResult=result;
    if(lm==null)
        lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

    //exceptions will be thrown if provider is not permitted.
    try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
    try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}

    //don't start listeners if no provider is enabled
    if(!gps_enabled && !network_enabled)
        return false;

    if(gps_enabled)
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
    if(network_enabled)
        lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
    timer1=new Timer();
    timer1.schedule(new GetLastLocation(), 20000);
    return true;
}

LocationListener locationListenerGps = new LocationListener() {
    public void onLocationChanged(Location location) {
        timer1.cancel();
        locationResult.gotLocation(location);
        lm.removeUpdates(this);
        lm.removeUpdates(locationListenerNetwork);
    }
    public void onProviderDisabled(String provider) {}
    public void onProviderEnabled(String provider) {}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
};

LocationListener locationListenerNetwork = new LocationListener() {
    public void onLocationChanged(Location location) {
        timer1.cancel();
        locationResult.gotLocation(location);
        lm.removeUpdates(this);
        lm.removeUpdates(locationListenerGps);
    }
    public void onProviderDisabled(String provider) {}
    public void onProviderEnabled(String provider) {}
    public void onStatusChanged(String provider, int status, Bundle extras) {}
};

class GetLastLocation extends TimerTask {
    @Override
    public void run() {
         lm.removeUpdates(locationListenerGps);
         lm.removeUpdates(locationListenerNetwork);

         Location net_loc=null, gps_loc=null;
         if(gps_enabled)
             gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
         if(network_enabled)
             net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

         //if there are both values use the latest one
         if(gps_loc!=null && net_loc!=null){
             if(gps_loc.getTime()>net_loc.getTime())
                 locationResult.gotLocation(gps_loc);
             else
                 locationResult.gotLocation(net_loc);
             return;
         }

         if(gps_loc!=null){
             locationResult.gotLocation(gps_loc);
             return;
         }
         if(net_loc!=null){
             locationResult.gotLocation(net_loc);
             return;
         }
         locationResult.gotLocation(null);
    }
}

public static abstract class LocationResult{
    public abstract void gotLocation(Location location);
}
}

现在,当我像这样使用它时,它可以正常工作(以下是 Main 活动类中的代码):

    MyLocation myLocation = new MyLocation();



    LocationResult locationResult = new LocationResult(){
        @Override
        public void gotLocation(final Location location){
           Message m = new Message();
           m.obj = location.getLongitude() + " " + location.getLattitude();
           threadHandler.sendMessage(m);
        }
    };

但是我想定期执行此操作,所以我有这样的事情(以下代码在主活动类中,这次实现 Runnable):

....
new Thread(this).start();
....

public void run() {
    MyLocation myLocation = new MyLocation();



    LocationResult locationResult = new LocationResult(){
        @Override
        public void gotLocation(final Location location){
           Message m = new Message();
           m.obj = "SDFSDF";
           threadHandler.sendMessage(m);
        }
    };

    while(true) {

        myLocation.getLocation(this, locationResult);
        try {
        Thread.sleep(30000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
      }
}
}

注意:threadHandler 属于 MyHandler 类型,定义如下:

class MyHandler extends Handler{

private TextView threadModifiedText;
public MyHandler(TextView tv) {
    threadModifiedText = tv;
}

 public void handleMessage(Message msg) {
        // whenever the Thread notifies this handler we have
        // only this behavior
        threadModifiedText.setText((CharSequence)msg.obj);
 }
}

我收到有关从尚未调用 Looper.prepare() 的线程写入处理程序的错误。我尝试在我的活动和线程的各个部分添加 Looper.prepare() 和 Looper.loop() 无济于事。我尝试使用计时器而不是 run() + sleep()。

稍后,我将将该位置插入队列,而不是写入线程处理程序。另一个处理套接字连接的线程将检查队列是否为空。如果它有一个元素,它将 dequeue() 并将其发送出去。

请给我一些建议。

4

1 回答 1

1

以防万一你没有发现。looper 应该不在 while 中,您应该在每次新调用之前重新初始化 myLocation。但是在这种情况下,MyLocation 类中的计时器将阻止它工作。因此,如果您删除 getLastLocation 部分,它应该可以在您的服务中正常工作。我想如果您想定期发送位置,您宁愿准确,而且您不在乎是否需要多花 30 秒,所以无论如何这不是一个坏方法。但是,如果在未启用 gps 和网络时抛出异常,您需要做一些事情(打开首选项)

祝你好运。

Looper.prepare();   

while(true) {
    myLocation = new MyLocatiom()
    myLocation.getLocation(this, locationResult);
    try {Thread.sleep(30000);} catch (InterruptedException e) {}

Looper.loop()
  }
于 2011-12-10T18:43:46.543 回答