HERE Android SDK Turn by turn instruction - android

I am using HERE Android SDK to perform turn by turn navigation project. But I do not get the result similar to image.
I hava this code to get the current manauver
private NavigationManager.NewInstructionEventListener newInstructionEventListener = new NavigationManager.NewInstructionEventListener() {
#Override
public void onNewInstructionEvent() {
Maneuver maneuver = navigationManager.getNextManeuver();
if (maneuver != null) {
if (maneuver.getAction() == Maneuver.Action.END) {
}
tvManeuver.setText(navigationManager.getNextManeuver().getTurn().name() + " " + maneuver.getIcon().value());
ivTitle.setImageBitmap(maneuver.getNextRoadImage().getBitmap());
tvStreet.setText(maneuver.getRoadName());
tvMeters.setText("durante " + maneuver.getDistanceFromPreviousManeuver() + " m");
if (maneuver.getDistanceToNextManeuver() == 0) {
tvMeters.setVisibility(View.GONE);
} else {
tvMeters.setVisibility(View.VISIBLE);
}
}
}
};
But I do not get the correct text of the maneuver. For example "Turn right at the next corner" and the and the corresponding arrow icon to put inside IMAGEVIEW.
can anybody help me?
Regards.

I assume the image you provided is from HERE Maps available on Google Store which is a custom implementation using the HERE SDK.
The instruction you can get from Maneuver , check documentation
https://developer.here.com/mobile-sdks/documentation/android-hybrid-plus/topics_api_nlp_hybrid_plus/com-here-android-mpa-routing-maneuver.html#topic-apiref__getinstruction-void
Icon should also be retrieved from getIcon() , which gives an enumeration and you will need to create images for possible enumerations in the icon , check documentation
https://developer.here.com/mobile-sdks/documentation/android-hybrid-plus/topics_api_nlp_hybrid_plus/com-here-android-mpa-routing-maneuver-icon.html#topic-apiref

If you want to get the list of maneuvers, you can't get it on the NewInstructionEvent.
Since you are already in navigation you should already have your route object. On the route object you can just call getManeuvers(). That will give you all the list of maneuvers for the current route.
You can also refer to their UI Kit https://developer.here.com/blog/build-beautiful-interfaces-with-the-here-mobile-sdk-ui-kit-for-android-and-ios.
Hope this helps. I know this is an older thread.

HERE SDK Premium does not provide Maneuver Instructions pre- start of Navigation nor can you get a list of Maneuver Instructions at any point.
You however could get a list of Maneuver Instructions using the HERE Routing API.
https://developer.here.com/documentation/routing-api/dev_guide/topics/use-cases/actions.html
One more way is to get Instructions through the AudioPlayerDelegate.PlayText callback.

Related

How to open Android Outlook application from an external one

I'm currently developing an Android application in order to display home screen widgets. Those ones are related to Microsoft Outlook (Events + Messages) in order to show incoming events and unread new messages in a kind of dynamic tiles.
The Msal graph library helps me a lot to authenticate and retrieve in formations which contains an identifier for each event / message results
But now I want to know if the outlook application is installed on the user device and if there is a way to open Outlook when the user click on the widget. Moreover if the user can open the corresponding clicked event or message with the identifier.
For example the Event widget currently displaying a birthday event. The user click on it. Then it opens Outlook and display directly that birthday event.
Regards
I don't think this is officially documented somewhere. But here's what you can do to find out about it.
You can list all Microsoft applications installed on your device...
val packages = context.packageManager
.getInstalledApplications(PackageManager.GET_META_DATA)
for (info in packages) {
if(info.packageName.startsWith("com.microsoft", true)){
Log.d("package name:" + info.packageName)
Log.d("Launch Activity: " + context.packageManager.getLaunchIntentForPackage(info.packageName))
}
}
Take a note of the "launch intent" displayed in the LogCat. You can use that to launch Outlook. Just make sure you don't hard-code those values because Microsoft can change those values at any point, for example the activity class can change. So, instead of doing this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
setPackage("com.microsoft.office.outlook")
component = ComponentName("com.microsoft.office.outlook", "com.microsoft.office.outlook.MainActivity")
}
)
Do this...
context.startActivity(
Intent().apply {
action = Intent.ACTION_MAIN
addCategory(Intent.CATEGORY_LAUNCHER)
component = ComponentName(
outlookLaunchIntent?.component?.packageName,
outlookLaunchIntent?.component?.className
)
setPackage(outlookLaunchIntent.package)
}
)
Also, remember that getLaunchIntentForPackage and component can return null, so make sure you check for null values properly
I am relaying a suggestion from a couple of internal folks:
Please try to open the event using one of the following URLs:
ms-outlook://events/open?restid=%s&account=test#om.com (if you have a regular REST id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (if you are using an immutable id)
Since immutable IDs are still in preview stage in Microsoft Graph, and customers should not use preview APIs in their production apps, I think option #1 applies to your case.
Please reply here if the URL works, or not, and if you have other related questions. I requested the couple of folks to keep an eye on this thread as well.
Well, i managed to open the outlook android application with the help of your code #Leo. As im not developping with Kotlin, ill post the JAVA code below :
Intent outlookLaunchIntent = context.getPackageManager().getLaunchIntentForPackage("com.microsoft.office.outlook");
if (outlookLaunchIntent != null) {
context.startActivity(outlookLaunchIntent );
}
Below code to open event/message in a web browser provided by webLink property of the graph API. (I only test for event and the url provided not working. Ill post a new issue on StackOverFlow for that but you already see the issue over there : https://github.com/microsoftgraph/microsoft-graph-docs/issues/4203
try {
Intent webIntent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(calendarWebLink));
webIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(webIntent);
} catch (RuntimeException e) {
// The url is invalid, maybe missing http://
e.printStackTrace();
}
However im still stuck on the decicive goal of my widget item click which is to open the relative event/email in the Microsoft Outlook Android application.
Microsoft Outlook Android app contains widgets which can achieve what im looking for. So i wonder if it is possible to list its broadcast receivers.
The best thing i found is an old manifest for that app but it doesnt help me.
https://gist.github.com/RyPope/df0e61f477af4b73865cd72bdaa7d8c2
Hi may you try to open the event using one of the url:
ms-outlook://events/open?restid=%s&account=test#om.com (If the
user is having rest id)
ms-outlook://events/open?immutableid=%s&account=test#om.com (If
the user is having immutable id)

How do I make a list of nearby places in a static location, not current location?

I'm not sure if this has been answered. This feels like such a basic question but I've been looking for a way to do this and all the examples I came across showed a list of places near the device. What I'm trying to do is to specify a location via button click, then show the places near it.
Specifically, if the user clicks button 1, this means the user wants to see the places near train station A, probably in another activity with a RecyclerView.
I was using http://www.zoftino.com/current-location-and-nearby-places-android-example for reference. I followed it all the way to adding the API key in the manifest file but I got stuck trying to analyze how I'm supposed to define a specific location instead of getting the device's location.
I'm not sure if I'm approaching this correctly but so far, I've made a Java bean that can get which station was selected...
public class Station {
String station;
public Station (String station) {
this.station = station;
}
public Station () {
}
public String getStation() {
return station;
}
public void setStation(String station) {
this.station = station;
}
I also have an activity with an onClick method to check which button was clicked...
public void onClick (View v) {
switch (v.getId()) {
case R.id.img1: station = getString(R.string.StationName1);
Log.d("project", "selected station is " + station);
break;
//other cases deleted to make this more concise
}
Station selected = new Station (station);
Log.d("project", "content of station bean is " + selected.getStation());
}
I'm testing this using a phone running Android 7.1.1. From the logcat, I know that the Station bean is able to get the selected station correctly. I honestly don't know why I decided to use getString(R.string.StationName1) but considering I'm doing this for 4 train lines and I'm already past the project's deadline. I'd rather not have to change them, if possible.
I was thinking of adding some sort of "coordinates" attribute to the Java bean and passing the exact coordinates using the switch case above but even if I did that, I still wouldn't know how to use it so I can show the nearby locations.
Edit: I'm using Android Studio 3.2.1
The linked tutorial has the following code block where places are being detected and displayed:
#SuppressLint("MissingPermission")
private void getCurrentPlaceData() {
Task<PlaceLikelihoodBufferResponse> placeResult = placeDetectionClient.
getCurrentPlace(null);
placeResult.addOnCompleteListener(new OnCompleteListener<PlaceLikelihoodBufferResponse>() {
#Override
public void onComplete(#NonNull Task<PlaceLikelihoodBufferResponse> task) {
Log.d(TAG, "current location places info");
List<Place> placesList = new ArrayList<Place>();
PlaceLikelihoodBufferResponse likelyPlaces = task.getResult();
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
placesList.add(placeLikelihood.getPlace().freeze());
}
likelyPlaces.release();
PlacesRecyclerViewAdapter recyclerViewAdapter = new
PlacesRecyclerViewAdapter(placesList,
CurrentLocationNearByPlacesActivity.this);
recyclerView.setAdapter(recyclerViewAdapter);
}
});
}
Here, the getCurrentPlace method uses the current device location, which is the likely cause of your issue. In fact, the Place Detection Client documentation itself notes that: (emphasis mine)
The Place Detection API provides quick access to the device's current place, and offers the opportunity to report the location of the device at a particular place (like a check in).
Like you said, there doesn't seem to be any API in the Android Places SDK that offers a 'Nearby Places' functionality for a location. Even the above is attempting to associate the current user location with a known place (as opposed to a set of coordinates with no extra info), and doesn't seem to be meant to search for nearby places by design (though it can clearly be done).
However, the Place Search API can be used for your requirements (I have used it in an app that does something similar to what you are looking to do). It includes an endpoint for Nearby Search Requests, where a static location can be passed. The only downside is that you will have to handle the HTTP calls through Retrofit or something similar, since the SDK doesn't have an existing framework for this API.

How to detect I'm near a waypoint

I want to make a navigation application on Android (Kotlin) using the mapbox-android SDK. I need to create a route with specific waypoints and want to know when I am near one of those waypoints (200m before for example). I already managed to display a map with my waypoints with the NavigationRoute object and launch a turn-by-turn navigation using the NavigationLauncher object. Still, I don't have a clue how to know when I'm getting near a waypoint. I've read things about milestones event listener (step or route), RouteProgress (leg or route), but I don't know if it's the right approach to do this.
I tried to declare a milestone with a STEP_DISTANCE_REMAINING_METERS and add a MilestoneEventListener but nothing fire up in my logs. Like I said, I don't even know if it's the right way to do this.
val milestone = RouteMilestone.Builder()
.setIdentifier(100)
.setTrigger(Trigger.all(
Trigger.lt(TriggerProperty.STEP_DISTANCE_REMAINING_METERS, 200)
))
.build()
navigation = MapboxNavigation(this#MainActivity, Mapbox.getAccessToken())
navigation.addMilestone(milestone)
navigation.addMilestoneEventListener { _, _, milestone ->
Log.d(TAG, "milestone triggered: " + milestone.instruction)
}
navigationMapRoute = NavigationMapRoute(navigation, mapView, map, R.style.NavigationMapRoute)
navigationMapRoute!!.addRoute(currentRoute)
I'm using those versions of mapbox SDK
mapbox-android-sdk:5.3.2
mapbox-android-navigation:0.9.0
mapbox-android-navigation-ui:0.9.0
If you know the location of your waypoints you could just use Location Manager's Proximity Alert

Google Keep list note from inside your app

In my app, I am writing a functionality to share a shopping list to Google Keep. For this, I use the Intent.ACTION_SEND action and set the package to the one of Google Keep.
Everything works great, but I am wondering if it is possible to add an EXTRA parameter to the Intent telling Google Keep it must be displayed as a list with checkboxes, like it is possible to add extra event-specific extra's when creating a Calendar Event. Now, it is displayed as plain text.
Here is my code:
try {
Intent keepIntent = new Intent(Intent.ACTION_SEND);
keepIntent.setType("text/plain");
keepIntent.setPackage("com.google.android.keep");
keepIntent.putExtra(Intent.EXTRA_SUBJECT, "Shopping List " + recipe.getName());
keepIntent.putExtra(Intent.EXTRA_TEXT, "Flower\nyeast\nbutter\nalmonds");
startActivity(keepIntent);
} catch (Exception e) {
Dialogs.toastShort(this, "Google Keep is not installed on your device");
}
Now, I get this as result:
What, I want to get is this as result - without that the user has to select "show checkboxes" in the actionbar:
Thanks for your help.
Unfortunately, it's not possible. Google has not published an API for public nor 3rd party use. If you check out the http traffic you can see the underlying API but there's no real way to replicate it. Sorry

Baidu maps on Android: access key does not work for location searching

I'm creating an Android app for a chinese client and they need map integration, so Google maps is not an option since all Google services are blocked in China. I'm trying to use Baidu maps, which is called Baidu LBS (location-based services) cloud.
Getting a basic map with no overlays to work was relatively easy. The process is described here (in Chinese, but the code speaks for itself if you don't understand the language). Downloading the latest Baidu Android SDK (v3.2.0 at time of writing) and integrating it into my Eclipse project as a library was no problem, but don't trust the documentation in that link too much even though it is the official one. Their examples often contain code that wouldn't even compile. The name of the .jar file for example was completely different from what you see in their screenshot.
Oh and also their .jar library is obfuscated which is super annoying to work with :-(
I needed to register a Baidu account and go to their control center to generate a key. To create an access key ("ak") for mobile you need to enter the SHA1 fingerprint of the keystore which signs your app, followed by the package name specified in your manifest.
Then I added the generated key to my manifest under the tag
<meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="xxx...xxx" />
I then copied code from their sample project's CloudSearchActivity because I have specific coordinates that I would like to display. I implemented the CloudListener interface as shown:
#Override
public void onGetSearchResult(final CloudSearchResult result, final int error)
{
Log.w("onGetSearchResult", "status=" + result.status + ". size=" + result.size + ". total=" + result.total + ". error=" + error);
if(null != result && null != result.poiList && 0 < result.poiList.size())
{
mBaiduMap.clear();
final BitmapDescriptor bitmapDescriptor=BitmapDescriptorFactory.fromResource(R.drawable.icon_address_grey);
LatLng latitudeLongitude;
LatLngBounds.Builder builder=new Builder();
for(final CloudPoiInfo info : result.poiList)
{
latitudeLongitude=new LatLng(info.latitude, info.longitude);
final OverlayOptions overlayOptions=new MarkerOptions().icon(bitmapDescriptor).position(latitudeLongitude);
mBaiduMap.addOverlay(overlayOptions);
builder.include(latitudeLongitude);
}
final LatLngBounds bounds=builder.build();
MapStatusUpdate mapStatusUpdate=MapStatusUpdateFactory.newLatLngBounds(bounds);
mBaiduMap.animateMapStatus(mapStatusUpdate);
}
}
And I added code to launch a query (also copied from their sample project):
#Override
public View onCreateView(final LayoutInflater layoutInflater, final ViewGroup viewGroup,
final Bundle savedInstanceState)
{
// initialize needs to be called
SDKInitializer.initialize(getApplication());
CloudManager.getInstance().init(MyFragment.this);
view=(ViewGroup)layoutInflater.inflate(R.layout.fragment_map, viewGroup, false);
mMapView=(MapView)view.findViewById(R.id.baiduMapView);
mBaiduMap=mMapView.getMap();
NearbySearchInfo info=new NearbySearchInfo();
info.ak="xxx...xxx";
info.geoTableId=12345;
info.tags="";
info.radius=30000;
info.location="116.403689,39.914957";
CloudManager.getInstance().nearbySearch(info);
return view;
}
Unfortunately I keep getting a status value of 102 from the server (according to this API page that means STATUS_CODE_SECURITY_CODE_ERROR. Now I don't know what to do.
Things that I don't understand:
Why do I need to repeat my access key ("ak") when building the query? Is it not enough to have it in the manifest once?
What is this "geoTableId" value in the query supposed to be?
Any ideas?
After many hours of research I have made some progress on the open questions.
The reason for the "ak" field in a cloud search query is not duplication, it is in fact a different access key. Somewhere in a hidden place Baidu says that access keys "for mobile" will not work for these cloud searches, you need an ak "for server". So the solution is to go back to the Baidu control center and create another key "for server". This key needs to be used in the query, while the "for mobile" key needs to remain in the manifest.
geoTableId is an identifier of your account, not unsimilar to the access keys. It is a (currently) 5 digit number that you need to obtain in the Baidu control center. The other keys were generated in the tab titled "API控制台" (API control desk), but for the geoTableId you need to switch to the tab called "数据管理" (data management). There I think I needed to press the "创建" (~create) button on top left, then enter a name, select "是" (yes) where they ask if this is for release (not sure about that translation) and then click "保存" (save). After this, your freshly generated number is displayed in the top field in parentheses behind the name you chose just now.
These steps have allowed me to send "successful" queries where the server answers with status 0 (STATUS_CODE_SUCCEED). However, so far all the answers I get are empty, I have yet to find a query which produces a non-empty answer. If anyone manages to do that, please let me know!

Categories

Resources