Search code examples
javaandroidgoogle-mapsgoogle-maps-api-2

Android App keeps crashing when using GoogleMap V2


Im having an annoying problem with GoogleMap. I have tested it and the map shows fine. But now I want to set My Location Enabled so the map auto starts where the phone is. And now everytime I run the app it crashes. And I have noticed, the app crashes when Im using the syntax GoogleMap. I have tried to figure out this problem and look around on the web without result.

Here is my Maps.java file:

package test.test;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;

import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class Maps extends FragmentActivity implements LocationListener{

    GoogleMap googlemap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maps);
        SupportMapFragment mf = (SupportMapFragment)     getSupportFragmentManager().findFragmentById(R.id.map);
        googlemap = mf.getMap();

        googlemap.setMyLocationEnabled(true);
        googlemap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    }

Maps.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

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

</LinearLayout>

And finally my androidmanifest:

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

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

        <permission
            android:name="test.test.permission.MAPS_RECEIVE"
            android:protectionLevel="signature" />

        <uses-permission android:name="test.test.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

....
<meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="my key is here" />
    </application>

Here is the error log:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{test.test/test.test.Maps}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at test.test.Maps.onCreate(Maps.java:23)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
... 11 more

Solution

  • The fragment isn't ready yet or something's amiss with Google Play services on the device.

    From the docs (emphasis added):

    Returns
    the GoogleMap. Null if the view of the fragment is not yet ready. This can happen if the fragment lifecyle have not gone through onCreateView(LayoutInflater, ViewGroup, Bundle) yet. This can also happen if Google Play services is not available. If Google Play services becomes available afterwards and the fragment have gone through onCreateView(LayoutInflater, ViewGroup, Bundle), calling this method again will initialize and return the GoogleMap.

    The 'maps' demo app shows a pattern to deal with this, attempting to set up the map if needed both at creation and on resume:

    /**
     * This shows how to create a simple activity with a map and a marker on the map.
     * <p>
     * Notice how we deal with the possibility that the Google Play services APK is not
     * installed/enabled/updated on a user's device.
     */
    public class BasicMapActivity extends FragmentActivity {
        /**
         * Note that this may be null if the Google Play services APK is not available.
         */
        private GoogleMap mMap;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.basic_demo);
            setUpMapIfNeeded();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            setUpMapIfNeeded();
        }
    
        /**
         * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
         * installed) and the map has not already been instantiated.. This will ensure that we only ever
         * call {@link #setUpMap()} once when {@link #mMap} is not null.
         * <p>
         * If it isn't installed {@link SupportMapFragment} (and
         * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
         * install/update the Google Play services APK on their device.
         * <p>
         * A user can return to this FragmentActivity after following the prompt and correctly
         * installing/updating/enabling the Google Play services. Since the FragmentActivity may not have been
         * completely destroyed during this process (it is likely that it would only be stopped or
         * paused), {@link #onCreate(Bundle)} may not be called again so we should call this method in
         * {@link #onResume()} to guarantee that it will be called.
         */
        private void setUpMapIfNeeded() {
            // Do a null check to confirm that we have not already instantiated the map.
            if (mMap == null) {
                // Try to obtain the map from the SupportMapFragment.
                mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                        .getMap();
                // Check if we were successful in obtaining the map.
                if (mMap != null) {
                    setUpMap();
                }
            }
        }
    
        /**
         * This is where we can add markers or lines, add listeners or move the camera. In this case, we
         * just add a marker near Africa.
         * <p>
         * This should only be called once and when we are sure that {@link #mMap} is not null.
         */
        private void setUpMap() {
            mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
        }
    }