Mapbox Navigation `onProgressChange()` not fired when 0.4.0-SNAPSHOT used - android

I've implemented Mapbox Navigation and lately got it working, now I want to update navigation from 0.3.1 to 0.4.0-SNAPSHOT, unfortunately after update onProgressChange() not being fired even though I haven't made any changes to code.
NOTE: onLocationChanged works in both cases.
EDIT
NOTE: 0.3.1 still fires onProgressChange() although its speed is 0.0, but not 0.4.0-SNAPSHOT
public class MapActivity implements MapboxMap.OnMarkerClickListener
,OnMapReadyCallback, AlertLevelChangeListener, ProgressChangeListener, OffRouteListener
,NavigationEventListener, LocationEngineListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fabStartNavigation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// star Navigation
startNavigation();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
// Remove all navigation listeners being used
mNavigation.removeNavigationEventListener(this);
mNavigation.removeAlertLevelChangeListener(this);
mNavigation.removeProgressChangeListener(this);
mNavigation.removeOffRouteListener(this);
// End the navigation session
mNavigation.endNavigation();
mapView.onDestroy();
}
//navigation controller
private void startNavigation(){
mNavigation.addNavigationEventListener(this);
mNavigation.addAlertLevelChangeListener(this);
mNavigation.addOffRouteListener(this);
mNavigation.addProgressChangeListener(this);
mNavigation.setSnapToRoute(true);
/*LocationEngine mLocationEngine = LostLocationEngine.getLocationEngine(this);
// mNavigation.setLocationEngine(mLocationEngine);*/
mLocationEngine = LostLocationEngine.getLocationEngine(this);
mLocationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
mLocationEngine.addLocationEngineListener(this);
mLocationEngine.activate();
mNavigation.startNavigation(mPlannedRoute);
}
// navigation listeners
#Override
public void onAlertLevelChange(int alertLevel, RouteProgress routeProgress) {
switch (alertLevel) {
case HIGH_ALERT_LEVEL:
break;
case MEDIUM_ALERT_LEVEL:
break;
case LOW_ALERT_LEVEL:
break;
case ARRIVE_ALERT_LEVEL:
break;
case NONE_ALERT_LEVEL:
break;
case DEPART_ALERT_LEVEL:
break;
}
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
}
#Override
public void userOffRoute(Location location) {
}
#Override
public void onRunning(boolean running) {
}
#Override
public void onConnected() {
mNavigation.setLocationEngine(mLocationEngine);
mLocationEngine.requestLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
}
}

Is it possible that the location updates you are receiving have no speed values? If the speed value is 0 or less, onProgressChange doesn't get called. If this isn't the issue, any additional information and code snippets will help to troubleshoot this.

Related

Map Download by Specifying a Bounding Box implementation

i have read in the premium user guide that we can download a small amount of map with MapDataPrefetcher. i use a Mapfragment to show the map in my app, and it says that the MapEngine is automatically initialized by using MapFragment.
the problem is that i can't understand how to apply the methods and where i need to initialize the request for downloading the bounding box itself. its not so clear in the user guide.
if someone here can help me with that problem or send an example of the implementation i will be very grateful!
this is my init method for the map and the map fragment
private void initialize() {
setContentView(R.layout.activity_main);
// Search for the map fragment to finish setup by calling init().
// mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapfragment);
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapfragment);
mLocationInfo = (TextView) findViewById(R.id.textViewLocationInfo);
mapFragment.setRetainInstance(false);
// Set up disk cache path for the map service for this application
// It is recommended to use a path under your application folder for storing the disk cache
boolean success = com.here.android.mpa.common.MapSettings.setIsolatedDiskCacheRootPath(
getApplicationContext().getExternalFilesDir(null)+File.separator + ".here-maps",
"com.example.andrey88.MapService"); /* ATTENTION! Do not forget to update {YOUR_INTENT_NAME} */
if (!success) {
Toast.makeText(getApplicationContext(), "Unable to set isolated disk cache path.", Toast.LENGTH_LONG);
} else {
mapFragment.init(new OnEngineInitListener() {
#Override
public void onEngineInitializationCompleted(OnEngineInitListener.Error error) {
if (error == OnEngineInitListener.Error.NONE) {
// retrieve a reference of the map from the map fragment
map = mapFragment.getMap();
// Set the map center to the Ruppin region (no animation)
map.setCenter(new GeoCoordinate(32.343099, 34.911272, 0.0), Map.Animation.NONE);
// Set the zoom level
map.setZoomLevel(17.8);
map.setMapScheme(Map.Scheme.PEDESTRIAN_DAY);
map.setLandmarksVisible(false);
map.setProjectionMode(Map.Projection.MERCATOR);
map.getPedestrianFeaturesVisible();
// position of user
map.addTransformListener(MainActivity.this);
mPositioningManager = PositioningManager.getInstance();
// check source of getting geo location
mHereLocation = LocationDataSourceHERE.getInstance(
new StatusListener() {
#Override
public void onOfflineModeChanged(boolean offline) {
// called when offline mode changes
}
#Override
public void onAirplaneModeEnabled() {
// called when airplane mode is enabled
}
#Override
public void onWifiScansDisabled() {
// called when Wi-Fi scans are disabled
}
#Override
public void onBluetoothDisabled() {
// called when Bluetooth is disabled
}
#Override
public void onCellDisabled() {
// called when Cell radios are switch off
}
#Override
public void onGnssLocationDisabled() {
// called when GPS positioning is disabled
}
#Override
public void onNetworkLocationDisabled() {
// called when network positioning is disabled
}
#Override
public void onServiceError(StatusListener.ServiceError serviceError) {
// called on HERE service error
}
#Override
public void onPositioningError(PositioningError positioningError) {
// called when positioning fails
}
#Override
public void onWifiIndoorPositioningNotAvailable() {
// called when running on Android 9.0 (Pie) or newer
}
});
if (mHereLocation == null) {
Toast.makeText(MainActivity.this, "LocationDataSourceHERE.getInstance(): failed, exiting", Toast.LENGTH_LONG).show();
finish();
}
mPositioningManager.setDataSource(mHereLocation);
mPositioningManager.addListener(new WeakReference<PositioningManager.OnPositionChangedListener>(MainActivity.this));
// Create a custom marker image
com.here.android.mpa.common.Image myImage = new com.here.android.mpa.common.Image();
try {myImage.setImageResource(R.drawable.marker_round);
} catch (IOException e) {
finish();
}
initMarkers(myImage);
createPolygon();
mapFragment.getMapGesture().addOnGestureListener(new MapGesture.OnGestureListener() {
#Override
public void onPanStart() {
}
#Override
public void onPanEnd() {
}
#Override
public void onMultiFingerManipulationStart() {
}
#Override
public void onMultiFingerManipulationEnd() {
}
#Override
public boolean onMapObjectsSelected(List<ViewObject> list) {
return false;
}
#Override
public boolean onTapEvent(PointF pointF) {
return false;
}
#Override
public boolean onDoubleTapEvent(PointF pointF) {
return false;
}
#Override
public void onPinchLocked() {
}
#Override
public boolean onPinchZoomEvent(float v, PointF pointF) {
return false;
}
#Override
public void onRotateLocked() {
}
#Override
public boolean onRotateEvent(float v) {
return false;
}
#Override
public boolean onTiltEvent(float v) {
return false;
}
#Override
public boolean onLongPressEvent(PointF pointF) {
return false;
}
#Override
public void onLongPressRelease() {
}
#Override
public boolean onTwoFingerTapEvent(PointF pointF) {
return false;
}
}, 0, false);
if (mPositioningManager.start(PositioningManager.LocationMethod.GPS_NETWORK_INDOOR)) {
mapFragment.getPositionIndicator().setVisible(true);
} else {
Toast.makeText(MainActivity.this, "PositioningManager.start: failed, exiting", Toast.LENGTH_LONG).show();
finish();
}
}
else {
Log.d("errorTag",error.name());
onDestroy();
}
}
});
}
}
MapEngine must be initialized before it can be used. It should be done in the main thread. MapEngine is automatically initialized for your application by using AndroidXMapFragment. AndroidXMapFragment is a fragment class applications can use as a UI module in an activity for map display. However, if your application does not use AndroidXMapFragment classes, then the application should initialize the MapEngine directly before using any HERE APIs. You can do this by calling MapEngine.init(ApplicationContext, OnEngineInitListener) as shown below:
MapEngine mapEngine = MapEngine.getInstance(); ApplicationContext appContext = new ApplicationContext(context); mapEngine.init(appContext, new OnEngineInitListener() { #Override public void onEngineInitializationCompleted(Error error) {
if (error == OnEngineInitListener.Error.NONE) {
// Post initialization code goes here
} else {
// handle factory initialization failure
} } });

Mapbox Navigation `offRoute()` called when first `step` finishes

So, I'm using version Mapbox Navigation 0.3.1, I'm fetching route from private OSRM server. Snap-to-route and other features are just working fine, however when 1st step finishes navigation wouldn't proceed to the next step and offRoute method is being called. I'm stuck here for like 1-2 months. I would appreciate any help.
Below, my code snippet of Mapbox Navigation implementation.
public class MapActivity implements MapboxMap.OnMarkerClickListener
,OnMapReadyCallback, AlertLevelChangeListener, ProgressChangeListener, OffRouteListener
,NavigationEventListener, LocationEngineListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fabStartNavigation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// star Navigation
startNavigation();
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
// Remove all navigation listeners being used
mNavigation.removeNavigationEventListener(this);
mNavigation.removeAlertLevelChangeListener(this);
mNavigation.removeProgressChangeListener(this);
mNavigation.removeOffRouteListener(this);
// End the navigation session
mNavigation.endNavigation();
mapView.onDestroy();
}
//navigation controller
private void startNavigation(){
mNavigation.addNavigationEventListener(this);
mNavigation.addAlertLevelChangeListener(this);
mNavigation.addOffRouteListener(this);
mNavigation.addProgressChangeListener(this);
mNavigation.setSnapToRoute(true);
/*LocationEngine mLocationEngine = LostLocationEngine.getLocationEngine(this);
// mNavigation.setLocationEngine(mLocationEngine);*/
mLocationEngine = LostLocationEngine.getLocationEngine(this);
mLocationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
mLocationEngine.addLocationEngineListener(this);
mLocationEngine.activate();
mNavigation.startNavigation(mPlannedRoute);
}
// navigation listeners
#Override
public void onAlertLevelChange(int alertLevel, RouteProgress routeProgress) {
switch (alertLevel) {
case HIGH_ALERT_LEVEL:
break;
case MEDIUM_ALERT_LEVEL:
break;
case LOW_ALERT_LEVEL:
break;
case ARRIVE_ALERT_LEVEL:
break;
case NONE_ALERT_LEVEL:
break;
case DEPART_ALERT_LEVEL:
break;
}
}
#Override
public void onProgressChange(Location location, RouteProgress routeProgress) {
}
#Override
public void userOffRoute(Location location) {
}
#Override
public void onRunning(boolean running) {
}
#Override
public void onConnected() {
mNavigation.setLocationEngine(mLocationEngine);
mLocationEngine.requestLocationUpdates();
}
#Override
public void onLocationChanged(Location location) {
}
}
This sounds like your running into a really old bug that has since been fixed. My advice would be to either upgrade to 0.4.0 or the 0.5.0-snapshot.

Get data from viewpager fragments

I have an Activity which has a Save details button and a Viewpager which contains 4 fragments. The Fragments contains User details form. Once the Save button is clicked I need to get the data from all fragments and save the details. How to get the data entered by the user in all 4 fragments when Save button is clicked in the activity?
I just worked on an app that had the same use case. In addition, I had to save the data on a back navigation as well. The problem was a bit more difficult that I though it should have been. The problems came from the fact that not all the fragments in the ViewPager are guaranteed to be alive. They either may not have been started yet, or destroyed when the user paged off of them.
To solve the problem, I took inspiration from this blog post about handing back-press events. I had to modify it a bit to allow for any fragments that may be running and not just one.
public abstract class BackHandledFragment extends Fragment {
protected BackHandlerInterface backHandlerInterface;
public abstract String getTagText();
public abstract boolean onBackPressed();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!(getActivity() instanceof BackHandlerInterface)) {
throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
} else {
backHandlerInterface = (BackHandlerInterface) getActivity();
}
}
#Override
public void onResume() {
super.onResume();
backHandlerInterface.addRunningFragment(this);
}
#Override
public void onPause() {
super.onPause();
backHandlerInterface.removeRunningFragment(this);
}
public interface BackHandlerInterface {
public void addRunningFragment(BackHandledFragment backHandledFragment);
public void removeRunningFragment(BackHandledFragment backHandledFragment);
}
}
The Activity implements the interface and tracks the active fragments:
public class EditActivity implements BackHandledFragment.BackHandlerInterface
{
private List<BackHandledFragment> listActiveFragments = new ArrayList<>
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Notify each active fragment that the back was pressed, this will allow
// them to save any data.
for (BackHandledFragment bf : listActiveFragments) {
bf.onBackPressed();
}
}
#Override
public void addRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.add(backHandledFragment);
}
#Override
public void removeRunningFragment(BackHandledFragment backHandledFragment) {
listActiveFragments.remove(backHandledFragment);
}();
}
Each fragment must extend BackHandledFragment:
public class DetailNetworkFragment extends BackHandledFragment {
#Override
public void onPause() {
super.onPause();
EventBus.getDefault().unregister(this);
saveDataFields();
}
#Override
public void onResume() {
super.onResume();
EventBus.getDefault().register(this);
}
#Override
public String getTagText() {
return TAG;
}
#Override
public boolean onBackPressed() {
saveDataFields();
return false;
}
}
The saveDataFields() is not too interesting. It just copies the data out of the UI views and saves them back to an object in the Activity.

Android vungle event listener

I'm having a problem with vungle, I want the dialog fragment to appear after the video ad ends, my code looks good and there is no errors, the video starts and ends but my dialog fragment never appears, here is my code:
private final EventListener vungleListener = new EventListener(){
#Override
public void onVideoView(boolean isCompletedView, int watchedMillis, int videoDurationMillis) {
if (isCompletedView){
frag.show(fm, "");
}
}
#Override
public void onAdStart() {
// Called before playing an ad
}
#Override
public void onAdEnd(boolean wasCallToActionClicked) {
}
#Override
public void onAdPlayableChanged(boolean isAdPlayable) {
}
#Override
public void onAdUnavailable(String reason) {
}
};
According to Vungle the method onVideoView is deprecated and the method onAdEnd should be used instead. You should try moving the fragment being shown to onAdEnd like below:
#Override
public void onAdEnd(boolean wasCallToActionClicked) {
frag.show(fm, "");
}

Trouble with Sensor Listeners and Ambient mode in Android Wear fragments

I have an app that uses sensor listeners in fragments to detect shaking gestures on a Moto360 smartwatch. Each fragment has a different set of gestures so must register/unregister it's listeners from the sensor manager when it is opened/closed. Everything works fine until the watch goes into ambient mode. Once the app returns from ambient mode the sensors start to malfunction or stop working altogether. I suspect I may be handling the registering/unregistering incorrectly. Can anyone see where I might be going wrong?
I have a MainWearActivity class which extends WearableActivity and handles all the fragment transactions:
public class MainWearActivity extends WearableActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main_wear);
setAmbientEnabled();
// ... etc ...//
}
#Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
}
#Override
public void onUpdateAmbient() {
super.onUpdateAmbient();
}
#Override
public void onExitAmbient() {
super.onExitAmbient();
}
// Method the main fragment uses to replace itself with a new fragment
public void replaceFragment(Fragment frag, String fragTag) {
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.fragmentContainer, frag, fragTag);
mFragmentTransaction.addToBackStack(null);
mFragmentTransaction.commit();
}
}
I have a main fragment which presents a menu to the user and allows them to choose an option. When the user chooses an option, the main fragment is placed on the backstack and replaced by the option fragment. When the user returns from the option fragment, the backstack is popped to return to the main menu fragment:
public class MainFragment extends Fragment {
private MainWearActivity mMainWearActivity;
View view;
private SensorManager mSensorMgr;
private WearXFlick mXFlick; //Extends SensorEventListener
private Vibrator vibrator;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainWearActivity = (MainWearActivity) getActivity();
vibrator = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
mSensorMgr = (SensorManager) mMainWearActivity.getSystemService(Activity.SENSOR_SERVICE);
mXFlick = new WearXFlick();
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mSensorMgr.registerListener(mXFlick, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
mXFlick.setOnShakeListener(new OnShakeListener() {
#Override
public void onShake() {
vibrator.vibrate(Consts.vibPattern, -1);
// Select the current menu item
switch (mMainWearActivity.getCurrentSelection()) {
case Consts.MENU_MAIL:
MailFragment mf = new MailFragment();
mMainWearActivity.replaceFragment(mf, Consts.FRAG_MAIL);
break;
}
}
});
}
#Override
public void onStop() {
mSensorMgr.unregisterListener(mXFlick);
super.onStop();
}
#Override
public void onStart() {
super.onStart();
mSensorMgr.registerListener(mXFlick, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
#Override
public void onPause() {
mSensorMgr.unregisterListener(mXFlick);
super.onPause();
}
#Override
public void onResume() {
super.onResume();
mSensorMgr.registerListener(mXFlick, mSensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_GAME);
}
#Override
public void onDestroyView() {
mSensorMgr.unregisterListener(mXFlick);
super.onDestroyView();
}
}
Once replaceFragment() is called, a new fragment is loaded which basically has the same format as this, where a different set of sensor listeners are registered and unregistered on stop/start/pause/resume, although I really don't know if that's the correct way I should be unregistering/registering the sensor listeners. It all works fine, though, until the app goes into ambient mode and returns. When that happens, the sensors malfunction or fail.

Categories

Resources