How to show actual road route driving mode in map in Android

2.3k views Asked by At

I have a web application, in which we add lat and lng and in web it shows driving route clearly in the map. I have send the same details including api, lat and longitude to the android using json. But in android app, map doesn't show proper path.

This is my map activity

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    LatLng latLng;
    private SharedPreferenceHelper sharedPreferenceHelper;
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    MyAlertDialogFragment newFragment;
    public final String BEFORE_BUS_POSTION = "BEFORE_BUS_POSTION";
    public final String AFTER_BUS_POSTION = "AFTER_BUS_POSTION";
    public final String CURRENT_BUS_POSTION = "CURRENT_BUS_POSTION";

    public final String GREEN_COLOR_CODE = "#228b22";
    public final String ORANGE_COLOR_CODE = "#C56E00";


    private String[] mNavigationDrawerItemTitles;
    private DrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    Toolbar toolbar;
    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    android.support.v7.app.ActionBarDrawerToggle mDrawerToggle;
    private ProgressDialog progress;
    int count = 0;

        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        mTitle = mDrawerTitle = getTitle();
        mNavigationDrawerItemTitles= getResources().getStringArray(R.array.navigation_drawer_items_array);
       ....


        sharedPreferenceHelper = new SharedPreferenceHelper(getApplicationContext());
        if (!sharedPreferenceHelper.getBooleanSharedPreferenceName("isRegistred")) {
            RegisterGCM();
        }
        sharedPreferenceHelper.WriteBooleanPreference("notification", true);

        /*Sharedpreference check wheather  app is running for firsttime.*/
        if (!sharedPreferenceHelper.getBooleanSharedPreferenceName("isfirsttime")) {
            sharedPreferenceHelper.WriteBooleanPreference("isfirsttime", true);
            sharedPreferenceHelper.WriteStringPreference("email", getIntent().getStringExtra("email"));
            sharedPreferenceHelper.WriteBooleanPreference("ringtone", true);
            sharedPreferenceHelper.WriteBooleanPreference("notification", true);
        }

        FragmentManager fm = getSupportFragmentManager();
        SupportMapFragment supportMapFragment =  SupportMapFragment.newInstance();
        fm.beginTransaction().replace(R.id.content_frame, supportMapFragment).commit();
        supportMapFragment.getMapAsync(this);
    }
    private class DrawerItemClickListener implements ListView.OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectItem(position);
        }

    }

    private void selectItem(int position) {

        AboutFragment aboutfragment = null;
        InfoFragment infofragment = null;
        switch (position) {
            case 0:
                startActivity(new Intent(this, MapsActivity.class));
                break;
            case 1:
                aboutfragment = new AboutFragment();
                break;
            case 2:
                infofragment= new InfoFragment();
                break;

            default:
                break;
        }

        if (aboutfragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, aboutfragment).commit();

            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(mNavigationDrawerItemTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);

        }else if (infofragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction().replace(R.id.content_frame, infofragment).commit();

            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(mNavigationDrawerItemTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);

        } else {
            Log.e("MapActivity", "Error in creating fragment");
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }    
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getSupportActionBar().setTitle(mTitle);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    void setupToolbar(){
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    void setupDrawerToggle(){
        mDrawerToggle = new android.support.v7.app.ActionBarDrawerToggle(this,mDrawerLayout,toolbar,R.string.app_name, R.string.app_name);
        //This is necessary to change the icon of the Drawer Toggle upon state change.
        mDrawerToggle.syncState();
    }
    private void RegisterGCM() {

        Log.i("HomeActivity", "This device is not supported.");
        if (checkPlayServices()) {

            // Start IntentService to register this application with GCM.
            Intent intent = new Intent(this, RegistrationIntentService.class);
            startService(intent);
        }

    }

    private boolean checkPlayServices() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                        .show();
            } else {
                if(sharedPreferenceHelper.getBooleanSharedPreferenceName("googleplayservice")) {
                    showDialog();
                }
                Log.i("HomeActivity", "This device is not supported.");
            }
            return false;
        }
        return true;
    }    
    void showDialog() {
        newFragment = MyAlertDialogFragment.newInstance(R.string.google_play_service_not_found);
        newFragment.show(getSupportFragmentManager(), "dialog");
    }

    public static class MyAlertDialogFragment extends DialogFragment {

        AlertDialog alert;

        public static MyAlertDialogFragment newInstance(int title) {
            MyAlertDialogFragment frag = new MyAlertDialogFragment();
            Bundle args = new Bundle();
            args.putInt("title", title);
            frag.setArguments(args);
            return frag;
        }    
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            int title = getArguments().getInt("title");

            return new AlertDialog.Builder(getActivity())
                    .setIcon(R.drawable.ic_info_black_24dp)
                    .setTitle(title)
                    .setMessage(R.string.google_play_service_not_found_message)
                    .setPositiveButton("Ok",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton) {
                                    ((MapsActivity)getActivity()).doPositiveClick();
                                }
                            }
                    )
                    .setNegativeButton("Don't show again",
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton) {
                                    ((MapsActivity)getActivity()).doNegativeClick();
                                }
                            }
                    ).create();  
        }
    }

    public void doPositiveClick() {
        Log.i("FragmentAlertDialog", "Positive click!");
        newFragment.dismiss();
    }

    public void doNegativeClick() {
        newFragment.dismiss();
        sharedPreferenceHelper.WriteBooleanPreference("googleplayservice", true);
        Log.i("FragmentAlertDialog", "Negative click!");
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        progress=new ProgressDialog(this);
        progress.setMessage("Map Loading");
        progress.show();
        progress.setCanceledOnTouchOutside(false);
        final Handler ha=new Handler();

        ha.postDelayed(new Runnable() {

            @Override
            public void run() {
                //call function
                setLocationFromServerWithRoute();
                ha.postDelayed(this, 2000);
            }
        }, 10000);

        // Add a marker in Sydney and move the camera
/*        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/
    }
    private void setLocationFromServerWithRoute() {

        RequestQueue queue = Volley.newRequestQueue(this);

        String email = new SharedPreferenceHelper(getApplicationContext()).getStringSharedPreferenceName("email");
        String url = LoginActivity.URL+ "read.jsp?email="+email;
        Log.d("email",email);

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>(){
                    @Override
                    public void onResponse(String response) {

                        JSONArray array = new JSONArray();
                        Log.d("Response 10 secs",response);
                        try {
                            array = new JSONArray(response);
                            mMap.clear();
                            for(int n = 0; n < array.length()-1; n++) {

                                JSONObject jsonObject = array.getJSONObject(n);
                                JSONObject jsonObjectNext = array.getJSONObject(n+1);
                                LatLng latLng = new LatLng(jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"));
                                LatLng latLngNext = new LatLng(jsonObjectNext.getDouble("latitude"), jsonObjectNext.getDouble("longitude"));
                                String address = jsonObject.getString("routename");   
                                Log.d("Response",response);
                                if(jsonObjectNext.getString("busPosition").equals(CURRENT_BUS_POSTION) && n < array.length()-2 ) {
                                    jsonObjectNext = array.getJSONObject(n+2);
                                    latLngNext = new LatLng(jsonObjectNext.getDouble("latitude"), jsonObjectNext.getDouble("longitude"));

                                }                                    if(jsonObject.getString("busPosition").equals(CURRENT_BUS_POSTION)){

                                    mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                                .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_blue)));

                                    Log.d("CURRENT_BUS_POSTION","REACHED");

                                }else if(jsonObject.getString("busPosition").equals(AFTER_BUS_POSTION)){

                                    if(jsonObject.getBoolean("isBusStop")) {
                                        mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                                .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_orange)));
                                    }
                                    mMap.addPolyline(new PolylineOptions()
                                            .add(latLng,latLngNext)
                                            .width(5)
                                            .color(Color.parseColor(ORANGE_COLOR_CODE)));

                                }else if(jsonObject.getString("busPosition").equals(BEFORE_BUS_POSTION)){

                                    if(jsonObject.getBoolean("isBusStop")) {
                                        mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                                .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_green)));
                                    }
                                    mMap.addPolyline(new PolylineOptions()
                                            .add(latLng,latLngNext)
                                            .width(5)
                                            .color(Color.parseColor(GREEN_COLOR_CODE)));    
                                }    
                            }

                            JSONObject jsonObject = array.getJSONObject(array.length() - 1);
                            LatLng latLng = new LatLng(jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"));
                            String address = jsonObject.getString("routename");

                            if (jsonObject.getString("busPosition").equals(CURRENT_BUS_POSTION)) {
                                mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_blue)));
                            } else if (jsonObject.getString("busPosition").equals(AFTER_BUS_POSTION) && jsonObject.getBoolean("isBusStop")) {
                                mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_orange)));
                            } else if (jsonObject.getString("busPosition").equals(BEFORE_BUS_POSTION) && jsonObject.getBoolean("isBusStop")) {
                                mMap.addMarker(new MarkerOptions().position(latLng).title("" + address)
                                        .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_green)));
                            }
                            ;
                    if(count < 2) {

                        Log.v("count",""+count);
                        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
                        mMap.animateCamera(CameraUpdateFactory.zoomTo(16.0f));
                        if(count == 1){
                            progress.hide();
                        }
                        }
                            count ++;
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }      
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                 Toast.makeText(getApplicationContext(),"Error:"+error.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(stringRequest);    
    }


    private void setLocationFromServer() {  
        RequestQueue queue = Volley.newRequestQueue(this);    
        String email = new SharedPreferenceHelper(getApplicationContext()).getStringSharedPreferenceName("email");
        String url = LoginActivity.URL+ "read.jsp?email="+email;

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>(){
                    @Override
                    public void onResponse(String response) {
                        Toast.makeText(getApplicationContext(),"Response:"+response,Toast.LENGTH_SHORT).show();
                        Log log = null;
                        log.v("response",""+response);
                        JSONObject jsonObject = null;
                        Double param1 = 0.0;
                        Double param2 = 0.0;
                        Long datecreated = null;
                        String dateCreated = null;
                        Date dateCREATED = null, twoHOURDate;

                        Calendar cal = Calendar.getInstance();
                        cal.add(Calendar.HOUR, -2);
                        Date twoHourBack = cal.getTime();
                        Log.v("twoHourBack::", "" + twoHourBack);
                        Toast.makeText(getApplicationContext(),"+twoHourBack:"+twoHourBack,Toast.LENGTH_SHORT).show();


                        JSONObject jsonObjectData = new JSONObject();
                        JSONArray array = new JSONArray();
                        try {
                            jsonObjectData = new JSONObject(response);
                            array = jsonObjectData.getJSONArray("route");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }


                        ArrayList<BusRoute> arrayList = new ArrayList();
                        for(int n = 0; n < array.length(); n++) {
                            try {
                                JSONObject object = array.getJSONObject(n);
                                BusRoute busRoute = new BusRoute();
                                busRoute.setId(object.getString("routeID"));
                                busRoute.setLatitude(object.getString("latitude"));
                                busRoute.setLongitude(object.getString("longitude"));
                                busRoute.setDate(object.getString("dateCreated"));
                                busRoute.setPlaceWeight(object.getString("busRouteweight"));
                                busRoute.setPlaceId(object.getString("routename"));
                                arrayList.add(busRoute);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                        Collections.sort(arrayList, new Comparator<BusRoute>() {
                            @Override
                            public int compare(BusRoute o1, BusRoute o2) {
                                return o1.getDate().compareTo(o2.getDate());
                            }
                        });




                        boolean isBusLocationPassed = false;
                        for(int n = 0; n < arrayList.size(); n++)
                        {
                            try {

                                BusRoute object = arrayList.get(n);

                                param1 = Double.parseDouble(object.getLatitude());
                                param2 = Double.parseDouble(object.getLongitude());

                                latLng = new LatLng(param1, param2);
                                Geocoder geocoder = new Geocoder(MapsActivity.this, Locale.getDefault());
                                List<Address> addresses = null;
                                try {
                                    addresses = geocoder.getFromLocation(param1, param2, 1);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                String cityName = addresses.get(0).getAddressLine(0);
                                String stateName = addresses.get(0).getAddressLine(1);
                                String countryName = addresses.get(0).getAddressLine(2);
                                log.v("cityName", "" + cityName);
                                log.v("lat", "" + param1);
                                log.v("log", "" + param2);

                                BusRoute objectnext = null;
                                if( n < arrayList.size()-1 ) {
                                    objectnext = arrayList.get(n + 1);
                                }
                                if(object.getId().trim() .equals(jsonObjectData.getString("prevStop").trim())){

                                    Polyline line = mMap.addPolyline(new PolylineOptions()
                                            .add(new LatLng(Double.parseDouble(object.getLatitude()), Double.parseDouble(object.getLongitude())), new LatLng(jsonObjectData.getDouble("latitude"), jsonObjectData.getDouble("Longitude")))
                                            .width(5)
                                            .color(Color.GREEN));
                                    if( objectnext != null ) {
                                        Polyline line2 = mMap.addPolyline(new PolylineOptions()
                                                .add(new LatLng(jsonObjectData.getDouble("Lattitude"), jsonObjectData.getDouble("Longitude")), new LatLng(Double.parseDouble(objectnext.getLatitude()), Double.parseDouble(objectnext.getLongitude())))
                                                .width(5)
                                                .color(Color.parseColor("#C56E00")));
                                    }

                                    log.v("done", "1 " + jsonObjectData.getString("nextStop"));
                                    LatLng latLngCurrent = new LatLng(jsonObjectData.getDouble("Lattitude"), jsonObjectData.getDouble("Longitude"));
                                    mMap.addMarker(new MarkerOptions().position(latLngCurrent).title("" + cityName + "" + stateName + "" + countryName)
                                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_blue)));
                                    mMap.addMarker(new MarkerOptions().position(latLng).title("" + cityName + "" + stateName + "" + countryName)
                                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_green)));
                                    isBusLocationPassed = true;
                                }else if(isBusLocationPassed){
                                    if( objectnext != null ) {

                                        Polyline line = mMap.addPolyline(new PolylineOptions()
                                                .add(new LatLng(Double.parseDouble(object.getLatitude()), Double.parseDouble(object.getLongitude())), new LatLng(Double.parseDouble(objectnext.getLatitude()), Double.parseDouble(objectnext.getLongitude())))
                                                .width(5)
                                                .color(Color.parseColor("#C56E00")));
                                    }
                                    log.v("done", "2 " + jsonObjectData.getString("nextStop"));

                                    mMap.addMarker(new MarkerOptions().position(latLng).title("" + cityName + "" + stateName + "" + countryName)
                                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_orange)));
                                }else{
                                    if( objectnext != null ) {

                                        Polyline line = mMap.addPolyline(new PolylineOptions()
                                                .add(new LatLng(Double.parseDouble(object.getLatitude()), Double.parseDouble(object.getLongitude())), new LatLng(Double.parseDouble(objectnext.getLatitude()), Double.parseDouble(objectnext.getLongitude())))
                                                .width(5)
                                                .color(Color.GREEN));
                                    }
                                    log.v("done", "3 " + jsonObjectData.getString("nextStop"));

                                    mMap.addMarker(new MarkerOptions().position(latLng).title("" + cityName + "" + stateName + "" + countryName)
                                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.bus_green)));

                                }

                                mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
                                mMap.animateCamera(CameraUpdateFactory.zoomTo(10.0f));



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

                        }

                        Toast.makeText(getApplicationContext(), "Location received, Latitude:" + param1 + " Longitude:" + param2, Toast.LENGTH_SHORT).show();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),"Error:"+error.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(stringRequest);    
    }       
}

any help?

Update:

I tried with solution one and solution two

In both cases, i am getting error : OVER_QUERY_LIMIT

Anyone has any solution for this???

This is how i am getting in android map..i want them to show in actual road path.

enter image description here

In website, it shows correctly...

enter image description here

2

There are 2 answers

0
Pravin Divraniya On

To display actual road path in Android map you can use geodesic(true) like given below.

Polyline line = map.addPolyline(new PolylineOptions()
    .add(new LatLng(-37.81319, 144.96298), new LatLng(-31.95285, 115.85734))
    .width(25)
    .color(Color.BLUE)
    .geodesic(true));

As per this link (Read Geodesic segments)

The geodesic setting determines how the line segments between consecutive vertices of the polyline/polygon are drawn. Geodesic segments are those that follow the shortest path along the Earth's surface (a sphere) and often appear as curved lines on a map with a Mercator projection. Non-geodesic segments are drawn as straight lines on the map.

Set this property on the shape's option object by calling *Options.geodesic() where true indicates the segments should be drawn as geodesics and false indicates the segments should be drawn as straight lines. If unspecified, the default is non-geodesic segments (false).

For OVER_QUERY_LIMIT :- Use of the Google Maps APIs web services is subject to specific limits on the amount of requests per 24 hour period. Requests sent in excess of these limits will receive an error message.

If you exceed the usage limits you will get an OVER_QUERY_LIMIT status code as a response.

This means that the web service will stop providing normal responses and switch to returning only status code OVER_QUERY_LIMIT until more usage is allowed again. This can happen:

  • Within a few seconds, if the error was received because your application sent too many requests per second.
  • Within the next 24 hours, if the error was received because your application sent too many requests per day. The daily quotas are reset at midnight, Pacific Time.

Solutions :-

The above problems can be address by combining two approaches:

  • Lowering usage, by optimizing applications to use the web services more efficiently.
  • Increasing usage limits, when possible, by purchasing additional allowance for your Google Maps APIs for Work license.

Check this link for detail information.

Hope this will help you.

0
Flame_Phoenix On

Error

Over query limit means that you are performing too many queries per second to the API or that you have exceeded your quota.

In order to further assist you I would need in detail which APIs you are using, since I don't know that I am assuming you are using the Google Maps Roads API which does give you the paths you want.

Usage Limits

Every API has a usage limit. In the case of the Roads API you can only make 50 Queries Per Second (QPS) and you have other limitations. To see the list of limitations regarding this API I encourage you to check the link bellow:

I am not using Roads API!

If you are not using the Roads API, you will have to find which API you are using, and the limitation for it. Following is a list of all the APIs Google Maps offers:

Ok, I know which API I am using, and I am hitting a limit. What now?

Once you have the previous steps figured out, you have usually two main options to avoid hitting the limit:

  • Caching information
  • Throttling requests

Each solution is a world on its own, but I will leave you with some directions on the concepts so you have an easier time following them:

I specially recommend the last link, which points to official documentation and covers both caching and throttling.

Hope it helps !


PS: I also upvoted the question, seeing no real reason why someone would downvote it. I do recommend however that you add a Minimal Working Example instead of posting all your code, and it will make more people willing to help you.

In an Android case, I usually recommend creating a project from scratch as minimalist as possible that can replicate your issue.