1

Working on a small app that i'm trying to use Fragments in. The app pulls some JSON data from a URI. It then creates then displays that data in a list. All this works fine, if the fragment is not involved.

I am trying to get Google Maps to display in a Fragment below that list in my layout and that is where i'm running into trouble.

My API key is good. I've gone through the StackTrace, but cannot figure out just what is going on. So, i'm asking you guys for some help. Also, before it is suggested I have Cleaned and Rebuilt the app in Android Studio many times.

Here is my code, which I'll try to only show the relevant bits. Let me know if you need more.

CODE

MainActivity.java

public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<CycloneData>> {

...

private CycloneMap cycloneMapFrag;

private void initMapFragment() {

    android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    cycloneMapFrag = new CycloneMap();
    SupportMapFragment supportMapFragment = cycloneMapFrag;
    fragmentTransaction.add(google_map, supportMapFragment);
    fragmentTransaction.commit();
}

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

    ...

    initMapFragment();
}

}

CycloneMap.java (The Fragment im trying to add)

public class CycloneMap extends SupportMapFragment {

//Defining Google Map objects variables
private GoogleMap googleMapView;
boolean mapReady = false;

static final CameraPosition START_POINT = CameraPosition.builder()
        .target(new LatLng(38.1254, -101.1703))
        .zoom(3)
        .bearing(359)
        .tilt(5)
        .build();

private void initGoogleMap() {
    getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap googleMap) {

            //Setting mapReady to true
            mapReady = true;

            //Loading local instance map from Callback
            googleMapView = googleMap;

            //Set map type to Satellite view
            googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);

            //Set camera at starting point, high over the middle of the U.S of A.
            initialCameraPosition(START_POINT);
        }
    });

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.cyclone_list, container, false);
}

//@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initGoogleMap();
}

private void initialCameraPosition(CameraPosition target) {
    //Setting position to the target created above
    googleMapView.moveCamera(CameraUpdateFactory.newCameraPosition(target));
}

}

XML

cyclone_list.xml layout file

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


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!-- Layout for a list of cyclones -->
    <ListView
        android:id="@+id/cyclone_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:orientation="vertical"
        android:layout_weight="1"/>

    <!-- Layout for Google Maps Fragment -->
    <FrameLayout
        android:id="@+id/google_map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>
</LinearLayout>

...

</RelativeLayout>

MANIFEST

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

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

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher_cycloops"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

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

    <activity
        android:name=".MenuSettingsActivity"
        android:label="@string/settings_title">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.palarran.cycloops.MenuSettingsActivity"/>
    </activity>

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="AHlaSyCIse5CB1QqYj9IqKzd7jRwGtIdjI48Mto"/>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version"/>
</application>

</manifest>

STACKTRACE

CatLog says:

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: com.palarran.cycloops, PID: 31964
                                                                   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.palarran.cycloops/com.palarran.cycloops.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.v()' on a null object reference
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
                                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                       at android.os.Looper.loop(Looper.java:154)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                                                                    Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.v()' on a null object reference
                                                                       at com.google.maps.api.android.lib6.impl.co.i(:com.google.android.gms.DynamiteModulesB:178)
                                                                       at com.google.android.gms.maps.internal.w.onTransact(:com.google.android.gms.DynamiteModulesB:209)
                                                                       at android.os.Binder.transact(Binder.java:499)
                                                                       at com.google.android.gms.maps.internal.IMapFragmentDelegate$zza$zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.maps.SupportMapFragment$zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza$6.zzb(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza.zza(Unknown Source)
                                                                       at com.google.android.gms.dynamic.zza.onStart(Unknown Source)
                                                                       at com.google.android.gms.maps.SupportMapFragment.onStart(Unknown Source)
                                                                       at android.support.v4.app.Fragment.performStart(Fragment.java:2215)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1340)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
                                                                       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
                                                                       at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2893)
                                                                       at android.support.v4.app.FragmentController.dispatchStart(FragmentController.java:212)
                                                                       at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:613)
                                                                       at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
                                                                       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
                                                                       at android.app.Activity.performStart(Activity.java:6696)
                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2628)
                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
                                                                       at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                       at android.os.Looper.loop(Looper.java:154) 
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6119) 
                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

CAUSE of StackTrace

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bq.v()' on a null object reference

I've gone through the StackTrace and read the suggested Article on NullPointerExceptions. No help there. I cannot find or figure out what the NullPointer is referring to or how to correct it.

EDIT/UPDATE

I might be running into a Google API bug. If I run this on an emulator it does not crash as before. I've found bug reports and some StackOverFlow post that say the issue happens due to the USB connection to my phone or that it happens on some phones if there is no SD card. I don't have an SD card on my phone(Nexus 5X) and no other phone to test with. :(

CB Midkiff
  • 165
  • 1
  • 14
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Harshad Pansuriya Mar 21 '17 at 03:45
  • This is very difficult to debug since the stacktrace has no reference to any class and method which you created. It is all Android API and Google Maps API. – Code-Apprentice Mar 21 '17 at 03:57
  • Yes. I would agree. I am stumped. – CB Midkiff Mar 21 '17 at 03:58
  • Will the Android debugger let you step into the Google Maps API code? Of course, you'll have to figure out how to make it break so you can do this...hmm... – Code-Apprentice Mar 21 '17 at 04:01
  • Yes it will and I have been going through that. Seems to die shortly after getMapAsync(new OnMapReadyCallback() while it is going through the FragmentManager.java API code. I am wading through, but wow...there is a lot going on. :) – CB Midkiff Mar 21 '17 at 04:06
  • refer http://stackoverflow.com/questions/29134914/google-maps-android-app-not-load-null-object-reference – sasikumar Mar 21 '17 at 04:32

1 Answers1

0

I'd recommend setting up your Fragment transaction so you're holding an instance of the manager instead of the transaction.

// Get an instance of your custom map fragment class
// or of "new SupportMapFragment();"
SupportMapFragment mapFragment = new MyMapFragment();

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    // Add the Map Fragment to your FrameLayout container
    .replace(R.id.fragment_container, mapFragment, "MAP_FRAGMENT")
    .commit();

And you may want to try putting your initGoogleMap() inside your Map Fragment's onResume().

Sammy T
  • 1,924
  • 1
  • 13
  • 20
  • I gave your suggestion a shot, but same NullPointerException error. I think my problem is the way I have the CycloneMap.Java Fragment written. I'm fairly new to OOP. Coming from a Networking/Unix procedural back ground, OOP confuses me sometimes. I guess I could move everything into MainActivity.java and just do the fragment statically in XML. :( – CB Midkiff Mar 21 '17 at 22:27
  • @CBMidkiff using `new SupportMapFragment()` should allow you to add it programmatically. That way didn't work for you either? – Sammy T Mar 22 '17 at 00:11
  • I did not try that, because I was not exactly sure how you meant for that to be used? I was also unsure where you came up with the String "MAP_FRAGMENT". I sorta butchered it I guess – CB Midkiff Mar 22 '17 at 02:58
  • Editing this comment. I retried it, the way you suggested. And it does load the map, but it does not load it from the CycloneMap.java fragment. It loads a basic map. Same as the "fix" I thought I came up with yesterday. I cannot seem to get the CycloneMap.java fragment code to run and load correctly. When that is called, it just produces the NullException. – CB Midkiff Mar 22 '17 at 03:03
  • @CBMidkiff Yeah, that's the part I'm not certain of. I've worked with SupportMapFragment but I've never extended it. If you really must extend it, then I would suggest commenting out everything inside your CycloneMap class and put your `getMapAsync` in the activity, see if you can still use it to get the basic map, and, if you can, move `getMapAsync` back to CycloneMap and keep adding and testing bit by bit until you see what breaks it. – Sammy T Mar 22 '17 at 05:41
  • 1
    I was reading the documentation a bit closer and it stated a 'getMapAsync' has to run in the main thread. So I moved everything in to the MainActivity.java and it is working as I wanted. I'm sure I was doing something wrong though in my Fragment..... dunno...I'll come back to this a some point later. I've been banging my head on it for 3 days or so. :P Wanna work on something else for a bit. :) – CB Midkiff Mar 22 '17 at 06:06