Сделать таймер/обработчик для получения текущего местоположения каждые 5 секунд во фрагменте?

У меня есть этот класс, чтобы получить фактическое местоположение, вторая точка (маркер) устанавливается другим фрагментом.

Мне действительно нужно обновить свое местоположение автоматически, вместо того, чтобы нажимать для этого кнопку Google. Как я могу это сделать? Как лучше всего это сделать? Я не понимаю, где его разместить. Я думал поставить таймер или что-то в этом роде. Я бы предпочел сделать это только с функциями Google Maps.

Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    public void run() {

                    }
                }, 0, 500000);

Или с обработчиком

  final Runnable r = new Runnable() {
        public void run() {
    //Here add your code location listener call
    handler.postDelayed(this, 300000 );
        }
    };

    handler.postDelayed(r, 300000 );

Вот класс googleXdon:

package com.example.mysqltest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;


import org.json.JSONObject;

import android.content.Context;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;



public class googleXdon extends Fragment {

    static GoogleMap map;
    static LatLng myPosition;
    static RadioButton rbDriving;
    static RadioButton rbBiCycling;
    static RadioButton rbWalking;
    RadioGroup rgModes;
    static ArrayList<LatLng> markerPoints;
    static int mMode=0;
    final static int MODE_DRIVING=0;
    final static int MODE_BICYCLING=1;
    final static int MODE_WALKING=2;
    int fragVal;

    static Context ontext2;

    static googleXdon init(int val, Context contexts) {
        googleXdon X = new googleXdon();

        ontext2 = contexts;
       // Supply val input as an argument.
        Bundle args = new Bundle();
        args.putInt("val", val);
        X.setArguments(args);
        return X;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View layoutView = inflater.inflate(R.layout.actgooglex, container,
                false);

          fragVal = getArguments() != null ? getArguments().getInt("val") : 1;

        // Getting reference to rb_driving
        rbDriving = (RadioButton) layoutView.findViewById(R.id.rb_driving);

        // Getting reference to rb_bicylcing
        rbBiCycling = (RadioButton) layoutView.findViewById(R.id.rb_bicycling);

        // Getting reference to rb_walking
        rbWalking = (RadioButton) layoutView.findViewById(R.id.rb_walking);

        // Getting Reference to rg_modes
        rgModes = (RadioGroup) layoutView.findViewById(R.id.rg_modes);

        rgModes.setOnCheckedChangeListener(new OnCheckedChangeListener() {


            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {             

                // Checks, whether start and end locations are captured
                if(markerPoints.size() >= 2){                   
                    LatLng origin = markerPoints.get(0);
                    LatLng dest = markerPoints.get(1);

                    // Getting URL to the Google Directions API
                    String url = getDirectionsUrl(origin, dest);                

                    DownloadTask downloadTask = new DownloadTask();

                    // Start downloading json data from Google Directions API
                    downloadTask.execute(url);
                }           
            }
        });

        // Initializing 
        markerPoints = new ArrayList<LatLng>();

        // Getting reference to SupportMapFragment of the activity_main
        SupportMapFragment fm = (SupportMapFragment)getFragmentManager().findFragmentById(R.id.map);

        // Getting Map for the SupportMapFragment
        map = fm.getMap();

        // Enable MyLocation Button in the Map
        map.setMyLocationEnabled(true);     

        // Getting LocationManager object from System Service LOCATION_SERVICE
        /*LocationManager locationManager = (LocationManager) ontext2.getSystemService(Context.LOCATION_SERVICE);
        // Creating a criteria object to retrieve provider
        Criteria criteria = new Criteria();

        // Getting the name of the best provider
        String provider = locationManager.getBestProvider(criteria, true);

        // Getting Current Location
        Location location = locationManager.getLastKnownLocation(provider);

        if(location!=null) {
        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude = location.getLongitude();

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

         myPosition = new LatLng(latitude, longitude);

         markerPoints.add(myPosition);*/

        // Setting onclick event listener for the map
    /*  map.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {

                // Already two locations    value is 1          
                if(markerPoints.size()>1){
                    markerPoints.clear();
                    map.clear();                    
                }

                // Adding new item to the ArrayList
                markerPoints.add(point);                        

                // Draws Start and Stop markers on the Google Map
                drawStartStopMarkers();                             

                // Checks, whether start and end locations are captured
                if(markerPoints.size() >= 2){                   
                    LatLng origin = markerPoints.get(0);
                    LatLng dest = markerPoints.get(1);

                    // Getting URL to the Google Directions API
                    String url = getDirectionsUrl(origin, dest);                

                    DownloadTask downloadTask = new DownloadTask();

                    // Start downloading json data from Google Directions API
                    downloadTask.execute(url);
                }

            }
        }); 


        }*/
         return layoutView;
    }   

    //este antes no era final

    public static void agregarMarket( LatLng point) {


        // Already two locations                
        if(markerPoints.size()>1){
            markerPoints.clear();
            map.clear();                    
        }





        // Getting LocationManager object from System Service LOCATION_SERVICE
        LocationManager locationManager = (LocationManager) ontext2.getSystemService(Context.LOCATION_SERVICE);
        // Creating a criteria object to retrieve provider
        Criteria criteria = new Criteria();

        // Getting the name of the best provider
        String provider = locationManager.getBestProvider(criteria, true);

        // Getting Current Location
        Location location = locationManager.getLastKnownLocation(provider);



        if(location!=null) {
        // Getting latitude of the current location
        double latitude = location.getLatitude();

        // Getting longitude of the current location
        double longitude = location.getLongitude();

        // Creating a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

         myPosition = new LatLng(latitude, longitude);

         markerPoints.add(myPosition);

        // Adding new item to the ArrayList
        markerPoints.add(point);                        

        // Draws Start and Stop markers on the Google Map
        drawStartStopMarkers();                             

        // Checks, whether start and end locations are captured
        if(markerPoints.size() >= 2){                   
            LatLng origin = markerPoints.get(0);
            LatLng dest = markerPoints.get(1);

            // Getting URL to the Google Directions API
            String url = getDirectionsUrl(origin, dest);                

            DownloadTask downloadTask = new DownloadTask();

            // Start downloading json data from Google Directions API
            downloadTask.execute(url);
        }
        }


    }


    // Drawing Start and Stop locations
    private static void drawStartStopMarkers(){

        for(int i=0;i<markerPoints.size();i++){

            // Creating MarkerOptions
            MarkerOptions options = new MarkerOptions();            


            // Setting the position of the marker
            options.position(markerPoints.get(i) );

            /** 
             * For the start location, the color of marker is GREEN and
             * for the end location, the color of marker is RED.
             */
            if(i==0){
                options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
            }else if(i==1){
                options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
            }           

            // Add new marker to the Google Map Android API V2
            map.addMarker(options);
        }       
    }


    private static String getDirectionsUrl(LatLng origin,LatLng dest){

        // Origin of route
        String str_origin = "origin="+origin.latitude+","+origin.longitude;

        // Destination of route
        String str_dest = "destination="+dest.latitude+","+dest.longitude;  

        // Sensor enabled
        String sensor = "sensor=false";         

        // Travelling Mode
        String mode = "mode=driving";   

        if(rbDriving.isChecked()){
            mode = "mode=driving";
            mMode = 0 ;
        }else if(rbBiCycling.isChecked()){
            mode = "mode=bicycling";
            mMode = 1;
        }else if(rbWalking.isChecked()){
            mode = "mode=walking";
            mMode = 2;
        }


        // Building the parameters to the web service
        String parameters = str_origin+"&"+str_dest+"&"+sensor+"&"+mode;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;


        return url;
    }

    /** A method to download json data from url */
    private static String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
                URL url = new URL(strUrl);

                // Creating an http connection to communicate with url 
                urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url 
                urlConnection.connect();

                // Reading data from url 
                iStream = urlConnection.getInputStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

                StringBuffer sb  = new StringBuffer();

                String line = "";
                while( ( line = br.readLine())  != null){
                        sb.append(line);
                }

                data = sb.toString();

                br.close();

        }catch(Exception e){
                Log.d("Exception while downloading url", e.toString());
        }finally{
                iStream.close();
                urlConnection.disconnect();
        }
        return data;
     }



    // Fetches data from url passed
    static class DownloadTask extends AsyncTask<String, Void, String>{          

        // Downloading data in non-ui thread
        @Override
        protected String doInBackground(String... url) {

            // For storing data from web service
            String data = "";

            try{
                // Fetching the data from web service
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;        
        }

        // Executes in UI thread, after the execution of
        // doInBackground()
        @Override
        protected void onPostExecute(String result) {           
            super.onPostExecute(result);            

            ParserTask parserTask = new ParserTask();

            // Invokes the thread for parsing the JSON data
            parserTask.execute(result);

        }       
    }

    /** A class to parse the Google Places in JSON format */
    static class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{

        // Parsing the data in non-ui thread        
        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

            JSONObject jObject; 
            List<List<HashMap<String, String>>> routes = null;                     

            try{
                jObject = new JSONObject(jsonData[0]);
                DirectionsJSONParser parser = new DirectionsJSONParser();

                // Starts parsing data
                routes = parser.parse(jObject);    
            }catch(Exception e){
                e.printStackTrace();
            }
            return routes;
        }

        // Executes in UI thread, after the parsing process
        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {
            ArrayList<LatLng> points = null;
            PolylineOptions lineOptions = null;
            MarkerOptions markerOptions = new MarkerOptions();

            // Traversing through all the routes
            for(int i=0;i<result.size();i++){
                points = new ArrayList<LatLng>();
                lineOptions = new PolylineOptions();

                // Fetching i-th route
                List<HashMap<String, String>> path = result.get(i);

                // Fetching all the points in i-th route
                for(int j=0;j<path.size();j++){
                    HashMap<String,String> point = path.get(j);                 

                    double lat = Double.parseDouble(point.get("lat"));
                    double lng = Double.parseDouble(point.get("lng"));
                    LatLng position = new LatLng(lat, lng); 

                    points.add(position);                       
                }

                // Adding all the points in the route to LineOptions
                lineOptions.addAll(points);
                lineOptions.width(2);

                // Changing the color polyline according to the mode
                if(mMode==MODE_DRIVING)
                    lineOptions.color(Color.RED);
                else if(mMode==MODE_BICYCLING)
                    lineOptions.color(Color.GREEN);
                else if(mMode==MODE_WALKING)
                    lineOptions.color(Color.BLUE);              
            }

            if(result.size()<1){
                Toast.makeText(ontext2, "No Points", Toast.LENGTH_SHORT).show();
                return;
            }

            // Drawing polyline in the Google Map for the i-th route
            map.addPolyline(lineOptions);

        }           
    }   

    /*@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }   */
}

person Arnoldo Bazaldua    schedule 15.05.2014    source источник
comment
См. эту ссылку, которая поможет вам получить текущее местоположение автоматически... Используйте полученное местоположение для установки маркера на Картах..   -  person Lal    schedule 15.05.2014
comment
LocationManager или LocationClient могут доставлять вам обновления местоположения по мере изменения местоположения (например, requestLocationUpdates() на LocationManager). Вам не нужно проводить опрос.   -  person CommonsWare    schedule 15.05.2014
comment
Посмотрите на Fused Location Provider, на мой взгляд, лучший метод, доступный для Android, для получения обновлений местоположения.   -  person zgc7009    schedule 15.05.2014


Ответы (2)


Прежде всего, посмотрите эту ссылку, в которой говорится об использовании обработчика для запроса одного обновления с requestSingleUpdate() каждые 5 минут.

Вот пример для onLocationChanged()...

внутри onCreate()

mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();                             
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);

Класс MyLocationListener

public class MyLocationListener implements LocationListener
{

    @Override
    public void onLocationChanged(Location location)
    {                         

          //Set marker here
          LatLng pos=new LatLng(location.getLatitude(), location.getLongitude());
           map.addMarker(new MarkerOptions().position(pos).icon(BitmapDescriptorFactory.fromResource(markericon)));

    }

    @Override
    public void onProviderDisabled(String provider)
    {

    }

    @Override
    public void onProviderEnabled(String provider)
    {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras)
    {

    }                
}
person Lal    schedule 15.05.2014
comment
В течение 5 секунд он может использовать locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, mlocListener); - person Lal; 15.05.2014
comment
duuuud Я пробовал с вашим LocationListener, но думаю, что это не сработало!! pastebin.com/A1YRXYsg - person Arnoldo Bazaldua; 15.05.2014
comment
Я реализую это в том же классе, также я печатаю местоположение, но не делаю никаких изменений: C - person Arnoldo Bazaldua; 15.05.2014
comment
Что такое googleXdon() в вашем классе????mlocListener = new MyLocationListener(); отсутствует в вашем коде.. - person Lal; 16.05.2014

Нет никаких гарантий, как часто будет происходить смена местоположения. И сделать это можно двумя способами.

  1. Вам не нужно читать местоположение каждые X секунд. Просто сохраните последнее местоположение из onLocationChanged() и используйте его в своих тиках таймера. Вы также можете проверить, отличается ли это местоположение от последнего использованного, если это имеет значение

  2. Другой способ — использовать LocationClient и его метод getLastLocation(). Вы можете использовать getLastLocation() в любое время (после правильной инициализации), например, каждые 5 секунд.

Что-то вроде этого:

timer.scheduleAtFixedRate( new UpdateLocationTask(), 1000, 5000 );

class UpdateLocationTask extends TimerTask
{
   public void run()
      {
      final Location location = mLocationClient.getLastLocation();
      if ( location != null )
         {
         runOnUiThread( new Runnable()
            {
            public void run()
               {
               // do whatever you want here
               }
            });
         }
      }
}
person ggurov    schedule 15.05.2014
comment
Я добавил код для второго пункта. Для работы с LocationClient проверьте это: developer.android.com/training/location/retrieve -current.html - person ggurov; 16.05.2014