Question

Here is MainActivity Class

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 org.json.JSONObject;

import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
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;


public class MainActivity extends FragmentActivity {

    GoogleMap map;
    ArrayList markerPoints;

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

        // Initializing 
        markerPoints = new ArrayList();

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

        // Getting reference to Button
        Button btnDraw = (Button)findViewById(R.id.btn_draw);       

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

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

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

            @Override
            public void onMapClick(LatLng point) {

                // Already 10 locations with 8 waypoints and 1 start location and 1 end location. 
                // Upto 8 waypoints are allowed in a query for non-business users
                if(markerPoints.size()>=10){
                    return;
                }

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

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

                // Setting the position of the marker
                options.position(point);

                /** 
                 * For the start location, the color of marker is GREEN and
                 * for the end location, the color of marker is RED and
                 * for the rest of markers, the color is AZURE
                 */
                if(markerPoints.size()==1){
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                }else if(markerPoints.size()==2){
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                }else{
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
                }           

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

            }
        });


        // The map will be cleared on long click
        map.setOnMapLongClickListener(new OnMapLongClickListener() {

            @Override
            public void onMapLongClick(LatLng point) {
                // Removes all the points from Google Map
                map.clear();

                // Removes all the points in the ArrayList
                markerPoints.clear();

            }
        });


        // Click event handler for Button btn_draw
        btnDraw.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // 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);
                }

            }
        });     


    }

    private 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";         

        // Waypoints
        String waypoints = "";
        for(int i=2;i{         

        // 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 */
    private class ParserTask extends AsyncTask>> >{

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

            JSONObject jObject; 
            List>> 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>> result) {

            ArrayList points = null;
            PolylineOptions lineOptions = null;

            // Traversing through all the routes
            for(int i=0;i();
                lineOptions = new PolylineOptions();

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

                // Fetching all the points in i-th route
                for(int j=0;j 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);
                lineOptions.color(Color.RED);               
            }

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

Direction Parser Class is like this

package in.wptrafficanalyzer.locationwaypointmapv2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.gms.maps.model.LatLng;

public class DirectionsJSONParser {

    /** Receives a JSONObject and returns a list of lists containing latitude and longitude */
    public List>> parse(JSONObject jObject){

        List>> routes = new ArrayList>>();
        JSONArray jRoutes = null;
        JSONArray jLegs = null;
        JSONArray jSteps = null;    

        try {

            jRoutes = jObject.getJSONArray("routes");

            /** Traversing all routes */
            for(int i=0;i>();

                /** Traversing all legs */
                for(int j=0;j list = decodePoly(polyline);

                        /** Traversing all points */
                        for(int l=0;l hm = new HashMap();
                            hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
                            hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
                            path.add(hm);                       
                        }                               
                    }
                    routes.add(path);
                }
            }

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


        return routes;
    }   


    /**
     * Method to decode polyline points 
     * Courtesy : jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java 
     * */
    private List decodePoly(String encoded) {

        List poly = new ArrayList();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index = 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) = 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }

        return poly;
    }
}

Android Manifest.xml is

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET"/>

 <permission
      android:name="in.wptrafficanalyzer.locationwaypointmapv2.permission.MAPS_RECEIVE"
      android:protectionLevel="signature" />

<uses-permission android:name="in.wptrafficanalyzer.locationwaypointmapv2.permission.MAPS_RECEIVE" />

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>


<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="in.wptrafficanalyzer.locationwaypointmapv2.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="AIzaSyC6TVk6gtR_i_.......**************"/>    

</application>

And Layout activity_main.xml is

<Button 
    android:id="@+id/btn_draw"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/str_btn_draw" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" />


<fragment 
    android:id="@+id/map"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"        
    class="com.google.android.gms.maps.SupportMapFragment" 
    android:layout_above="@id/btn_draw" />

My LogCat file is

03-02 21:35:25.157: D/dalvikvm(25733): Late-enabling CheckJNI
03-02 21:35:25.758: D/AndroidRuntime(25733): Shutting down VM
03-02 21:35:25.758: W/dalvikvm(25733): threadid=1: thread exiting with uncaught exception (group=0x40ddd2a0)
03-02 21:35:25.768: E/AndroidRuntime(25733): FATAL EXCEPTION: main
03-02 21:35:25.768: E/AndroidRuntime(25733): java.lang.RuntimeException: Unable to start activity ComponentInfo{in.wptrafficanalyzer.locationwaypointmapv2/in.wptrafficanalyzer.locationwaypointmapv2.MainActivity}: android.view.InflateException: Binary XML file line #16: Error inflating class fragment
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread.access$700(ActivityThread.java:140)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.os.Handler.dispatchMessage(Handler.java:99)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.os.Looper.loop(Looper.java:137)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread.main(ActivityThread.java:4935)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at java.lang.reflect.Method.invokeNative(Native Method)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at java.lang.reflect.Method.invoke(Method.java:511)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at dalvik.system.NativeStart.main(Native Method)
03-02 21:35:25.768: E/AndroidRuntime(25733): Caused by: android.view.InflateException: Binary XML file line #16: Error inflating class fragment
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:710)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:752)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:316)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.Activity.setContentView(Activity.java:1924)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at in.wptrafficanalyzer.locationwaypointmapv2.MainActivity.onCreate(MainActivity.java:43)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.Activity.performCreate(Activity.java:5206)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
03-02 21:35:25.768: E/AndroidRuntime(25733):    ... 11 more
03-02 21:35:25.768: E/AndroidRuntime(25733): Caused by: java.lang.IllegalStateException: The meta-data tag in your app's AndroidManifest.xml does not have the right value.  Expected 4242000 but found 0.  You must have the following declaration within the  element:     
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.common.GooglePlayServicesUtil.n(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.common.GooglePlayServicesUtil.isGooglePlayServicesAvailable(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.internal.q.v(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.internal.q.u(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.MapsInitializer.initialize(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.SupportMapFragment$b.ex(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.SupportMapFragment$b.a(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.dynamic.a.a(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.dynamic.a.onInflate(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at com.google.android.gms.maps.SupportMapFragment.onInflate(Unknown Source)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:279)
03-02 21:35:25.768: E/AndroidRuntime(25733):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:682)
03-02 21:35:25.768: E/AndroidRuntime(25733):    ... 21 more

Please, help

Was it helpful?

Solution

The problem is here:

<meta-data
   android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyC6TVk6gtR_i_.......**************"/> 

The meta-data tag expects here an integer, so you'll have to include here the version of the com.google.android.maps lib you're using. You'll find this probably in the lib you're including in your project, then just define:

<meta-data
   android:name="com.google.android.maps.v2.API_KEY"
   android:value="@integer/your_google_maps_version" />

OTHER TIPS

<meta-data
   android:name="com.google.android.maps.v2.API_KEY"
    android:value="AIzaSyC6TVk6gtR_i_.......**************"/> 

In manifest.xml just add this after application> tag and before your first activity

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top