所以,一两年后我又开始了这个项目......当它过时时,它工作正常...但是自从 Android X 问世以来,我想升级我的应用程序并卡在一个错误上,我觉得这很有趣......
快速简要介绍,我有让我在线/离线的按钮..按下按钮时,地图应该缩放到我的当前位置并添加标记..但是错误来了:
日志猫:
Process: com.app.mk.transport, PID: 22142
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.model.Marker com.google.android.gms.maps.GoogleMap.addMarker(com.google.android.gms.maps.model.MarkerOptions)' on a null object reference
at com.app.mk.transport.DriverHome$16$1$1.onComplete(DriverHome.java:1110)
at com.firebase.geofire.GeoFire$2.onComplete(GeoFire.java:178)
at com.google.firebase.database.core.Repo$6.run(com.google.firebase:firebase-database@@19.2.0:404)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
DriverHome.java (不是整个代码(:
private void setUpAutocomplete() {
AutocompleteSupportFragment autocompleteFragment = new AutocompleteSupportFragment();
// final AutocompleteSupportFragment autocompleteFragment;
// autocompleteFragment = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setCountry("MK");
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), getResources().getString(R.string.google_open_api));
}
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ADDRESS));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(@NonNull Place place) {
if (location_switch.isChecked()) {
destination = place.getAddress();
destination = destination.replace(" ", "+");
if (destination.contains("+(FYROM)")) {
destination = destination.replace("+(FYROM)", "");
}
mMap.clear();
getDirection();
}
}
@Override
public void onError(@NonNull Status status) {
Toast.makeText(DriverHome.this, "" + status.toString(), Toast.LENGTH_SHORT).show();
Log.i("MITKASIN", "An error occurred: " + status);
}
});
}
@Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.driver_home, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_trip_history) {
// Handle the camera action
} else if (id == R.id.nav_way_bill) {
} else if (id == R.id.nav_help) {
} else if (id == R.id.nav_settings) {
} else if (id == R.id.nav_update_Info) {
showDialogUpdateInfo();
} else if (id == R.id.nav_sign_out) {
signOut();
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private void showDialogUpdateInfo() {
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(DriverHome.this);
alertDialog.setTitle("Update Information");
alertDialog.setMessage("Please fill in the informations");
LayoutInflater inflater = this.getLayoutInflater();
View dialog_change_pwd = inflater.inflate(R.layout.layout_update_information, null);
final TextInputEditText edt_Name = dialog_change_pwd.findViewById(R.id.edtName);
final TextInputEditText edt_Phone = dialog_change_pwd.findViewById(R.id.edtPhone);
final ImageView image_upload = (ImageView) dialog_change_pwd.findViewById(R.id.image_upload);
image_upload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
chooseImage();
}
});
alertDialog.setView(dialog_change_pwd);
alertDialog.setPositiveButton("UPDATE", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
final android.app.AlertDialog waitingDialog = new SpotsDialog.Builder()
.setContext(DriverHome.this)
.setTheme(R.style.Orange)
.setMessage(R.string.waitingDialog_title)
.setCancelable(false)
.build();
waitingDialog.show();
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
@Override
public void onSuccess(Account account) {
String name = edt_Name.getText().toString();
String phone = edt_Phone.getText().toString();
Map<String, Object> updateInfo = new HashMap<>();
if (!TextUtils.isEmpty(name))
updateInfo.put("name", name);
if (!TextUtils.isEmpty(phone))
updateInfo.put("phone", phone);
DatabaseReference driverInformations = FirebaseDatabase.getInstance().getReference(Common.user_driver_tbl);
driverInformations.child(account.getId())
.updateChildren(updateInfo)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
waitingDialog.dismiss();
if (task.isSuccessful()) {
Toast.makeText(DriverHome.this, "Information updated!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DriverHome.this, "Information update Failed!", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onError(AccountKitError accountKitError) {
}
});
}
});
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
private void chooseImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), Common.PICK_IMAGE_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Common.PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri saveUri = data.getData();
if (saveUri != null) {
final ProgressDialog mDialog = new ProgressDialog(this);
mDialog.setMessage("Uploading...");
mDialog.show();
String imageName = UUID.randomUUID().toString();
final StorageReference imageFolder = storageReference.child("images/" + imageName);
imageFolder.putFile(saveUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
mDialog.dismiss();
Toast.makeText(DriverHome.this, "Uploaded !", Toast.LENGTH_SHORT).show();
imageFolder.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(final Uri uri) {
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
@Override
public void onSuccess(Account account) {
Map<String, Object> avatarUpdate = new HashMap<>();
avatarUpdate.put("avatarUrl", uri.toString());
DatabaseReference driverInformations = FirebaseDatabase.getInstance().getReference(Common.user_driver_tbl);
driverInformations.child(account.getId())
.updateChildren(avatarUpdate)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(DriverHome.this, "Uploaded!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(DriverHome.this, "Upload error !", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onError(AccountKitError accountKitError) {
}
});
}
});
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
mDialog.setMessage("Upliaded " + progress + "%");
}
});
}
}
}
private void signOut() {
AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
else
builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to logout?")
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Paper.init(this);
AccountKit.logOut();
Intent intent = new Intent(DriverHome.this, MainActivity.class);
startActivity(intent);
finish();
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
}
private float getBearing(LatLng startPosition, LatLng endPosition) {
double lat = Math.abs(startPosition.latitude - endPosition.latitude);
double lng = Math.abs(startPosition.longitude - endPosition.longitude);
if (startPosition.latitude < endPosition.latitude && startPosition.longitude < endPosition.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)));
else if (startPosition.latitude >= endPosition.latitude && startPosition.longitude < endPosition.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
else if (startPosition.latitude >= endPosition.latitude && startPosition.longitude >= endPosition.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180);
else if (startPosition.latitude < endPosition.latitude && startPosition.longitude >= endPosition.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
return -1;
}
private void updateFirebaseToken() {
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
@Override
public void onSuccess(Account account) {
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference tokens = db.getReference(Common.token_tbl);
Token token = new Token(FirebaseInstanceId.getInstance().getToken());
tokens.child(account.getId())
.setValue(token);
}
@Override
public void onError(AccountKitError accountKitError) {
}
});
}
private void getDirection() {
currentPosition = new LatLng(Common.mLastLocation.getLatitude(), Common.mLastLocation.getLongitude());
String requestApi = null;
try {
requestApi = "https://maps.googleapis.com/maps/api/directions/json?" +
"mode=driving&" +
"transit_routing_reference=less_driving&" +
"origin=" + currentPosition.latitude + "," + currentPosition.longitude + "&" +
"destination=" + destination + "&" +
"key=" + getResources().getString(R.string.google_direction_api);
Log.i("MITKASIN", requestApi);
mServices.getPath(requestApi)
.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
try {
JSONObject jsonObject = new JSONObject(response.body());
JSONArray jsonArray = jsonObject.getJSONArray("routes");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject route = jsonArray.getJSONObject(i);
JSONObject poly = route.getJSONObject("overview_polyline");
String polyline = poly.getString("points");
polyLineList = decodePoly(polyline);
}
if (!polyLineList.isEmpty()) {
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (LatLng latLng : polyLineList)
builder.include(latLng);
LatLngBounds bounds = builder.build();
CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 1);
mMap.animateCamera(mCameraUpdate);
// mMap.getUiSettings().setAllGesturesEnabled(true);
}
polylineOptiuons = new PolylineOptions();
polylineOptiuons.color(Color.GRAY);
polylineOptiuons.width(5);
polylineOptiuons.startCap(new SquareCap());
polylineOptiuons.endCap(new SquareCap());
polylineOptiuons.jointType(JointType.ROUND);
polylineOptiuons.addAll(polyLineList);
greyPolyline = mMap.addPolyline(polylineOptiuons);
blackPolylineOptions = new PolylineOptions();
blackPolylineOptions.color(Color.BLACK);
blackPolylineOptions.width(7);
blackPolylineOptions.startCap(new SquareCap());
blackPolylineOptions.endCap(new SquareCap());
blackPolylineOptions.jointType(JointType.ROUND);
blackPolyline = mMap.addPolyline(blackPolylineOptions);
if (!polyLineList.isEmpty()) {
mMap.addMarker(new MarkerOptions()
.position(polyLineList.get(polyLineList.size() - 1))
.title("Pickup Location"));
}
//Animation
ValueAnimator polyLineAnimator = ValueAnimator.ofInt(0, 100);
polyLineAnimator.setDuration(2000);
polyLineAnimator.setInterpolator(new LinearInterpolator());
polyLineAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
List<LatLng> points = greyPolyline.getPoints();
int percentValue = (int) valueAnimator.getAnimatedValue();
int size = points.size();
int newPoints = (int) (size * (percentValue / 100.0f));
List<LatLng> p = points.subList(0, newPoints);
blackPolyline.setPoints(p);
}
});
polyLineAnimator.start();
carMarker = mMap.addMarker(new MarkerOptions()
.position(currentPosition)
.flat(true)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.car)));
handler = new Handler();
index = -1;
next = 1;
handler.postDelayed(drawPathRunnable, 2000);
// mMap.getUiSettings().setScrollGesturesEnabled(true);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Toast.makeText(DriverHome.this, "" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
// mMap.getUiSettings().setScrollGesturesEnabled(true);
}
private List decodePoly(String encoded) {
List poly = new ArrayList();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PEMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
buildLocationCallback();
buildLocationRequest();
if (location_switch.isChecked())
displayLocation();
}
}
}
private void setUpLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//Request runtime permission
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
}, MY_PEMISSION_REQUEST_CODE);
} else {
buildLocationRequest();
buildLocationCallback();
if (location_switch.isChecked())
displayLocation();
}
}
private void buildLocationCallback() {
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
Common.mLastLocation = location;
}
displayLocation();
}
};
}
private void buildLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
private void displayLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
Common.mLastLocation = location;
if (Common.mLastLocation != null) {
if (location_switch.isChecked()) {
final double latitude = Common.mLastLocation.getLatitude();
final double longitude = Common.mLastLocation.getLongitude();
//Update to Firebase
AccountKit.getCurrentAccount(new AccountKitCallback<Account>() {
@Override
public void onSuccess(Account account) {
geoFire.setLocation(account.getId(), new GeoLocation(latitude, longitude), new GeoFire.CompletionListener() {
@Override
public void onComplete(String key, DatabaseError error) {
if (mCurrent != null) {
mCurrent.remove();
}
mCurrent = mMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.title("Your Location"));
// Move camera to this position when set to online!
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 14.5f));
// Draw animation rotate marker
// rotateMarker(mCurrent, 360, mMap);
}
});
}
@Override
public void onError(AccountKitError accountKitError) {
}
});
}
} else {
Log.d("ERROR", "Cannot get your location");
}
}
});
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.setTrafficEnabled(false);
mMap.setIndoorEnabled(false);
mMap.setBuildingsEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(false);
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.style_json));
if (!success) {
Log.e("Mitkasin", "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e("Mitkasin", "Can't find style. Error: ", e);
}
if (ActivityCompat.checkSelfPermission(DriverHome.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(DriverHome.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
buildLocationRequest();
buildLocationCallback();
fusedLocationProviderClient.requestLocationUpdates(mLocationRequest, locationCallback, Looper.myLooper());
}
}
请原谅我讨厌的代码 tho :D 对不起,如果这是一个愚蠢的问题,但idk我在这里错过了什么......
只有在映射初始化后,您才需要调用displayLocation
和getDirection
方法(即mMap = googleMap
(。查看相关的空指针异常和获取映射异步错误
例如:
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.setTrafficEnabled(false);
mMap.setIndoorEnabled(false);
mMap.setBuildingsEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(false);
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.style_json));
if (!success) {
Log.e("Mitkasin", "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e("Mitkasin", "Can't find style. Error: ", e);
}
displayLocation();
getDirection();
}
希望这有帮助!