Using MapBox to start Navigation UI causes unexpected crash - java

I am attempting to implement a navigation component to my application following this MapBox guide:
https://docs.mapbox.com/help/tutorials/android-navigation-sdk/
When I attempt to call .startNavigation(...) I get an unexpected error:
2020-03-08 19:51:45.786 11394-11394/com.example.mapboxnav A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8 in tid 11394 (mple.mapboxnav), pid 11394 (mple.mapboxnav)
Since the application I'm creating features many buttons, I've implemented View.OnClickListener and am calling the Navigation interface when a user presses the navigation button (R.id.startNav). However, as soon as a user presses the button the application crashes.
The currentRoute is working and shown on the map upon calling getRoute, like the example. I have verified that currentRoute is definitely not null. I have also attempted to start navigation with different coordinates without any luck.
currentRoute contains a route from the user's current/last known location to a specified destination. For reference, the line is set/generated with the following method:
public void initLine(Double lng, Double lat) {
Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();
Point origin = Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
Point destination = Point.fromLngLat(lng, lat);
getRoute(origin, destination);
}
onClick:
public void onClick(View v) {
switch (v.getId()) {
...
case R.id.startNav:
boolean simulateRoute = true;
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.build();
NavigationLauncher.startNavigation(MainActivity.this, options); // Causes Crash
}
}

I spend two and a half days over this until I discovered that the problem is that we need to set the location Engine before calling :
NavigationLauncher.startNavigation(MainActivity.this, options);
so your code should look like this and it should work:
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.build();
// Just add these three lines
MapboxNavigation navigation = new MapboxNavigation(DriveActivity.this, getString(R.string. mapbox_access_token));
navigation.setLocationEngine(locationEngine); mapboxMap.getLocationComponent().setLocationComponentEnabled(true);
NavigationLauncher.startNavigation(MainActivity.this, options);
Let me know how it goes
Criss

Hmm, very strange. I still feel like there's gotta be more info buried in the logcat. Maybe well above the Fatal signal 11 line? Maybe, just maybe, it's related to Location lastKnownLocation = mapboxMap.getLocationComponent().getLastKnownLocation();. Add a null check for lastKnownLocation and put
Point origin = Point.fromLngLat(lastKnownLocation.getLongitude(), lastKnownLocation.getLatitude());
Point destination = Point.fromLngLat(lng, lat);
getRoute(origin, destination);
inside of the null check block?
Maybe you're using the wrong classes? Look at the Nav SDK's NavigationLauncher test app activity: https://github.com/mapbox/mapbox-navigation-android/blob/master/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java#L342-L347. It's using NavigationLauncherOptions.Builder, whereas you aren't.
https://github.com/mapbox/mapbox-navigation-android/blob/master/app/src/main/java/com/mapbox/services/android/navigation/testapp/activity/navigationui/NavigationLauncherActivity.java#L365

A SIGSEGV error is thrown when you attempt to access memory incorrectly or are accessing a piece of memory that is not allotted for your use. See What causes a SIGSEGV for more information on this.
The fact that the error occurs on the line below,
NavigationLauncher.startNavigation(MainActivity.this, options);
leads me to believe that NavigationLauncherOptions options is not being assigned correctly and is possibly NULL causing you to derefrence a null pointer.
I know this isn't a perfect answer and doesn't really provide a solution to your problem, but I hope it helps bring you closer to finding an answer.
Here are some links that may help(including documentation):
https://github.com/mapbox/mapbox-navigation-android/issues/1529
https://docs.mapbox.com/android/navigation/overview/

Related

How to fix crash handling in android 10

I have a Unity Scene built with Cardboard SDK and exported as a library for Android. The library is used to play videos in cardboard mode on the android app. it's not the whole app, but a part in it. The rest of the android app is built with Kotlin and Java.
I have implemented that and all the functions work as expected, but, exiting the scene crashes the android.
We tried various ways to clear player prefs and even clear memory before closing the scene. But on android it always crashes. I have two android phones with android 9 and 10 for testing.
In the android app, I have made it such that as soon as the app crashes, I try to recover. My crash is that some lateinit var variables are destroyed. Their value becomes null and recovering the previous activity crashes it. So right after I exit the unity scene, I load the dereferenced variables back into memory and everything works again.
Note: I have tried using Application.Quit(); in unity, but it just closes the whole app. On the other hand, I only want to close the running scene
In unity [I call a function goBack in android part to close the app]:
public void GoToHome()
{
Pause();
Stop();
Resources.UnloadUnusedAssets();
PlayerPrefs.DeleteAll();
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("goBack");
}
In App:
public void goBack()
{
UnityPlayer.currentActivity.finish();
finish();
loadDerereferencedVars();
}
This goes perfectly on android 9. On the other phone with android 10, after I close the scene, the app continues to function, but, there comes a message
When I click close app, the app continues to work.
I have checked the logs and there is a null pointer dereference cause for the crash in Unity Main >...
If you'd like to see the Unity Crash Log from LogCat in Android Studio
So, since the app is still running, I thought, it would be better to just hide the crash report and just let the user not know about this crash, but still report it.
I tried enclosing my app in Application and added a method to catch uncaughtException.
here is my application class:
public class MyApp extends Application {
private static final String TAG = "MyAPP";
#Override
public void onCreate() {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException (Thread thread, Throwable e) {
handleUncaughtException (thread, e);
}
});
}
/**
* Handles Uncaught Exceptions
*/
private void handleUncaughtException (Thread thread, Throwable e) {
// The following shows what I'd like, though it won't work like this.
Toast.makeText(getApplicationContext(), "Looks like I am having a bad day!", Toast.LENGTH_LONG).show();
Log.e("UncaughtException", "I found an exception!");
// Add some code logic if needed based on your requirement
}
}
Again, this works perfectly in Android 9 and I also got the error reported. However in the phone with android 10, I just get the crash report like the image above and no error is reported.
I want to know why the crash handling is not working and how can I fix it?
I would not finish the Activity you came from, instead just open a new intent (on UnityActivity). When you end this intent the app will come back to the last active Activity.
I will give you my script as an example:
public void sendJobToUnity(String fileName, boolean isNewJob){
//creates a new job. It exists inside the JobSelector Activity
isUnityLoaded = true;
//this is what you are looking for part1
Intent i = new Intent(JobSelector.this, MainUnityActivity.class); //same as (CurrentActivity.this, UnityActivity.this)
//those are how I send some data across the app. just ignore it
//i.putExtra("jobName", fileName);
//i.putExtra("isNewJob",isNewJob);
//i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(i, 1); //this is what you are looking for part2
}
For closing it, in the MainUnityActivity Activity I have an override that Unity sends to Android in order to Unload the activity (not quit it completely cause you cannot load it again if you do it) like this:
#Override
protected void receiveJobAndUnloadUnity(String data){
saveCurrentJob(data); //saves the job it receives from Unity
mUnityPlayer.unload(); //this is what you are looking for part3
}
If you want to unload Unity from android you can put "mUnityPlayer.unload();" wherever you want, provided you have started the Activity the way I've shown you.
Note that "mUnityPlayer" is a default Unity variable and cannot be renamed

Android Studio show me the Error load: id=gralloc != hmi->id=gralloc

My IDE shows me the error even is empty project. As you can see I create the new project with empty activity. App is launched in mobile successfully and work fine. but logcat isn't working properly or any thing else I'm stuck help me out. And when I connect my mobile even I didn't build the project logcat is full of instruction/logs.
UPDATE:
First, gralloc stands for the low-level graphics buffer allocator.
The gralloc is part of the HAL (Hardware Abstraction Layer) which
means that the implementation is platform-specific. You can find the
interface definitions in
hardware/libhardware/include/hardware/gralloc.h. As expected from a
HAL component, the interface is divided into a module interface
(gralloc_module_t) and a device interface (alloc_device_t).
The error is very low level and related with OpenGLRenderer. Your device is trying to open some 64-bit library files, but if fails. Then the error occurs.
I did very deep search about this but nothing useful came up.
Try running apps on another devices and see the error occurs again.
Continue developing if the error is not causing crash or other important issue. If you find a solution, you will try again.
in my case, I tried to use Application class static context for calling new Activity and I changed it to local static Activity and problem solved.
Notice that this problem doesn't happen in all devices it just occur in some cases.
private static MainActivity u_static;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_users);
u_static = this;
}
public static void new(int id, String name){
Intent i = new Intent(u_static, NewActivity.class);
u_static.startActivity(i);
}
And something I notice that in some devices when an application stops working instead of showing error, this error happens. Trace and debug your codes.
About the crazy E/HAL: load: id=gralloc != hmi->id=gralloc
Reason for error: Generally, it is caused by the fact that the control object is not fetched, the click event of the control is executed, and the null value is related to the initialization control.
As
private Button bt;
bt.setOnclickListener(new OnClickLisenter(){....});
Is there a problem? Yes!
xml layout control
Check if the findViewById() is missing in the java code!
    The above leaked bt = (Button) findViewById(R.id...);
java dynamic new control / custom control error
     Check if you forgot to create the object!
     The above leaked bt = new Button();
So the correct way to change the above code is:
private Button bt;
bt=(Button)findViewById(R.id...);
I encountered this issue while using runnable and passing an unassigned view.
This is caused by an empty view object where findViewById returns a null value.
Instead of passing the view object passing the value the view holds resolved the issue.

Citymaps questions on Android studio

I have some new questions in today's citymaps development.
In the Android studio,if I develop the code for citymap, there are always no logs showing but for others that does not happen. Why?
According to the citymaps official website, to create a map instance with CitymapsMapFragment, but in the sample project which citymaps provides, it uses SupportCitymapsMpaFragment ,What is the difference between them?
When the map is loading complete, is it automatically positioning to the current position or some other default position? Where is it?
If I open the GPS location,I can locate to the current position and show a blue arrow quickly, but too much power consumption,are there any other location way like network or base station location?
Code follows:
CitymapsMapFragment fragment = (CitymapsMapFragment)fragmentManager.findFragmentById(R.id.map);
if (fragment != null) {
fragment.setMapViewListener(this);
}
I did not find the fragment have the method setMapViewListener but setMapViewReadyListener,does it right?
Other code:
CitymapsMapView mapView = new CitymapsMapView(this, options, this);
When I add animate in additional methods like this:
mapView.setMapPosition(position, 300, new MapViewAnimationListener() {
#Override
public void onAnimationEnd(boolean completed) {
Log.d("SomeApp", "Move Complete!");
}
});
the project fails and exits,I tried to surround the code with try-catch block to catch exception for purpose, but nothing shows in logcat view. Why?
I am developer on the Citymaps project. I will do my best to answer all your questions
1) If you are not receiving log statements, this is likely an issue with your own application, IDE, or device configuration. In our own application, which uses the Citymaps SDK, we have no issues with logging.
2) Prior to using the Citymaps SDK, it is highly advisable that you familiarize yourself with fragments, but the short version is that SupportCitymapsMapFragment extends from the Fragment class in the v4 support library.
3) It is up to you to set the default position the map.
4) If you create a class which implements from the LocationSource interface, and then call mapView.setLocationSource, you can modify the behaviors of the map's location services. For an example, have a look at CitymapsLocationSource.java, which is the default implementation for this interface used by the SDK.
As for the exception you are having, you have not provided nearly enough information. Please show a stack trace, and I may be able to help.
Thank you for using our SDK, feel free to post again with any more questions.

Robotium - Trying to click home button in app

I'm new to robotium and i'm trying to write a quick and dirty script to run through all screens in an app.
The problem i have mainly with the 'home button' in the app. I've tried lots of options but i cant seem to get it to click there except with index, which is not what i want.
When i check out the button with the hierarchyviewer it looks like this:
Link
However when i try for example:
assertTrue(
"Wait for text (id: myapp.R.id.home) failed.",
solo.waitForImageById("myapp.R.id.home", 20000));
solo.clickOnImage((ImageView) solo.findViewById("myapp.R.id.home"));
solo.waitForActivity("MenuActivity");
It fails at the waitForImageByID line. Ive tried multiple options like waitForImageButton etc, but i just cant seem to get it clicked. What am i missing here?
junit.framework.AssertionFailedError: View with id: '0' is not found!
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1990)
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1970)
at com.bitbar.recorder.extensions.OtherUtils.a(OtherUtils.java:246)
at com.bitbar.recorder.extensions.OtherUtils.b(OtherUtils.java:241)
at com.bitbar.recorder.extensions.v.a(Waiter.java:71)
at com.bitbar.recorder.extensions.ExtSolo.waitForImageButtonById(ExtSolo.java:4176)
at com.example.android.apis.test.Test.testRecorded(Test.java:137)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1740)
Use the following line to press the home button in the action bar
solo.clickOnActionBarHomeButton();
The issue is that the id that it is referring is not in your application, it is in androids default R file, try android.R.id.home and it should work fine. It is worth noting though that if your application uses action bar sherlock to support the action bar pre 4.0 that this will have a different ID there and you will have to handle this in your test.
You can see this for yourself looking at: http://developer.android.com/reference/android/R.id.html
When you are using ActionBarSherlock there are two different Ids you have to check, android.R.id.home for API-Level>11 and abs__home for lower levels (provided by ActionBarSherlock):
View homeButton = activity.findViewById(android.R.id.home);
if (homeButton == null) {
homeButton = activity.findViewById(R.id.abs__home);
}
What about this code:
ArrayList<LinearLayout> ll = solo.getCurrentViews(LinearLayout.class);
//You can change 1 with the ordinal number of LinearLayout you want to click.
solo.clickOnView(ll.get(1));
or also
ArrayList<ImageView> iv = solo.getCurrentViews(ImageView.class);
//You can change 0 with the ordinal number of Image you want to click.
solo.clickOnView(iv.get(0));
I think if you identify the correct id for view or linear layout or image view it should work.
Dave C's answer was working only partially for me. The button was clicked but before the preceding screen was loaded assertions had started and thus were always false. The solution is to run "home click" on the main thread (Robotium 5.2.1):
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
solo.clickOnActionBarHomeButton();
}
});
From your question I can see that it is an image view. You can click on any view using the following piece of code.
View view = solo.getView("View_name_from_hierachy_viewer");
solo.clickOnView(view);
View_name_from_hierachy_viewer in your case will be "home".
Let me know if this does not work.

Getting Coordinates From Button Press Not Working

I am pretty new to Android Development, and I've tried to make a method in my Android Application, where you press the button and get coordinates (Longitude and Latitude). But the program stops working on the emulator when I press the button.
I am probably just doing something wrong here. Looking through the Callstack didn't help me. It was simply too cluttered with...a lot of useless information.
How do I fix this?
public void onLocateByGMapButtonClick() {
LocationManager mloc = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = mloc.getAllProviders();
Location loc = new Location(providers.get(0));
double loTude = loc.getLongitude();
double laTude = loc.getLatitude();
String newCoords = loTude + "," + laTude;
location.setText(newCoords);
Toast.makeText(this.getBaseContext(),"Location have been updated!",5);
}
The reason you application is crashing is probably because you are receiving a null pointer exception.
You have to understand that a GPS fix is not an immediate process, it might take time and in this time you don't have a location to work on unless you use the getLaskKnownLocation method (which maybe return null as well).
So what you need to to is or use:
Location loc = lm.getLastKnownLocation(provider);
or implement a LocationListener that will fire as soon as a new location update arrives.
Tutorial: http://www.vogella.com/articles/AndroidLocationAPI/article.html

Categories