6

I have an app in which I am continuously tracking user's location using Google Plays new service API for Maps. I am updating the location every single second and I am also checking user activity like STILL, TILTING, IN VEHICLE, etc to get the better location tracking. I am able to draw a path using my code but it's not accurate and differs very much from the road where the user actually drives/walk. It always draws the line someway far from the actual user's path.

My Service:-

public class MyService extends Service implements LocationListener {

    private final Context mContext;
    private static MyService mInstance = null;
    private final static String TAG = "RidingTimerService";

    boolean isGPSEnabled = false;

    private long mStartTime = 0L;
    private long timeInMilliseconds = 0L;
    private long timeSwapBuff = 0L;
    private long updatedTime = 0L;
    private Handler mHandler = null;
    private int mHours = 0;

    // Declaring a Location Manager
    private LocationManager mLocationManager = null;
    private Location mCurrentLocation = null; // location
    private double[][] positions;
    private long[] times;
    private final Integer data_points = 2; // how many data points to calculate
    private double mTravelledDistance = 0.0f;

    private SharedPreferences mPreferences = null;
    private ArrayList<LatLng> mDirectionsPoints = new ArrayList<LatLng>();

    public boolean mIsPhoneMoving = false;
    public int mActivityType = -1;
    int counter = 0;

    private IntentFilter mBroadcastFilter;
    private DetectionRequester mDetectionRequester;
    private DetectionRemover mDetectionRemover;

    public MyService() {
        mContext = this;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        // two arrays for position and time.
        positions = new double[data_points][2];
        times = new long[data_points];

        mStartTime = SystemClock.uptimeMillis();
        mHandler = new Handler();
        mHandler.postDelayed(countDownTimerThread, 0);
        mPreferences = getSharedPreferences(MyPreferences.PREFERENCES,
                Context.MODE_PRIVATE);
        // Create a new Intent filter for the broadcast receiver
        mBroadcastFilter = new IntentFilter(
                MyConstants.ACTION_REFRESH_STATUS_LIST);
        mBroadcastFilter.addCategory(MyConstants.CATEGORY_LOCATION_SERVICES);

        // Get detection requester and remover objects
        mDetectionRequester = new DetectionRequester(this);
        mDetectionRemover = new DetectionRemover(this);
        mDirectionsPoints.clear();
    }

    /**
     * Pause the timer
     */
    public void pauseRide() {
        timeSwapBuff += timeInMilliseconds;
        mHandler.removeCallbacks(countDownTimerThread);
        mLocationManager.removeUpdates(this);
    }

    /**
     * Restart the timer
     */
    public void reStartRide() {
        mStartTime = SystemClock.uptimeMillis();
        mHandler.postDelayed(countDownTimerThread, 0);
        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                0, 0, this);
    }

    @Override
    public void onDestroy() {
        mHandler.removeCallbacks(countDownTimerThread);
        mLocationManager.removeUpdates(this);
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        getLocation();
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * Timer thread
     */
    private final Runnable countDownTimerThread = new Runnable() {

        public void run() {
            mHours = 0;
            timeInMilliseconds = SystemClock.uptimeMillis() - mStartTime;
            updatedTime = timeSwapBuff + timeInMilliseconds;
            int secs = (int) (updatedTime / 1000);
            final int mins = secs / 60;
            mHours = mins / 60;
            secs = secs % 60;

            final Message msg = new Message();
            final Bundle bundle = new Bundle();
            bundle.putInt(MyPreferences.BROADCAST_CODES, 300);
            bundle.putString(
                    "time",
                    String.format("%02d", mHours) + ":"
                            + String.format("%02d", mins) + ":"
                            + String.format("%02d", secs));
            msg.setData(bundle);
            final Intent intent = new Intent(MyConstants.BROADCAST_INTENT);
            intent.putExtras(bundle);
            sendBroadcast(intent);
            mHandler.postDelayed(this, 1000);
        }
    };

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

    @Override
    public void onLocationChanged(final Location location) {
        if (location != null) {
            LocationUtils.sLatitude = location.getLatitude();
            LocationUtils.sLongitude = location.getLongitude();

            mDirectionsPoints.add(new LatLng(LocationUtils.sLatitude,
                    LocationUtils.sLongitude));
            riderLocation(location);
        } else {
            Log.i(TAG, "Location is not available.");
        }
    }

    /**
     * Calculate speed, distance and average speed. Send Broadcast which
     * received by activities
     * 
     * @param location
     */
    private void riderLocation(final Location location) {
        DecimalFormat formatter = new DecimalFormat("#0.00");
        double distance = 0.0;
        Double speed = 0.0;
        long t1 = 0l;
        final float[] results = new float[3];

        positions[counter][0] = location.getLatitude();
        positions[counter][1] = location.getLongitude();
        times[counter] = location.getTime();

        final Bundle bundle = new Bundle();
        bundle.putInt(MyPreferences.BROADCAST_CODES, 200);

        distance = calculateDistance(positions[counter][0],
                positions[counter][1], positions[(counter + (data_points - 1))
                        % data_points][0],
                positions[(counter + (data_points - 1)) % data_points][1]);

        Location.distanceBetween(positions[counter][0], positions[counter][1],
                positions[(counter + (data_points - 1)) % data_points][0],
                positions[(counter + (data_points - 1)) % data_points][1],
                results);

        mTravelledDistance += results[0] / 1000;
        LocationUtils.sDistance = formatter
                .format((mTravelledDistance * 100.0) / 100.0);

        final double averageSpeed = mTravelledDistance / mHours;
        LocationUtils.sAverageSpeed = formatter
                .format((averageSpeed * 100.0) / 100.0);

        if (location.hasSpeed()) {
            speed = location.getSpeed() * 3.6;
            LocationUtils.sSpeed = speed.intValue();
        } else {
            try {
                t1 = times[counter]
                        - times[(counter + (data_points - 1)) % data_points];
            } catch (final NullPointerException e) {
                // all good, just not enough data yet.
            }

            speed = (distance / t1) * 3.6;
            LocationUtils.sSpeed = speed.intValue();
            counter = (counter + 1) % data_points;
        }

        LocationUtils.sLatitude = location.getLatitude();
        LocationUtils.sLongitude = location.getLongitude();

        final Intent intent = new Intent(MyConstants.BROADCAST_INTENT);
        intent.putExtras(bundle);
        sendBroadcast(intent);
    }

    public void onProviderDisabled(final String arg0) {
        Toast.makeText(getApplicationContext(), "Gps Disabled",
                Toast.LENGTH_LONG).show();
    }

    public void onProviderEnabled(final String arg0) {
        Toast.makeText(getApplicationContext(), "Gps Enabled",
                Toast.LENGTH_SHORT).show();
    }

    /**
     * @return location
     */
    public Location getLocation() {
        try {
            mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = mLocationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            if (!isGPSEnabled) {
                // no network provider is enabled
                showSettingsAlert();
            } else {
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    mLocationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER, 0, 0, this);
                    Log.d(TAG, "GPS Enabled");
                    if (mCurrentLocation == null) {
                        if (mLocationManager != null) {
                            mCurrentLocation = mLocationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);

                            if (mCurrentLocation != null) {
                                LocationUtils.sLatitude = mCurrentLocation
                                        .getLatitude();
                                LocationUtils.sLongitude = mCurrentLocation
                                        .getLongitude();
                            }
                        }
                    } else {
                        LocationUtils.sLatitude = mCurrentLocation
                                .getLatitude();
                        LocationUtils.sLongitude = mCurrentLocation
                                .getLongitude();
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return mCurrentLocation;
    }

    /**
     * @fn public static RidingTimerService getInstance()
     * @brief returns instance of the service.
     * @return RidingTimerService instance
     */
    public static MyService getInstance() {
        return mInstance;
    }

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

    /**
     * Reset all the values stored in Preferences
     */
    public void resetAllText() {
        mPreferences.edit().putString(MyPreferences.LATITUDE, "0.0").commit();
        mPreferences.edit().putString(MyPreferences.LONGITUDE, "0.0")
                .commit();
        mPreferences.edit().putString(MyPreferences.SPEED, "0.0").commit();
        mPreferences.edit().putString(MyPreferences.AVERAGE_SPEED, "0.0")
                .commit();
        mPreferences.edit().putString(MyPreferences.DISTANCE, "0.0").commit();
    }

    /**
     * Respond to "Start" button by requesting activity recognition updates.
     * 
     * @param view
     *            The view that triggered this method.
     */
    public void onStartUpdates() {
        // Pass the update request to the requester object
        mDetectionRequester.requestUpdates();
    }

    /**
     * Respond to "Stop" button by canceling updates.
     * 
     * @param view
     *            The view that triggered this method.
     */
    public void onStopUpdates() {
        // Pass the remove request to the remover object
        mDetectionRemover.removeUpdates(mDetectionRequester
                .getRequestPendingIntent());

        /*
         * Cancel the PendingIntent. Even if the removal request fails,
         * canceling the PendingIntent will stop the updates.
         */
        mDetectionRequester.getRequestPendingIntent().cancel();
    }

    /**
     * Function to show settings alert dialog On pressing Settings button will
     * lauch Settings Options
     * */
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
        alertDialog.setTitle("GPS");
        alertDialog.setMessage("GPS is not enabled. Do you want to enable it?");

        // On pressing Settings button
        alertDialog.setPositiveButton("Settings",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        mContext.startActivity(intent);
                    }
                });

        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        alertDialog.show();
    }

    /**
     * @return List of Direction points
     */
    public ArrayList<LatLng> getDirectionsPoints() {
        if (mDirectionsPoints != null) {
            return mDirectionsPoints;
        } else {
            mDirectionsPoints = new ArrayList<LatLng>();
            return mDirectionsPoints;
        }
    }

    /**
     * Calculate distance
     * 
     * @param lat1
     * @param lon1
     * @param lat2
     * @param lon2
     * @return
     */
    private double calculateDistance(final double lat1, final double lon1,
            final double lat2, final double lon2) {
        // haversine great circle distance approximation, returns meters
        final double theta = lon1 - lon2;
        double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2))
                + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2))
                * Math.cos(deg2rad(theta));
        dist = Math.acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60; // 60 nautical miles per degree of seperation
        dist = dist * 1852; // 1852 meters per nautical mile
        return dist;
    }

    private double deg2rad(final double deg) {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(final double rad) {
        return (rad * 180.0 / Math.PI);
    }
}

I kept location updates every 1 seconds and activity recognition updates every 3 seconds. I am able to get the location but path is not drawn properly in Google maps.

Code to draw path :-

public class MapsActivity extends FragmentActivity {

    private static GoogleMap mGoogleMap = null;
    private static final String TAG = "MapsActivity";
    private Button mBtnStartRide, mBtnPauseRide, mBtnStopRide = null;
    private static TextView mTxtLatLong, mTxtTimer, mTxtTotalSize,
            mTxtSpeed = null;
    private static PolylineOptions mPolyLineOptions = null;
    // Storing the directions returned by the direcction api
    private SharedPreferences mPreferences = null;
    private MapsBroadcastReceiver receiver = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

        receiver = new MapsBroadcastReceiver();
        mPreferences = getSharedPreferences(TestPreferences.PREFERENCES,
                Context.MODE_PRIVATE);

        mTxtLatLong = (TextView) findViewById(R.id.txtLatLong);
        mTxtTimer = (TextView) findViewById(R.id.txtTimer);
        mTxtTotalSize = (TextView) findViewById(R.id.txtDirectionsSize);
        mTxtSpeed = (TextView) findViewById(R.id.txtSpeed);

        mBtnStartRide = (Button) findViewById(R.id.btn_start_ride);
        mBtnPauseRide = (Button) findViewById(R.id.btn_pause_ride);
        mBtnStopRide = (Button) findViewById(R.id.btn_stop_ride);

        final Button mBtnCenter = (Button) findViewById(R.id.btn_center);
        mBtnCenter.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                animateCameraTo();
            }
        });

        mBtnStartRide.setOnClickListener(btnStartRideClickListener);
        mBtnPauseRide.setOnClickListener(btnPauseRideClickListener);
        mBtnStopRide.setOnClickListener(btnStopRideClickListener);

        initilizeMap();
    }

    /**
     * Start Ride Button Click Listener
     */
    private OnClickListener btnStartRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (mPreferences.getBoolean(TestPreferences.IS_RIDE_PAUSE, false)) {
                if (MyService.getInstance() != null) {
                    MyService.getInstance().reStartRide();
                }
            } else {
                startService(new Intent(MapsActivity.this,
                        MyService.class));
            }

            mPreferences.edit().putBoolean(TestPreferences.IS_RIDE_START, true)
                    .commit();
            mPreferences.edit().remove(TestPreferences.IS_RIDE_PAUSE).commit();
            mPreferences.edit().remove(TestPreferences.IS_RIDE_STOPPED)
                    .commit();

            mBtnStartRide.setVisibility(View.GONE);
            mBtnPauseRide.setVisibility(View.VISIBLE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        }
    };

    /**
     * Start Ride Button Click Listener
     */
    private OnClickListener btnPauseRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            MyService.getInstance().pauseRide();

            mPreferences.edit().putBoolean(TestPreferences.IS_RIDE_PAUSE, true)
                    .commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_START, false).commit();
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        }
    };

    /**
     * Stop Ride Button Click Listener
     */
    private OnClickListener btnStopRideClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            stopService(new Intent(MapsActivity.this, MyService.class));
            mPreferences.edit().remove(TestPreferences.IS_RIDE_PAUSE).commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_START, false).commit();
            mPreferences.edit()
                    .putBoolean(TestPreferences.IS_RIDE_STOPPED, true).commit();
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receiver, new IntentFilter(
                MyConstants.BROADCAST_INTENT));
        initilizeMap();

        if (mPreferences.getBoolean(TestPreferences.IS_RIDE_START, false)) {
            mBtnStartRide.setVisibility(View.GONE);
            mBtnPauseRide.setVisibility(View.VISIBLE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        } else if (mPreferences
                .getBoolean(TestPreferences.IS_RIDE_PAUSE, false)) {
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.VISIBLE);
        } else if (mPreferences.getBoolean(TestPreferences.IS_RIDE_STOPPED,
                false)) {
            // Show start button and gone Pause & Stop both
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        } else {
            // Show start button and gone Pause & Stop both
            mBtnStartRide.setVisibility(View.VISIBLE);
            mBtnPauseRide.setVisibility(View.GONE);
            mBtnStopRide.setVisibility(View.GONE);
        }

        setAllText();
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mGoogleMap = null;
    }

    /**
     * Function to load map. If map is not created it will create it for you
     * */
    private void initilizeMap() {
        if (mGoogleMap == null) {
            mGoogleMap = ((MapFragment) getFragmentManager().findFragmentById(
                    R.id.map)).getMap();
            // check if map is created successfully or not
            if (mGoogleMap == null) {
                Toast.makeText(getApplicationContext(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            } else {
                mPolyLineOptions = new PolylineOptions().width(6).color(
                        Color.BLUE);
                mGoogleMap.setTrafficEnabled(true);
                mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
                mGoogleMap.getUiSettings().setRotateGesturesEnabled(true);
                mGoogleMap.getUiSettings().setCompassEnabled(true);
                mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
                mGoogleMap.getUiSettings().setZoomControlsEnabled(true);

                if (MyService.getInstance() != null
                        && MyService.getInstance().getDirectionsPoints() != null
                        && !MyService.getInstance().getDirectionsPoints()
                                .isEmpty()
                        && MyService.getInstance().getDirectionsPoints()
                                .size() >= 1) {
                    mGoogleMap.addMarker(new MarkerOptions()
                            .position(
                                    MyService.getInstance()
                                            .getDirectionsPoints().get(0))
                            .anchor(0.8f, 1.0f).title("Your Location"));

                    animateCameraTo(MyService.getInstance()
                            .getDirectionsPoints().get(0).latitude,
                            MyService.getInstance().getDirectionsPoints()
                                    .get(0).longitude);
                }
            }
        } else {
            mPolyLineOptions = new PolylineOptions().width(6).color(Color.BLUE);
            mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
            mGoogleMap.getUiSettings().setRotateGesturesEnabled(true);
            mGoogleMap.getUiSettings().setCompassEnabled(true);
            mGoogleMap.getUiSettings().setZoomGesturesEnabled(true);
            mGoogleMap.getUiSettings().setZoomControlsEnabled(true);

            if (MyService.getInstance() != null
                    && MyService.getInstance().getDirectionsPoints() != null
                    && !MyService.getInstance().getDirectionsPoints()
                            .isEmpty()
                    && MyService.getInstance().getDirectionsPoints().size() >= 1) {

                Log.i(TAG, "Lat long in resume2222222222 = "
                        + MyService.getInstance().getDirectionsPoints()
                                .get(0).latitude
                        + ", "
                        + MyService.getInstance().getDirectionsPoints()
                                .get(0).longitude);

                mGoogleMap.addMarker(new MarkerOptions()
                        .position(
                                MyService.getInstance().getDirectionsPoints()
                                        .get(0)).anchor(0.8f, 1.0f)
                        .title("Your Location"));

                animateCameraTo(MyService.getInstance().getDirectionsPoints()
                        .get(0).latitude, MyService.getInstance()
                        .getDirectionsPoints().get(0).longitude);
            }
        }
    }

    /**
     * @author Scorpion
     * 
     */
    private class MapsBroadcastReceiver extends BroadcastReceiver {

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

            switch (intent.getExtras().getInt(TestPreferences.BROADCAST_CODES)) {
            case 100:
                showErrorDialog(intent.getExtras().getInt(
                        TestPreferences.BROADCAST_CODES));
                break;

            case 200:
                setAllText();
                break;

            case 300:
                if (intent.getExtras().getString("time") != null) {
                    mTxtTimer.setText("Timer - "
                            + intent.getExtras().getString("time"));
                } else {
                    mTxtTimer.setText("Timer - 00:00:00");
                }
                break;

            default:
                break;
            }

            if (MyService.getInstance() != null
                    && !MyService.getInstance().getDirectionsPoints()
                            .isEmpty()
                    && MyService.getInstance().getDirectionsPoints().size() == 1) {
                mGoogleMap.addMarker(new MarkerOptions()
                        .position(
                                MyService.getInstance().getDirectionsPoints()
                                        .get(0)).anchor(0.8f, 1.0f)
                        .title("Your Location"));
            }

        }
    }

    /**
     * 
     */
    public void setAllText() {
        mTxtLatLong.setText("Lat - " + LocationUtils.sLatitude + ", Lng - "
                + LocationUtils.sLongitude);

        mTxtSpeed.setText("Speed - " + LocationUtils.sSpeed);
        mTxtTotalSize.setText("Distance - " + LocationUtils.sDistance);
    }

    /**
     * Animate to position on Google Maps
     * 
     * @param lat
     * @param lng
     */
    private void animateCameraTo() {
        // Saving the points in a polyline

        if (MyService.getInstance() != null
                && MyService.getInstance().getDirectionsPoints() != null
                && !MyService.getInstance().getDirectionsPoints().isEmpty()) {
            mPolyLineOptions.geodesic(true);
            mPolyLineOptions.addAll(MyService.getInstance()
                    .getDirectionsPoints());

            // Drawing the path on the map Polyline route =
            mGoogleMap.addPolyline(mPolyLineOptions);

            int index = MyService.getInstance().getDirectionsPoints().size() - 1;
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(MyService.getInstance().getDirectionsPoints()
                            .get(index)).zoom(20).build();

            mGoogleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));
        }

    }

    /**
     * Animate to position on Google Maps
     * 
     * @param lat
     * @param lng
     */
    private void animateCameraTo(final double lat, final double lng) {
        // Saving the points in a polyline
        if (MyService.getInstance() != null
                && MyService.getInstance().getDirectionsPoints() != null
                && !MyService.getInstance().getDirectionsPoints().isEmpty()) {
            mPolyLineOptions.geodesic(true);
            mPolyLineOptions.addAll(MyService.getInstance()
                    .getDirectionsPoints());

            // Drawing the path on the map
            mGoogleMap.addPolyline(mPolyLineOptions);
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(lat, lng)).zoom(20).build();

            mGoogleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));
        }

    }

    /**
     * Show a dialog returned by Google Play services for the connection error
     * code
     * 
     * @param errorCode
     *            An error code returned from onConnectionFailed
     */
    private void showErrorDialog(int errorCode) {

        // Get the error dialog from Google Play services
        Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
                MapsActivity.this,
                LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

        // If Google Play services can provide an error dialog
        if (errorDialog != null) {

            // Create a new DialogFragment in which to show the error dialog
            ErrorDialogFragment errorFragment = new ErrorDialogFragment();

            // Set the dialog in the DialogFragment
            errorFragment.setDialog(errorDialog);

            // Show the error dialog in the DialogFragment
            errorFragment.show(getSupportFragmentManager(),
                    LocationUtils.APPTAG);
        }
    }
}

Coordinate results got from Location provider :- 23.030392522689674, 72.5570888165469, 23.030408166940184, 72.55708600340783, 23.030451207802273, 72.55708215400317, 23.030448342522195, 72.5570607428365, 23.03045605637773, 72.55702903413072, 23.03046687434995, 72.55702007867455, 23.030481227996425, 72.55702017125606, 23.03049188235562, 72.55701618151457, 23.030501580461667, 72.55701051075931, 23.030506644074638, 72.55700568837983, 23.030510243171772, 72.55699463185964, 23.03051656621021, 72.55698811382064, 23.030523584332027, 72.55698589863236, 23.030527893257556, 72.5569835596, 23.03052731568596, 72.55698681171178, 23.030533706759005, 72.55699683791043, 23.03053795413862, 72.5570022232021, 23.03054422659466, 72.55700788646914, 23.030550353227323, 72.5570133047868, 23.03056167617575, 72.5570171806126, 23.030572274532982, 72.55702744953462, 23.03057623596164, 72.55703687229187, 23.03058756510295, 72.55703589208271, 23.030591797598742, 72.5570396833694, 23.030597556470788, 72.55703954449652, 23.030602030769657, 72.55704359454182, 23.030606735158617, 72.55704993131606, 23.030611670633565, 72.55705060538087,23.030618875802222, 72.55705181604097, 23.030629137631596, 72.55705043471286, 23.030651405170016, 72.55705440295588, 23.03066642161307, 72.55705285209174, 23.030690454277963, 72.55703884780276, 23.030708214416187, 72.55703489882957, 23.03072341369183, 72.5570340196122, 23.030737371000015, 72.55703289416898, 23.03075088423441, 72.55703750535102, 23.030767572625837, 72.55704489874579, 23.030794398930176, 72.55703870239826, 23.03081655932613, 72.55702474270966, 23.030827505666753, 72.5570121351611, 23.03083720431765, 72.55700390084714, 23.03084624667527, 72.55700122660554, 23.030859495795887, 72.55699948514881, 23.030870357210333, 72.55699625144317, 23.030881843633054

Daniel
  • 2,744
  • 1
  • 31
  • 41
Scorpion
  • 6,831
  • 16
  • 75
  • 123
  • Its a bit difficult with a lot of coding most probably not related to the problem. But the usage of the static fields of LocationUtils is very suspicious. If this class is used by different threads simultaneously the resulting coordinates are unpredictable. – user2808624 Dec 16 '13 at 19:07
  • I have used LocationUtils class to store Speed, Distance, Location (Lat/Lng) and these values are used by other activities. So i agree that these values are used simultaneously but only my service is writing values in it, other activities and classes are only reading these values to display it. Nothing else... – Scorpion Dec 17 '13 at 05:56
  • Did you check, how often onLocationChanged is called for one GPS-update? I am not sure what happens if the same LocationListener is registered multiple times (as it is the case in your service). I remember that I had somehow managed to be called multiple times. But I cannot remember, whether it was the same situation or whether I created multiple instances of LocationListeners by accident. – user2808624 Dec 17 '13 at 20:03
  • I am getting location updates per second, I have registered only 1 location listener not multiple. And I am also checking the speed, so if speed is 0 I am not adding points to my list and avoid those points. The main problem is that route drawn is not actually where it must drawn. Its always drawn out of road for some reason don;t know why. – Scorpion Dec 18 '13 at 03:18
  • 1
    Now, I see requestLocationUpdates two times. And one is inside a reStart method, which seems to be called multiple times.In conjunction with the static LocationUtils this still looks suspicious. – user2808624 Dec 18 '13 at 06:51

3 Answers3

9

This code will work

GoogleMap map;
   // ... get a map.
   // Add a thin red line from London to New York.
   Polyline line = map.addPolyline(new PolylineOptions()
       .add(new LatLng(51.5, -0.1), new LatLng(40.7, -74.0))
       .width(5)
       .color(Color.RED));
Asha Babu
  • 399
  • 2
  • 8
  • 2
    I am using the same code but its not working as required. Its drawing route off the rode and not exact where user is driving/walking. – Scorpion Dec 21 '13 at 14:46
  • @Scorpion What you can do to try to make it *work as required* better is to set the the accuracy in the location update request to priority accuracy and shorten the update interval a bit. – Daniel Kvist May 05 '15 at 17:21
2

You should split your problem into the aspects of data collection and data display.

Therefore take two coordinates you precisely know and draw a straight polyline on google maps. If it's really displayed at the wrong location, GoogleMap has indeed a bug, which BTW I don't believe.

Then print out your coordinates e.g. to LogCat before drawing them and check the coordinates. If they are wrong, it is not a problem of GoogleMaps but of the LocationProvider or of how you use it.

If the coordinates are collected correctly, you may pick them somehow up from LogCat and use them directly in your code to draw a polyline. If then the polyline is displaced, you may again have found a bug in GoogleMap. Then you should paste the coordinates here, so someone can reproduce it. It may be device dependent. I never had a polyline which did not match the map.

user2808624
  • 2,502
  • 14
  • 28
  • I have added the location got from location provider. Do you know how can i get route from this location on google maps, I am not asking about android draw route from location. I want to cross check this location online. Is there anyway to cross check it? – Scorpion Dec 18 '13 at 12:12
  • Or from location result can you judge that they are correct or not? – Scorpion Dec 18 '13 at 12:13
  • Got this site..http://www.darrinward.com/lat-long/ I added my all location in that and it showed me the same result as on my device. So we can say the problem is with location (lat/lng) which I am getting from Location provider. But I don't think that its a problem there is something else which I am missing. – Scorpion Dec 18 '13 at 12:22
  • Maybe your GPS is a bit inaccurate. I think there are lots of apps which are tracking and displaying the route on a map. Just try with them on the same device, whether they show a better result. – user2808624 Dec 18 '13 at 15:21
1

Your code for drawing the path looks strange. Inside the for-loop you should only add the points to an instance of PolylineOptions (which you create before entering the for loop).

Then, after the for-loop you can add the width, color etc. to the polylineOptions object and finally use that in mGoogleMap.addPolyline().

In your coding, you are somehow adding a new polyline for each point (I am wondering that this draws lines at all, as each "line" consists of one point only.).

User_1191
  • 981
  • 2
  • 8
  • 24
user2808624
  • 2,502
  • 14
  • 28
  • Thanks for your comment. Initially i have used PolyLineOptions inside the loop which i updated in the code. But in that also the path is drawing out of road, I am driving vehicle on road but my path always display somewhat away from the road...That's the main problem with the code... – Scorpion Dec 04 '13 at 12:36
  • I am pretty sure, the problem has nothing to do with drawing the polyline, but with the LatLng-points coming from RidingTimerService. (Is this a class of your own or some library? Could not find it.) I have a similar app, where the polyline perfectly matches my real way. – user2808624 Dec 04 '13 at 16:27
  • Its my own class, not using any library. Can you share some snippet of your code if you don;t have any issue in that. I have used code from android developer site and used Google Maps Android API v2 latest code sample and using Google Play services sdk for that... – Scorpion Dec 04 '13 at 16:34
  • Also for accurate location i have set location updates interval 1 seconds. And inside onLocationChanged method i am storing lat,long in a list and from that list I am drawing path on google maps – Scorpion Dec 04 '13 at 16:35
  • I have added full source of my service class for the reference. If you can help me out in that then it would be great help for me.. – Scorpion Dec 04 '13 at 16:51
  • @Scorpion just because you are driving on a road does not mean that your position according to the GPS is on the road. the location returned can and often is not exactly where you are, its based on how good of a GPS lock you have – tyczj Dec 04 '13 at 18:48
  • But when i used Google maps app, it gives me perfect navigation in the same device. How's that possible then. It simply means that my code has some issue with location or showing path on the map. Not sure what is the cause for it. – Scorpion Dec 05 '13 at 02:54
  • I would start with some test data to narrow down the cause of the problem. If a polyline for the test data shows up where it should, you can concentrate on the location provider and e.g. record (by writing into a file) the data from the location provider for some movement and then check these. – user2808624 Dec 05 '13 at 07:04