Make a timer/handler to get current location every

2019-05-25 00:07发布

问题:

I have this class to get actual location , the second point (marker) is set by another fragment.

I really need to update my location automatically instead clicking the google button for it. How can I make this? What is the best way to make this? I don´t figure out where to place it. I was thinking in placing a timer or something like that. I would prefer to make it with just google maps functionalities.

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

                    }
                }, 0, 500000);

Or with a handler

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

    handler.postDelayed(r, 300000 );

Here is the googleXdon class:

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;
    }   */
}

回答1:

First of all see this link which says to use a Handler to request one update with requestSingleUpdate() every 5 minutes.

Here is an example for the onLocationChanged()...

inside onCreate()

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

MyLocationListener class

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)
    {

    }                
}


回答2:

There is no any guarantee how often the location changes will come. And you can make it in two ways.

  1. You do not need to read the location every X seconds. Just save the last location from onLocationChanged() and use it on your timer ticks. You can also check if this location is different from the last used, if this matters

  2. The other way is to use LocationClient and its method getLastLocation(). You can use getLastLocation() in any time (after proper initialization), like every 5 sec.

Something like this:

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
               }
            });
         }
      }
}