Привет, я хочу запустить навигацию в android через mapbox, приложение cra sh на моем телефоне, когда
shouldSimulateRoute(false)
, когда оно истинно, работает
в эмуляторе приложение перенаправляется и ничего не происходит (стрелка находится в Калифорнии) и на телефоне (с apk) приложение cra sh и перезагружается, а затем во второй раз происходит сбой и закрывает приложение
здесь это версия, которую я использую
implementation 'com.mapbox.mapboxsdk:mapbox-android-navigation-ui:0.42.3'
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.5.0'
вот мой код
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.mapbox.api.directions.v5.models.BannerInstructions;
import com.mapbox.api.directions.v5.models.DirectionsResponse;
import com.mapbox.api.directions.v5.models.DirectionsRoute;
import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.services.android.navigation.ui.v5.NavigationView;
import com.mapbox.services.android.navigation.ui.v5.NavigationViewOptions;
import com.mapbox.services.android.navigation.ui.v5.OnNavigationReadyCallback;
import com.mapbox.services.android.navigation.ui.v5.listeners.BannerInstructionsListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.InstructionListListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.NavigationListener;
import com.mapbox.services.android.navigation.ui.v5.listeners.SpeechAnnouncementListener;
import com.mapbox.services.android.navigation.ui.v5.map.NavigationMapboxMap;
import com.mapbox.services.android.navigation.ui.v5.voice.SpeechAnnouncement;
import com.mapbox.services.android.navigation.v5.navigation.NavigationRoute;
import com.mapbox.services.android.navigation.v5.routeprogress.ProgressChangeListener;
import com.mapbox.services.android.navigation.v5.routeprogress.RouteProgress;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class HomeActivity extends AppCompatActivity implements OnNavigationReadyCallback,
NavigationListener, ProgressChangeListener, InstructionListListener, SpeechAnnouncementListener,
BannerInstructionsListener {
private static final Point ORIGIN = Point.fromLngLat(-77.03194990754128, 38.909664963450105);
private static final Point DESTINATION = Point.fromLngLat(-77.0270025730133, 38.91057077063121);
private static final int INITIAL_ZOOM = 16;
private NavigationView navigationView;
private View spacer;
private TextView speedWidget;
private String authKey;
private String missionId;
private Double lngOrigin;
private Double latOrigin;
private Double lngDest;
private Double latDest;
private static ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private FloatingActionButton fabNightModeToggle;
private boolean bottomSheetVisible = true;
private boolean instructionListShown = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat_Light_NoActionBar);
initNightMode();
getCoordinates();
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, "pk.eyJ1Ijoic2NobWVtNTUiLCJhIjoiY2syZDVjcGVmMDd2YzNpdGRrYWNneThxYSJ9.f0u1jB1HMxihXqAmHfVe7g");
setContentView(R.layout.activity_home);
navigationView = findViewById(R.id.navigationView);
fabNightModeToggle = findViewById(R.id.fabToggleNightMode);
speedWidget = findViewById(R.id.speed_limit);
spacer = findViewById(R.id.spacer);
setSpeedWidgetAnchor(R.id.summaryBottomSheet);
CameraPosition initialPosition = new CameraPosition.Builder()
.target(new LatLng(ORIGIN.latitude(),ORIGIN.longitude()))
.zoom(INITIAL_ZOOM)
.build();
navigationView.onCreate(savedInstanceState);
navigationView.initialize(this, initialPosition);
}
private void getCoordinates() {
Intent intent = getIntent();
lngOrigin = intent.getDoubleExtra("LONGITUDE_ORIGIN_POINT",0);
latOrigin = intent.getDoubleExtra("LATITUDE_ORIGIN_POINT",0);
lngDest = intent.getDoubleExtra("LONGITUDE_DESTINATION_POINT",0);
latDest = intent.getDoubleExtra("LATITUDE_DESTINATION_POINT",0);
}
@Override
public void onNavigationReady(boolean isRunning) {
// HomeActivity activity = new HomeActivity();
// Intent intent = getIntent();
// activity.missionId = missionId = intent.getStringExtra("MISSION_ID");
// activity.authKey = intent.getStringExtra("AUTHORIZATION_KEY");
// activity.latDest= intent.getDoubleExtra("LATITUDE_DESTINATION_POINT",0);
// activity.lngDest=intent.getDoubleExtra("LONGITUDE_DESTINATION_POINT",0);
// executorService.scheduleAtFixedRate(activity::postCoordinates, 10, 30, TimeUnit.SECONDS);
fetchRoute();
}
private void postCoordinates() {
NavigationMapboxMap map = navigationView.retrieveNavigationMapboxMap();
String userLat = String.valueOf(map.retrieveMap().getLocationComponent().getLastKnownLocation().getLatitude());
String userLng = String.valueOf(map.retrieveMap().getLocationComponent().getLastKnownLocation().getLongitude());
String data = "\t{\n" +
"\t\"mission_id\":"+missionId+",\n" +
"\t\"depart_lat\":"+userLat+",\n" +
"\t\"depart_lon\":"+userLng+",\n" +
"\t\"destination_lon\":"+lngDest+",\n" +
"\t\"destination_lat\":"+latDest+"\n" +
"\t}";
URL obj = null;
HttpURLConnection con = null;
try {
obj = new URL("https://some url");
con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setRequestProperty("Authorization", authKey);
}catch (IOException e) {
e.printStackTrace();
}
OutputStream os = null;
con.setDoOutput(true);
try {
os = con.getOutputStream();
os.write(data.getBytes());
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
int responseCode = 0;
try {
responseCode = con.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onStart() {
super.onStart();
navigationView.onStart();
}
@Override
public void onResume() {
super.onResume();
navigationView.onResume();
}
@Override
public void onLowMemory() {
super.onLowMemory();
navigationView.onLowMemory();
}
@Override
public void onBackPressed() {
// If the navigation view didn't need to do anything, call super
if (!navigationView.onBackPressed()) {
super.onBackPressed();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
navigationView.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
navigationView.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onPause() {
super.onPause();
navigationView.onPause();
}
@Override
public void onStop() {
super.onStop();
navigationView.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
navigationView.onDestroy();
if (isFinishing()) {
saveNightModeToPreferences(AppCompatDelegate.MODE_NIGHT_AUTO);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
}
}
@Override
public void onCancelNavigation() {
// Navigation canceled, finish the activity
finish();
}
public void finishNavigation (View v){
finish();
}
@Override
public void onNavigationFinished() {
// Intentionally empty
}
@Override
public void onNavigationRunning() {
// Intentionally empty
}
@Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
setSpeed(location);
}
@Override
public void onInstructionListVisibilityChanged(boolean shown) {
instructionListShown = shown;
speedWidget.setVisibility(shown ? View.GONE : View.VISIBLE);
if (instructionListShown) {
fabNightModeToggle.hide();
} else if (bottomSheetVisible) {
fabNightModeToggle.show();
fabNightModeToggle.show();
}
}
@Override
public SpeechAnnouncement willVoice(SpeechAnnouncement announcement) {
return SpeechAnnouncement.builder().announcement("All announcements will be the same.").build();
}
@Override
public BannerInstructions willDisplay(BannerInstructions instructions) {
return instructions;
}
private void startNavigation(DirectionsRoute directionsRoute) {
NavigationViewOptions.Builder options =
NavigationViewOptions.builder()
.navigationListener(this)
.directionsRoute(directionsRoute)
.shouldSimulateRoute(false)
.progressChangeListener(this)
.instructionListListener(this)
.speechAnnouncementListener(this)
.bannerInstructionsListener(this);
setBottomSheetCallback(options);
setupNightModeFab();
navigationView.startNavigation(options.build());
}
private void fetchRoute() {
//Point origin = Point.fromLngLat(lngOrigin, latOrigin);
//Point destination = Point.fromLngLat(lngDest, latDest);
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(ORIGIN)
.destination(DESTINATION)
.alternatives(true)
.build()
.getRoute(new Callback<DirectionsResponse>() {
@Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
DirectionsRoute directionsRoute = response.body().routes().get(0);
startNavigation(directionsRoute);
}
@Override
public void onFailure(Call<DirectionsResponse> call, Throwable t) {
}
});
}
/**
* Sets the anchor of the spacer for the speed widget, thus setting the anchor for the speed widget
* (The speed widget is anchored to the spacer, which is there because padding between items and
* their anchors in CoordinatorLayouts is finicky.
*
* @param res resource for view of which to anchor the spacer
*/
private void setSpeedWidgetAnchor(@IdRes int res) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) spacer.getLayoutParams();
layoutParams.setAnchorId(res);
spacer.setLayoutParams(layoutParams);
}
private void setBottomSheetCallback(NavigationViewOptions.Builder options) {
options.bottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
switch (newState) {
case BottomSheetBehavior.STATE_HIDDEN:
bottomSheetVisible = false;
fabNightModeToggle.hide();
setSpeedWidgetAnchor(R.id.recenterBtn);
break;
case BottomSheetBehavior.STATE_EXPANDED:
bottomSheetVisible = true;
break;
case BottomSheetBehavior.STATE_SETTLING:
if (!bottomSheetVisible) {
// View needs to be anchored to the bottom sheet before it is finished expanding
// because of the animation
fabNightModeToggle.show();
setSpeedWidgetAnchor(R.id.summaryBottomSheet);
}
break;
default:
return;
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
}
private void setupNightModeFab() {
fabNightModeToggle.setOnClickListener(view -> toggleNightMode());
}
private void toggleNightMode() {
int currentNightMode = getCurrentNightMode();
alternateNightMode(currentNightMode);
}
private void initNightMode() {
int nightMode = retrieveNightModeFromPreferences();
AppCompatDelegate.setDefaultNightMode(nightMode);
}
private int getCurrentNightMode() {
return getResources().getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
}
private void alternateNightMode(int currentNightMode) {
int newNightMode;
if (currentNightMode == Configuration.UI_MODE_NIGHT_YES) {
newNightMode = AppCompatDelegate.MODE_NIGHT_NO;
} else {
newNightMode = AppCompatDelegate.MODE_NIGHT_YES;
}
saveNightModeToPreferences(newNightMode);
recreate();
}
private int retrieveNightModeFromPreferences() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
return preferences.getInt(getString(R.string.current_night_mode), AppCompatDelegate.MODE_NIGHT_AUTO);
}
private void saveNightModeToPreferences(int nightMode) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt(getString(R.string.current_night_mode), nightMode);
editor.apply();
}
private void setSpeed(Location location) {
String string = String.format("%d\nMPH", (int) (location.getSpeed() * 2.2369));
int mphTextSize = getResources().getDimensionPixelSize(R.dimen.mph_text_size);
int speedTextSize = getResources().getDimensionPixelSize(R.dimen.speed_text_size);
SpannableString spannableString = new SpannableString(string);
spannableString.setSpan(new AbsoluteSizeSpan(mphTextSize),
string.length() - 4, string.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannableString.setSpan(new AbsoluteSizeSpan(speedTextSize),
0, string.length() - 3, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
speedWidget.setText(spannableString);
if (!instructionListShown) {
speedWidget.setVisibility(View.VISIBLE);
}
}
}
вот код деятельности. xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/button"
android:background="@drawable/btn_rounder_corner"
android:layout_width="90dp"
android:layout_height="45dp"
android:layout_gravity="bottom|center_horizontal"
android:layout_marginBottom="80dp"
android:onClick="finishNavigation"
android:text="@string/button"
android:textColor="#ffffff" />
<com.mapbox.services.android.navigation.ui.v5.NavigationView
android:id="@+id/navigationView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_anchor="@+id/navigationView"
app:layout_anchorGravity="center"
app:navigationLightTheme="@style/MyCustomTheme"
app:navigationDarkTheme="@style/NavigationViewDark"
/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabToggleNightMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|start"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:tint="@android:color/white"
app:layout_anchor="@id/spacer"
app:layout_anchorGravity="top|end"
/>
<TextView
android:id="@+id/speed_limit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginLeft="16dp"
android:background="@android:color/white"
android:elevation="3dp"
android:gravity="center"
android:padding="6dp"
android:textColor="@android:color/black"
android:textSize="35sp"
android:visibility="gone"
app:layout_anchor="@id/spacer"
app:layout_anchorGravity="top"/>
<View
android:id="@+id/spacer"
android:layout_width="wrap_content"
android:layout_height="6dp"
android:layout_gravity="top"
android:background="@android:color/transparent"
app:layout_anchorGravity="top"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>