在特定间隔后获取当前设备位置

时间:2011-12-02 06:08:56

标签: android

我希望在特定间隔(比如说30分钟)后捕获Android设备的当前位置(纬度和经度)。我的班级(或服务??不知道该使用什么)将开始收听LocationManagerListener时设备启动完成。实现这个的最佳方法是什么?我们如何在这种情况下使用locationChanged()方法?

我认为这是可以的:

侦听启动完成事件并设置警报服务:

public class OnBootReceiver extends BroadcastReceiver {
  private static final int PERIOD=1800000; // 30 minutes

  @Override
  public void onReceive(Context context, Intent intent) {

    AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    Intent i=new Intent(context, OnAlarmReceiver.class);
    PendingIntent pi=PendingIntent.getBroadcast(context, 0,
                                              i, 0);

    mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                      SystemClock.elapsedRealtime()+60000,
                      PERIOD,
                      pi);
  }
}

侦听警报服务并启动位置捕获类或服务:

 public class OnAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {    
      WakefulIntentService.acquireStaticLock(context);  
      context.startService(new Intent(context, locationCapture.class)); 
      or 
      new locationCapture().classmethod();
    }
    }

我不确定应该如何实现locationCapture类。它应该是普通的Java类还是Service类?

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:6)

这是您可以使用它的服务类

public class ServiceLocation extends Service{
    private LocationManager locMan;
    private Boolean locationChanged;
    private Handler handler = new Handler();

    public static Location curLocation;
    public static boolean isService = true;

    LocationListener gpsListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            if (curLocation == null) {
                curLocation = location;
                locationChanged = true;
            }else if (curLocation.getLatitude() == location.getLatitude() && curLocation.getLongitude() == location.getLongitude()){
                locationChanged = false;
                return;
            }else
                locationChanged = true;

            curLocation = location;

            if (locationChanged)
                locMan.removeUpdates(gpsListener);

        }
        public void onProviderDisabled(String provider) {
        }

        public void onProviderEnabled(String provider) {
        }

        public void onStatusChanged(String provider, int status,Bundle extras) {
            if (status == 0)// UnAvailable
            {
            } else if (status == 1)// Trying to Connect
            {
            } else if (status == 2) {// Available
            }
        }

    };

    @Override
    public void onCreate() {
        super.onCreate();

        curLocation = getBestLocation();

        if (curLocation == null) 
            Toast.makeText(getBaseContext(),"Unable to get your location", Toast.LENGTH_SHORT).show();
        else{
            //Toast.makeText(getBaseContext(), curLocation.toString(), Toast.LENGTH_LONG).show();
        }

        isService =  true;
    }
    final String TAG="LocationService";
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     return super.onStartCommand(intent, flags, startId);
   }
   @Override
   public void onLowMemory() {
       super.onLowMemory();
   }

   @Override
   public void onStart(Intent i, int startId){
      handler.postDelayed(GpsFinder,1);
   }

   @Override
   public void onDestroy() {
       handler.removeCallbacks(GpsFinder);
       handler = null;
       Toast.makeText(this, "Stop services", Toast.LENGTH_SHORT).show();
       isService = false;
   }

   public IBinder onBind(Intent arg0) {
         return null;
  }

  public Runnable GpsFinder = new Runnable(){
    public void run(){

        Location tempLoc = getBestLocation();
        if(tempLoc!=null)
            curLocation = tempLoc;
        tempLoc = null;
        handler.postDelayed(GpsFinder,1000);// register again to start after 1 seconds...        
    }
  };

    private Location getBestLocation() {
        Location gpslocation = null;
        Location networkLocation = null;

        if(locMan==null){
          locMan = (LocationManager) getApplicationContext() .getSystemService(Context.LOCATION_SERVICE);
        }
        try {
            if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){
                locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 1, gpsListener);// here you can set the 2nd argument time interval also that after how much time it will get the gps location
                gpslocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            }
            if(locMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000, 1, gpsListener);
                networkLocation = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
            }
        } catch (IllegalArgumentException e) {
            //Log.e(ErrorCode.ILLEGALARGUMENTERROR, e.toString());
            Log.e("error", e.toString());
        }
        if(gpslocation==null && networkLocation==null)
            return null;

        if(gpslocation!=null && networkLocation!=null){
            if(gpslocation.getTime() < networkLocation.getTime()){
                gpslocation = null;
                return networkLocation;
            }else{
                networkLocation = null;
                return gpslocation;
            }
        }
        if (gpslocation == null) {
            return networkLocation;
        }
        if (networkLocation == null) {
            return gpslocation;
        }
        return null;
    }
}

您可以将时间设置为处理程序或requestLocationUpdates()。你需要在家里开始这项服务。因为我已经在处理程序和requestLocationUpdate()中设置了1秒,以便在1秒后获取位置并更新我。

<强>编辑: 作为获取用户当前位置的服务,您可以从家庭活动开始,也可以从启动时间开始。通过家庭活动确定如果用户使用其他应用程序(例如任务杀手)停止服务,那么当用户启动您的应用程序然后从家中启动此服务将再次启动,启动服务您可以这样做

startService(new Intent(YourActivity.this,ServiceLocation.class));

当你需要停止服务时,它将调用onDestroy(),以便处理程序可以取消线程继续获取位置。

当GPS设置为1秒(1000)时,这将每1秒获得一次GPS位置,但是为了获得该位置,您需要每次呼叫,在我的情况下,我已设置为1秒并根据您的要求设置到30秒所以你gps每1秒获取一次位置并在处理程序中使用此服务设置30分钟。为了节省电池寿命,您还可以设置gps请求方法的不同时间,这样可以节省电池寿命。

您可以删除位置和当前位置的比较部分,因为locationlistener每次调用时都会更改位置,您可以在应用程序的任何位置使用curLocation来获取当前位置,但首先要确保必须启动此服务首先,然后在您可以使用之后,当您访问此对象的纬度和经度时,您将获得空指针异常

希望你有所了解,我得到了你的疑问的答案

答案 1 :(得分:0)

本指南包含各种API级别的源代码,来自:

http://android-developers.blogspot.com/search/label/Location