问题
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