Null Pointer Exception and getMapAsync Error

自闭症网瘾萝莉.ら 提交于 2020-01-15 11:58:09

问题


I'm a student programmer and currently coding a Route Guide App.

Suddenly, while trying to open my android application, it crashes. So, I tried searching for a lot of tutorials on how to fix the error message that I got. Unfortunately, I ran out of hope and came here to seek for help. I keep getting this on Console:

$ adb shell am start -n "com.garate.taraj/com.garate.taraj.MapsActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Waiting for application to come online: com.garate.taraj | com.garate.taraj.test
Waiting for application to come online: com.garate.taraj | com.garate.taraj.test
Waiting for application to come online: com.garate.taraj | com.garate.taraj.test
Waiting for application to come online: com.garate.taraj | com.garate.taraj.test
Connecting to com.garate.taraj
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/art: Debugger is active
I/System.out: Debugger has connected
    waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
Connected to the target VM, address: 'localhost:8600', transport: 'socket'
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: waiting for debugger to settle...
I/System.out: debugger has settled (1387)
W/System: ClassLoader referenced unknown path: /data/app/com.garate.taraj-2/lib/arm64
I/Typeface: initHwFontConfig end 
I/HwCust: Constructor found for class android.app.HwCustActivityImpl
I/HwCust: Constructor found for class android.app.HwCustHwWallpaperManagerImpl
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.garate.taraj, PID: 17542
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.garate.taraj/com.garate.taraj.MapsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2793)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:156)
        at android.app.ActivityThread.main(ActivityThread.java:6517)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.SupportMapFragment.getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)' on a null object reference
        at com.garate.taraj.MapsActivity.onCreate(MapsActivity.java:58)
        at android.app.Activity.performCreate(Activity.java:6915)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2746)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:156) 
        at android.app.ActivityThread.main(ActivityThread.java:6517) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832) 
I/Process: Sending signal. PID: 17542 SIG: 9
Disconnected from the target VM, address: 'localhost:8600', transport: 'socket'

The Application is not yet done so there may be useless buttons in there. So far, I have tried editing my xml but honestly, I don't know what I'm doing. I will be attaching my codes here.

My MapsActivity.java

package com.garate.taraj;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.DexterError;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.PermissionRequestErrorListener;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

import java.io.IOException;
import java.util.List;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
    private GoogleMap mMap;
    boolean isFirstTime;
    LocationManager locationManager;

    //PROCESS
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        // MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        //FOR BUTTONS
        Button fromButton, toButton;
        fromButton = findViewById(R.id.fromButton);
        fromButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openSearchPointA();
            }
        });

        toButton = findViewById(R.id.toButton);
        toButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openSearchPointB();
            }
        });

        isFirstTime = true;
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        Dexter.withActivity(this).withPermissions(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE).withListener(new MultiplePermissionsListener() {

            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onPermissionsChecked(MultiplePermissionsReport report) {
                // check if all permissions are granted
                if (report.areAllPermissionsGranted()) {
                    Geolocation();
                }
                else {
                    showSettingsDialog();
                    ShowDefault();
                }

                // check for permanent denial of any permission
                if (report.isAnyPermissionPermanentlyDenied()) {
                    showSettingsDialog();
                    ShowDefault();
                }
            }

            @Override
            public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
                token.continuePermissionRequest(); //Prompt for request
            }
        }).withErrorListener(new PermissionRequestErrorListener() {

            @Override
            public void onError(DexterError error) {
                Toast.makeText(getApplicationContext(), "Error occurred! ", Toast.LENGTH_SHORT).show();
            }
        }).onSameThread().check(); //CHECKS FOR ERROR
    }

    //FOR BUTTONS
    private void openSearchPointA() {
        Intent intent = new Intent(this, SearchPointA.class);
        startActivity(intent);
    }

    private void openSearchPointB() {
        Intent intent = new Intent(this, SearchPointB.class);
        startActivity(intent);
    }

    //DEFAULT MAP VIEW
    private void ShowDefault() {
        LatLng davaoDefault = new LatLng(7.0707, 125.6087);
        if (isFirstTime == true) {
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(davaoDefault, 12f));
        }
        isFirstTime = false;
    }

    //MAP UI
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setMyLocationButtonEnabled(true);
    }

    //OPEN SETTINGS in case the user DENIES
    private void showSettingsDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(MapsActivity.this);
        builder.setTitle("Need Permissions");
        builder.setMessage("TaraJ needs location and Storage permissions to function. You can grant them in the application's settings. (TaraJ > Permissions)");
        builder.setPositiveButton("OPEN SETTINGS", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                openSettings();
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });
        builder.show();
    }

    private void openSettings() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, 101);
    }

    //METHOD for the GEOLOCATION
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void Geolocation() {
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }

        //CHECK if network provider is ENABLED
        if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
            locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
                @SuppressWarnings("MoveFieldAssignmentToInitializer")
                @Override
                public void onLocationChanged(Location location) {

                    //GET latitude
                    double latitude = location.getLatitude();
                    //GET longitude
                    double longitude = location.getLongitude();
                    //INSTANTIATE LatLng class
                    LatLng latLng = new LatLng(latitude, longitude);
                    //INSTANTIATE Geocoder class
                    Geocoder geocoder = new Geocoder(getApplicationContext());

                    try {
                        List<Address> adressList = geocoder.getFromLocation(latitude, longitude, 1);
                        String str = adressList.get(0).getPremises() + ", ";
                        str += adressList.get(0).getSubLocality() + ", ";
                        str += adressList.get(0).getLocality();
                        mMap.clear();
                        mMap.addMarker(new MarkerOptions().position(latLng).title(str));
                        if (isFirstTime == true) {
                            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13f));
                        }
                        isFirstTime = false;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {

                }

                @Override
                public void onProviderEnabled(String provider) {

                }

                @Override
                public void onProviderDisabled(String provider) {

                }
            });
        }
        else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
                @Override
                public void onLocationChanged(Location location) {
                    //GET latitude
                    double latitude = location.getLatitude();
                    //GET longitude
                    double longitude = location.getLongitude();
                    //INSTANTIATE LatLng class
                    LatLng latLng = new LatLng(latitude, longitude);
                    //INSTANTIATE Geocoder clas
                    Geocoder geocoder = new Geocoder(getApplicationContext());
                    try {
                        List<Address> adressList = geocoder.getFromLocation(latitude, longitude, 1);
                        String str = adressList.get(0).getPremises() + ", ";
                        str += adressList.get(0).getSubLocality() + ", ";
                        str += adressList.get(0).getLocality();
                        mMap.clear();
                        mMap.addMarker(new MarkerOptions().position(latLng).title(str));
                        if (isFirstTime == true) {
                            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13f));
                        }
                        isFirstTime = false;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onStatusChanged(String provider, int status, Bundle extras) {

                }

                @Override
                public void onProviderEnabled(String provider) {

                }

                @Override
                public void onProviderDisabled(String provider) {

                }
            });
        }
    }
}

My xml file:

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


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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <Button
                android:id="@+id/fromButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Where are you going?" />

            <Button
                android:id="@+id/toButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Where are you going?" />

        </LinearLayout>

    </fragment>
</LinearLayout>

Please help me out. Thank you!


回答1:


You need to call your Geolocation and ShowDefault methods after the map has been initialized, i.e. within onMapReady. Not in onCreate. Like this:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setMyLocationButtonEnabled(true);

    Geolocation();
    ShowDefault();
} 

I just ran your app and it stopped crashing after the above changes, so hope this helps you!

Screenshot:



来源:https://stackoverflow.com/questions/59701736/null-pointer-exception-and-getmapasync-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!