Android: Blank page when using google map api 2

2020-05-06 07:40发布

问题:

I'm using google map v2 in my app but I get the blank page like this:

I did these stepe for adding this feature to my project.

  1. First of all I updated google play services

  2. Added D:\AndroidSDK\extras\google\google_play_services\libproject\google-play-services_lib as a dependency to my main project also the jar file in the libs folder of this path.

  3. Activated google map android APIs v2 in Google APIs Console

  4. Created new Android key and the result is:

After those steps I added the API key into the manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.test"
      android:versionCode="1"
      android:versionName="1.0">

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

  <permission
        android:name="com.example.test.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
  <uses-permission android:name="com.example.test.permission.MAPS_RECEIVE/>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <uses-permission   android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
  <!-- External storage for caching. -->
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <!-- My Location -->
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

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

  <!-- Maps API needs OpenGL ES 2.0. -->
  <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />
  <!-- End of copy. -->

  <application android:label="@string/app_name"
             android:icon="@drawable/ic_launcher"
             android:theme="@style/Theme.Sherlock.Light">
     <activity android:name=".ActivityBusinessDirections"
              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="AIzaSyBmFPG-Fri--**************" />
   </application>
</manifest>

And finally this is my layout that I use

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"  >

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

</RelativeLayout>

EDIT: this is my activity code

public class ActivityBusinessDirections extends FragmentActivity implements    LocationListener {

GoogleMap mGoogleMap;
ArrayList<LatLng> mMarkerPoints;
double mLatitude=0;
double mLongitude=0;

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

    // Getting Google Play availability status
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

    if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available

        int requestCode = 10;
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
        dialog.show();

    }else { // Google Play Services are available

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

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

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

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

        // Getting LocationManager object from System Service LOCATION_SERVICE
        LocationManager locationManager = (LocationManager) getSystemService(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 From GPS
        Location location = locationManager.getLastKnownLocation(provider);

        if(location!=null){
            onLocationChanged(location);
        }

        locationManager.requestLocationUpdates(provider, 20000, 0, this);

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

            @Override
            public void onMapClick(LatLng point) {

                // Already map contain destination location
                if(mMarkerPoints.size()>1){

                    FragmentManager fm = getSupportFragmentManager();
                    mMarkerPoints.clear();
                    mGoogleMap.clear();
                    LatLng startPoint = new LatLng(mLatitude, mLongitude);

                    // draw the marker at the current position
                    drawMarker(startPoint);
                }

                // draws the marker at the currently touched location
                drawMarker(point);

                // Checks, whether start and end locations are captured
                if(mMarkerPoints.size() >= 2){
                    LatLng origin = mMarkerPoints.get(0);
                    LatLng dest = mMarkerPoints.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";

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

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

/** A class to download data from Google Directions URL */
private 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 Directions in JSON format */
private 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;

        // 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);
            lineOptions.color(Color.RED);
        }

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

private void drawMarker(LatLng point){
    mMarkerPoints.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.
     */
    if(mMarkerPoints.size()==1){
        options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
    }else if(mMarkerPoints.size()==2){
        options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    }

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

@Override
public void onLocationChanged(Location location) {
    // Draw the marker, if destination location is not set
    if(mMarkerPoints.size() < 2){

        mLatitude = location.getLatitude();
        mLongitude = location.getLongitude();
        LatLng point = new LatLng(mLatitude, mLongitude);

        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(point));
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));

        drawMarker(point);
    }
}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
}
}

回答1:

If you changed API key in manifest just

  • clear data (in android device)

or

  • uninstall app and reinstall it


回答2:

From the Manifest file you posted it looks like you package name: package="com.com.my_package_name"

does not match the package name you used for Google Maps permissions:

<permission
    android:name="com.my_package_name.permission.MAPS_RECEIVE"
    android:protectionLevel="signature"/>
<uses-permission android:name="com.my_package_name.permission.MAPS_RECEIVE/>

You can see that com.com.my_package_name is different from com.my_package_name, this must be your problem.



回答3:

Try to add this permission to to your manifest

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


回答4:

There are two keys debug and release key. If you signed your apk you want to use release key. I think you used debug key. So only map looks blank. Release key procedures are here.

How to get production key for google map?



回答5:

Make sure you are using the same SHA1 finger print in API console that your project built with, find your SHA1 finger print from eclipse Window>Preferences>Android>Build>SHA1 fingerprint.