mapbox地图随机崩溃

时间:2019-01-22 17:30:37

标签: java android mapbox

我在一个活动中有此mapbox地图,当我进入包含mapview的活动时,一切都很好,当我按回去几秒钟后,它崩溃了...我不确定是什么造成这种情况,但我认为是位置图层引擎或onDestroy()方法上,还是mapView生命周期中缺少某些内容?这是我的代码

我已经尝试过deactivate(),removeLocationUpdates()....我不知道是什么导致了它。我非常感谢您的帮助/建议,顺便说一句,我正在使用mapbox sdk 6.8.1 ...操作系统:Oreo 8.1

public class display_store_locations_nearby extends AppCompatActivity 
implements OnMapReadyCallback,LocationEngineListener,
    PermissionsListener, LocationRecyclerViewAdapter.ClickListener {

private MapView mapView;
private MapboxMap map;
private PermissionsManager permissionsManager;
private LocationEngine locationEngine;
private LocationLayerPlugin locationLayerPlugin;
private Location originLocation;
private GoogleApiClient googleApiClient;
private MapboxDirections directionsApiClient;
private DirectionsRoute currentRoute;
final static int REQUEST_LOCATION = 199;
private static final int CAMERA_MOVEMENT_SPEED_IN_MILSECS = 1200;
private FeatureCollection featureCollection;
protected static final String TAG = "LocationOnOff";

private ArrayList<IndividualLocation> listOfIndividualLocations;
private LocationRecyclerViewAdapter styleRvAdapter;
private RecyclerView locationsRecyclerView;

public double lat,lng;
public ConstraintLayout constraintLayout;
double userLat,userLng;
private LatLng USER_LOCATION;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Mapbox.getInstance(this, getString(R.string.access_token));
    setContentView(R.layout.activity_display_store_locations_nearby);

    mapView = findViewById(R.id.mapView);
    constraintLayout = findViewById(R.id.constaintLayoutMap);
    mapView.onCreate(savedInstanceState);
    if(deviceHasInternetConnection()) {
        getLocationPermission();
    }
    else
    {
        Toast.makeText(getApplicationContext(), R.string.no_internet_message, Toast.LENGTH_SHORT).show();
        finish();
    }

}

@Override
public void onMapReady(MapboxMap mapboxMap) {
    map = mapboxMap;
    enableLocation();
    showBuildingExtrusions();
    mapboxMap.setMinZoomPreference(12);

        listOfIndividualLocations = new ArrayList<>();
        try {
            getFeatureCollectionFromJson();
            Icon shopsIcon = IconFactory.getInstance(display_store_locations_nearby.this).fromResource(R.drawable.monitor);

            List<Feature> featureList = featureCollection.features();
            for (int x = 0; x < featureList.size(); x++) {

                Feature singleLocation = featureList.get(x);

                // Get the single location's String properties to place in its map marker
                String singleLocationName = singleLocation.getStringProperty("Name");
                String singleLocationAddress = singleLocation.getStringProperty("Address");
                String singleLocationPhoneNum = singleLocation.getStringProperty("Number");
                String singleLocationWorkHours = singleLocation.getStringProperty("Work Hours");
                // Get the single location's LatLng coordinates
                Double stringLong = ((Point) singleLocation.geometry()).coordinates().get(0);
                Double stringLat = ((Point) singleLocation.geometry()).coordinates().get(1);

                // Create a new LatLng object with the Position object created above
                LatLng singleLocationLatLng = new LatLng(stringLat, stringLong);
                listOfIndividualLocations.add(new IndividualLocation(
                        singleLocationName,
                        singleLocationAddress,
                        singleLocationPhoneNum,
                        singleLocationLatLng,
                        singleLocationWorkHours
                ));
                map.addMarker(new MarkerOptions()
                        .position(singleLocationLatLng)
                        .title(singleLocationName)
                        .icon(shopsIcon));
            }

            setUpMarkerClickListener();
            setUpRecyclerViewOfLocationCards();
        } catch (Exception exception) {
          //  Log.e("MapActivity", "onCreate: " + exception);
            Toast.makeText(this, R.string.failure_to_load_file, Toast.LENGTH_LONG).show();
        }
}
public void getInformationFromDirectionsApi(double destinationLatCoordinate, double destinationLongCoordinate,
                                            final boolean fromMarkerClick, @Nullable final Integer listIndex,double lt,double ln) {

    boolean hasInternet = deviceHasInternetConnection();
    if(hasInternet) {
        // Set up origin and destination coordinates for the call to the Mapbox Directions API
        Point mockCurrentLocation = Point.fromLngLat(ln, lt);
        //Toast.makeText(getApplicationContext(), lt +"yes",Toast.LENGTH_SHORT).show();
        Point destinationMarker = Point.fromLngLat(destinationLongCoordinate, destinationLatCoordinate);

        // Initialize the directionsApiClient object for eventually drawing a navigation route on the map
        directionsApiClient = MapboxDirections.builder()
                .origin(mockCurrentLocation)
                .destination(destinationMarker)
                .overview(DirectionsCriteria.OVERVIEW_FULL)
                .profile(DirectionsCriteria.PROFILE_DRIVING)
                .accessToken(getString(R.string.access_token))
                .build();

        directionsApiClient.enqueueCall(new Callback<DirectionsResponse>() {
            @Override
            public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
                // Check that the response isn't null and that the response has a route
                if (response.body() == null) {
                    Log.e("MapActivity", "No routes found, make sure you set the right user and access token.");
                    //Toast.makeText(getApplicationContext(), "205", Toast.LENGTH_SHORT).show();
                } else if (response.body().routes().size() < 1) {
                    Log.e("MapActivity", "No routes found");
                    //Toast.makeText(getApplicationContext(), "208", Toast.LENGTH_SHORT).show();
                } else {
                    if (fromMarkerClick) {
                        // Retrieve and draw the navigation route on the map
                        currentRoute = response.body().routes().get(0);
                        drawNavigationPolylineRoute(currentRoute);
                    } else {
                        // Use Mapbox Turf helper method to convert meters to miles and then format the mileage number
                        DecimalFormat df = new DecimalFormat("#.#");
                        String finalConvertedFormattedDistance = String.valueOf(df.format(TurfConversion.convertLength(
                                response.body().routes().get(0).distance(), "meters", "miles")));

                        // Set the distance for each location object in the list of locations
                        if (listIndex != null) {
                            listOfIndividualLocations.get(listIndex).setDistance(finalConvertedFormattedDistance);
                            // Refresh the displayed recyclerview when the location's distance is set
                            styleRvAdapter.notifyDataSetChanged();
                        }
                    }
                }
            }

            @Override
            public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
                Toast.makeText(display_store_locations_nearby.this, R.string.failure_to_retrieve, Toast.LENGTH_LONG).show();
            }
        });
    }
    else
    {
        Toast.makeText(display_store_locations_nearby.this, R.string.no_internet_message, Toast.LENGTH_LONG).show();
    }
}

private void drawNavigationPolylineRoute(DirectionsRoute route) {
    // Check for and remove a previously-drawn navigation route polyline before drawing the new one
    if (map.getPolylines().size() > 0) {
        map.removePolyline(map.getPolylines().get(0));
    }

    // Convert LineString coordinates into a LatLng[]
    LineString lineString = LineString.fromPolyline(route.geometry(), PRECISION_6);
    List<Point> coordinates = lineString.coordinates();
    LatLng[] polylineDirectionsPoints = new LatLng[coordinates.size()];
    for (int i = 0; i < coordinates.size(); i++) {
        polylineDirectionsPoints[i] = new LatLng(
                coordinates.get(i).latitude(),
                coordinates.get(i).longitude());
    }

    // Draw the navigation route polyline on to the map
    map.addPolyline(new PolylineOptions()
            .add(polylineDirectionsPoints)
            .color(R.color.navigationLine)
            .width(9));
}

private void getFeatureCollectionFromJson() throws IOException {
    try {
        // Use fromJson() method to convert the GeoJSON file into a usable FeatureCollection object
        featureCollection = FeatureCollection.fromJson(loadGeoJsonFromAsset("ComputerStores.geojson"));
    } catch (Exception exception) {
        Log.e("MapActivity", "getFeatureCollectionFromJson: " + exception);
    }
}

private void setUpRecyclerViewOfLocationCards() {
    // Initialize the recyclerview of location cards and a custom class for automatic card scrolling

    locationsRecyclerView = findViewById(R.id.map_recycler_view);
    locationsRecyclerView.setHasFixedSize(true);
    locationsRecyclerView.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(this));
    styleRvAdapter = new LocationRecyclerViewAdapter(listOfIndividualLocations,
            getApplicationContext(), this);
    locationsRecyclerView.setAdapter(styleRvAdapter);
    SnapHelper snapHelper = new LinearSnapHelper();
    snapHelper.attachToRecyclerView(locationsRecyclerView);
}

private void setUpMarkerClickListener() {
    map.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(@NonNull Marker marker) {
            // Get the position of the selected marker
            LatLng positionOfSelectedMarker = marker.getPosition();

            // Check that the selected marker isn't the mock device location marker
            if (!marker.getPosition().equals(USER_LOCATION)) {

                for (int x = 0; x < map.getMarkers().size(); x++) {
                    if (map.getMarkers().get(x).getPosition() == positionOfSelectedMarker) {
                        // Scroll the recyclerview to the selected marker's card. It's "x-1" below because
                        // the mock device location marker is part of the marker list but doesn't have its own card
                        // in the actual recyclerview.
                        //Toast.makeText(getApplicationContext(), ""+USER_LOCATION, Toast.LENGTH_SHORT).show();
                        locationsRecyclerView.smoothScrollToPosition(x);
                    }
                }
                adjustMarkerSelectStateIcons(marker);
            }
            // Return true so that the selected marker's info window doesn't pop up
            return true;
        }
    });
}

@SuppressWarnings("MissingPermission")
private void initLocationEngine() {
    locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
    locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
    locationEngine.activate();

    Location lastLocation = locationEngine.getLastLocation();
    if (lastLocation != null) {
        originLocation = lastLocation;
        setCameraPosition(lastLocation);
    } else {
        locationEngine.addLocationEngineListener(this);
    }
}

@SuppressWarnings("MissingPermission")
private void initLocationLayer() {
    locationLayerPlugin = new LocationLayerPlugin(mapView, map, locationEngine);
    locationLayerPlugin.setLocationLayerEnabled(true);
    locationLayerPlugin.setCameraMode(CameraMode.TRACKING);
    locationLayerPlugin.setRenderMode(RenderMode.NORMAL);
}

@Override
@SuppressWarnings("MissingPermission")
public void onConnected() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    locationEngine.requestLocationUpdates();
}

public void setCameraPosition(Location location) {

    map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15.0));

    lat = location.getLatitude();
    lng = location.getLongitude();
    USER_LOCATION = new LatLng(lat,lng);
    // Call getInformationFromDirectionsApi() to eventually display the location's
    // distance from mocked device location
    List<Feature> featureList2 = featureCollection.features();
    for (int x = 0; x < featureList2.size(); x++) {

        Feature singleLocation2 = featureList2.get(x);
        Double stringLong2 = ((Point) singleLocation2.geometry()).coordinates().get(0);
        Double stringLat2 = ((Point) singleLocation2.geometry()).coordinates().get(1);

        // Create a new LatLng object with the Position object created above
        LatLng singleLocationLatLng = new LatLng(stringLat2, stringLong2);

        getInformationFromDirectionsApi(singleLocationLatLng.getLatitude(),
                singleLocationLatLng.getLongitude(), false, x,lat,lng);
    }
    setLat(lat);
    setLng(lng);

    //Toast.makeText(getApplicationContext(), deviceLocation.getLat()+"YES"+latlng[0], Toast.LENGTH_LONG).show();
    /*Icon userIcon = IconFactory.getInstance(display_store_locations_nearby.this).fromResource(R.drawable.figureperson);
    map.addMarker(new MarkerOptions()
            .position(USER_LOCATION)
            .title(getString(R.string.mock_location_title))
            .icon(userIcon));*/
}
@Override
public void onLocationChanged(Location location) {
    if (location != null) {
        originLocation = location;
        setCameraPosition(location);
    }
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {

}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        enableLocation();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@SuppressWarnings("MissingPermission")
@Override
public void onStart() {
    super.onStart();
    if (locationEngine != null) {
        locationEngine.requestLocationUpdates();
    }
    mapView.onStart();
}

@Override
public void onResume() {

    if(!deviceHasInternetConnection())
    {
        Toast.makeText(getApplicationContext(), R.string.no_internet_message, Toast.LENGTH_SHORT).show();
        finish();
    }
    else {
        super.onResume();
        mapView.onResume();
    }
}

@Override
public void onPause() {
    super.onPause();
    mapView.onPause();
}

@Override
public void onStop() {
    super.onStop();
    mapView.onStop();
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    if (mapView != null && !mapView.isDestroyed()) {
        mapView.onLowMemory();
    }
}

@Override
public void onDestroy() {
    super.onDestroy();
    if (locationEngine!=null)
    {
        locationEngine.removeLocationUpdates();
        locationEngine.deactivate();

    }
    mapView.onDestroy();
}


@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mapView.onSaveInstanceState(outState);

}

private String loadGeoJsonFromAsset(String filename) {
    try {
        // Load the GeoJSON file from the local asset folder
        InputStream is = getAssets().open(filename);
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        return new String(buffer, "UTF-8");
    } catch (Exception exception) {
        Log.e("MapActivity", "Exception Loading GeoJSON: " + exception.toString());
        exception.printStackTrace();
        return null;
    }
}

private void showBuildingExtrusions() {
    final String BUILDING_EXTRUSION_COLOR = "#c4dbed";
    final float BUILDING_EXTRUSION_OPACITY = .2f;

    // Use the Mapbox building plugin to display and customize the opacity/color of building extrusions
    BuildingPlugin buildingPlugin = new BuildingPlugin(mapView, map);
    buildingPlugin.setVisibility(true);
    buildingPlugin.setOpacity(BUILDING_EXTRUSION_OPACITY);
    buildingPlugin.setColor(Color.parseColor(BUILDING_EXTRUSION_COLOR));
}

private void enableLocation() {
    //Requesting location services from the user, if granted already proceed to if condition else ask user to grant for permission to access
    // current location
    if (PermissionsManager.areLocationPermissionsGranted(this)) {
        initLocationEngine();
        initLocationLayer();
    } else {
        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

private void getLocationPermission() {
    this.setFinishOnTouchOutside(true);
    // Todo Location Already on ...start
    final LocationManager manager = (LocationManager) display_store_locations_nearby.this.getSystemService(Context.LOCATION_SERVICE);

    if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(display_store_locations_nearby.this)) {
        //Toast.makeText(display_store_locations_nearby.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
        mapView.getMapAsync(this);
    }
    // Todo Location Already on ...end
    if (!hasGPSDevice(display_store_locations_nearby.this)) {
        // Toast.makeText(display_store_locations_nearby.this,"Gps not Supported",Toast.LENGTH_SHORT).show();
    }
    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(display_store_locations_nearby.this)) {
        //  Log.e("keshav","Gps already enabled");
        Toast.makeText(display_store_locations_nearby.this, "GPS not enabled", Toast.LENGTH_SHORT).show();
        enableLoc();
    } else {
        // Log.e("keshav","Gps already enabled");
        //Toast.makeText(display_store_locations_nearby.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
    }
}

private boolean deviceHasInternetConnection() {
    ConnectivityManager connectivityManager = (ConnectivityManager)
            getApplicationContext().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
    return activeNetwork != null && activeNetwork.isConnected();
}

private boolean hasGPSDevice(Context context) {
    final LocationManager mgr = (LocationManager) context
            .getSystemService(Context.LOCATION_SERVICE);
    if (mgr == null)
        return false;
    final List<String> providers = mgr.getAllProviders();
    if (providers == null)
        return false;
    return providers.contains(LocationManager.GPS_PROVIDER);
}

private void enableLoc() {

    if (googleApiClient == null) {
        googleApiClient = new GoogleApiClient.Builder(display_store_locations_nearby.this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle bundle) {

                    }
                    @Override
                    public void onConnectionSuspended(int i) {
                        googleApiClient.connect();
                    }
                })
                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult connectionResult) {
                        //  Log.d("Location error","Location error " + connectionResult.getErrorCode());
                    }
                }).build();
        googleApiClient.connect();

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);

        builder.setAlwaysShow(true);

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());

        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(display_store_locations_nearby.this, REQUEST_LOCATION);

                            finish();
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                        }
                        break;
                }
            }
        });
    }
}

private void repositionMapCamera(LatLng newTarget) {
    CameraPosition newCameraPosition = new CameraPosition.Builder()
            .zoom(16.0)
            .target(newTarget)
            .build();
    map.animateCamera(CameraUpdateFactory.newCameraPosition(newCameraPosition), CAMERA_MOVEMENT_SPEED_IN_MILSECS);
}
private void adjustMarkerSelectStateIcons(Marker marker) {
    double tempLat = getLat();
    double tempLng = getLng();
    // Set all of the markers' icons to the unselected marker icon
    Icon compShopsIcon = IconFactory.getInstance(display_store_locations_nearby.this).fromResource(R.drawable.monitor);
    for (Marker singleMarker : map.getMarkers()) {
        if (!singleMarker.getTitle().equals(getString(R.string.mock_location_title))) {
            singleMarker.setIcon(compShopsIcon);
        }
    }

    Icon tempUserIcon = IconFactory.getInstance(display_store_locations_nearby.this).fromResource(R.drawable.figureperson);
    Icon selectedMode_icon = IconFactory.getInstance(display_store_locations_nearby.this).fromResource(R.drawable.monitor_selected);
    // Change the selected marker's icon to a selected state marker except if the mock device location marker is selected
    if (!marker.getIcon().equals(tempUserIcon)) {
        marker.setIcon(selectedMode_icon);
    }

    // Get the directionsApiClient route to the selected marker except if the mock device location marker is selected
    if (!marker.getIcon().equals(tempUserIcon)) {
        // Check for an internet connection before making the call to Mapbox Directions API
        if (deviceHasInternetConnection()) {
            // Start the call to the Mapbox Directions API
            getInformationFromDirectionsApi(marker.getPosition().getLatitude(),
                    marker.getPosition().getLongitude(), true, null,tempLat,tempLng);
        } else {
            Toast.makeText(this, R.string.no_internet_message, Toast.LENGTH_LONG).show();
        }
    }
}

@Override
public void onDestroyView() {

}

@Override
public void onItemClick(int position) {
    double newLat = getLat();
    double newLng = getLng();
    IndividualLocation selectedLocation = listOfIndividualLocations.get(position);

    // Retrieve and change the selected card's marker to the selected marker icon
    Marker markerTiedToSelectedCard = map.getMarkers().get(position);
     adjustMarkerSelectStateIcons(markerTiedToSelectedCard);

    //Toast.makeText(getApplicationContext(), newLat+"", Toast.LENGTH_SHORT).show();
    // Reposition the map camera target to the selected marker
    LatLng selectedLocationLatLng = selectedLocation.getLocation();
    repositionMapCamera(selectedLocationLatLng);

    // Check for an internet connection before making the call to Mapbox Directions API
    if (deviceHasInternetConnection()) {
        // Start call to the Mapbox Directions API
       getInformationFromDirectionsApi(selectedLocationLatLng.getLatitude(),
                selectedLocationLatLng.getLongitude(), true, null,newLat,newLng);
    } else {
        Toast.makeText(this, R.string.no_internet_message, Toast.LENGTH_LONG).show();
    }
}

@Override
public void OnBackPressed() {
    finish();
}


public void setLat(double lat)
{
    userLat = lat;
}
public void setLng(double lng)
{
    userLng = lng;
}
public double getLat()
{
   return userLat;
}
public double getLng()
{
    return userLng;
}

}

0 个答案:

没有答案