PlaceId from Google Map, different from iOS and Android - android

I have apps which using google maps. iOS has GoogleMaps=6.2.1, android has:
implementation 'com.google.android.gms:play-services-maps:18.0.2'
implementation 'com.google.maps.android:android-maps-utils:2.2.3'
On both devices maps works good, but i faced with problem related with Point Of Interested id, and i cant find information why it happens.
So, for example, in iOS i have listener which return information about clicked place:
func mapView(_ mapView: GMSMapView, didTapPOIWithPlaceID placeID: String, name: String, location: CLLocationCoordinate2D) {
// placeID will be ZhDJA-k2Ym_pPkcFG1VfPvb99Vv, good ID
}
Example in Android, android has also listener, which return information about clicked place:
override fun onPoiClick(poi: PointOfInterest) {
// poi.placeId - will be like ZhDJAAAAAAAAAAA1VfPvb99Vv, bad ID
}
I clicked in the same place in iOS and Android, but android in some reason replace part of placeId to AAAAAAA.
but if in Android i will do additional request
placesClient.fetchPlace("ZhDJAAAAAAAAAAA1VfPvb99Vv", listOf(Place.Field.ID))
.addOnSuccessListener { response: FetchPlaceResponse ->
// response.place.id - now it ZhDJA-k2Ym_pPkcFG1VfPvb99Vv like in iOS without any additional requests
}
I will get normal placeID which in iOS i have without additional requests.
Why Google Map in Android and Google Map on iOS returns different placeID ?

Related

OPERATION_NOT_ALLOWED error when start navigation for transport mode RouteOptions.TransportMode.BICYCLE

I am integrating Here's premium SDK for Android to do a navigation test for a calculated route.
I have the following issue that I hope that somebody can help me. I configure the route itinerary from map and calculate routes fine but When I start navigation for this calculated route in this map the following error ocurre: NavigationManager.Error.OPERATION_NOT_ALLOWED
The code is the folowing:
override fun startNavigationForRouteInMap(
route: Route,
map: com.here.android.mpa.mapping.Map,
voiceSkinSelected: VoiceSkin?) {
navigationManager.apply {
setMap(map)
voiceGuidanceOptions.voiceSkin = voiceSkinSelected
/*
* Set the map update mode to ROADVIEW.This will enable the automatic map movement based on
* the current location.If user gestures are expected during the navigation, it's
* recommended to set the map update mode to NONE first. Other supported update mode can be
* found in HERE Android SDK API doc
*/
mapUpdateMode = NavigationManager.MapUpdateMode.ROADVIEW
addNavigationManagerEventListener(
WeakReference<NavigationManager.NavigationManagerEventListener>(
navigationManagerEventListener)
)
addPositionListener(
WeakReference<NavigationManager.PositionListener>(positionListener))
addManeuverEventListener(
WeakReference<NavigationManager.ManeuverEventListener>(routeManeuverEventListener))
}
val result = navigationManager.simulate(route, 60)
if(result == NavigationManager.Error.NONE)
navigationListener?.onNavigationStarted(route)
else {
Log.d("NAVIGATION", "Error name -> ${result.name}")
navigationListener?.onNavigationError()
}
Why ocurred this error? I have configured the correct api key and license key.
Thanks.
Navigation with BICYCLE is probably not enabled for your licensekey, you would need to get in touch with your HERE Sales Contact to have this enabled. If you don't have a Sales Contact, please use the Form available on HERE developer portal.

How to trigger in-app navigation based on API response

This question relates to both ios (swift) and android.
I'm working on building the backend implementation for a banner system that our mobile apps need to integrate with. Some of the banners need to redirect a user to a section of the app when pressed.
What is the best practice for triggering route navigation based on data returned in an API call?
For example, a list of banner objects in JSON where a key references the page to navigate to - would deep linking apply here, does it make sense for the apps to create a mapping of routes that I can reference by passing a string?
I feel like there has to be a simple solution here but the mobile team I'm working with seems pretty adamant.
In my current project (iOS), we are using deep links to map navigation to a certain tab of our app. So you could send it through JSON and then post a Notification, which your main controller is listening to (TabBarController for example), and then select the wanted index to go to, or any other navigation logic you need.
// Registering the deeplink with DeepLinkKit pod (https://github.com/button/DeepLinkKit)
self.router?.register("a/created/path") { link in
if let link = link {
debugPrint("Router: \(String(describing: link.url))")
NotificationCenter.default.post(
name: Notification.Name(Configuration.App.kGoToSomewhere),
object: nil
)
}
}
Or just extracted from your JSON and then setup the notification
call { URL in
NotificationCenter.default.post(
name: Notification.Name("ANotification"),
object: nil
)
}
And then in your main controller
class MainTabBarController: UITabBarController {
func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(selectTab),
name: Notification.Name("ANotificaton"),
object: nil
)
}
}
func selectTab() {
// Do your navigation logic here
}
I hope it helps!

Error : "Forbidden" when doing GeocodeRequest in Here-API for android

When doing a Geocoderequest in the Here API for Android I get the result FORBIDDEN for any search string.
Here is a snippet of the code (Kotlin) :
class GeoListner : ResultListener <MutableList<Location>>
{
override fun onCompleted(p0: MutableList<Location>?, p1: ErrorCode?) {
Log.d(this.javaClass.toString(),"Result code of search is ${p1?.name}")
}
}
fab_search.setOnClickListener { View ->
var currentPos = GeoCoordinate(49.2849,-123.1252)
val listner : ResultListener<MutableList<Location>> = GeoListner()
val request = GeocodeRequest("Granville").setSearchArea(currentPos,5000)
if (request.execute(listner) != ErrorCode.NONE)
{
}
}
This search area and string is picked from the HERE-API documentation for Here. Also i notice that the GeocodeRequest is deprecated, but the result for GeocodeRequest2 is the same error.
Anyone ?
Regards
Trond
Summary: Please ensure that you set the APP_ID and APP_CODE in the manifest file correctly.
For the background: Developers using HERE SDK with their app are required to register for a set of HERE credentials and to specify these credentials (App_Id and App_Code) in their app's Android manifest XML file. Failure to do so results in blocked access to certain features and degradation in the quality of other services.
To obtain these credentials visit the developer portal at https://developer.here.com/plans and register for a license. Once your project is created, you can generate these credentials on your Project Details page. If you already have a plan, you can also retrieve these credentials from your Project Details page.
Note: Credentials are unique to your account and your application's package namespace. Avoid reusing credentials across multiple applications.

Howto use org.chromium.identity for native google connect in Cordova

I would like use native google plus sign feature for connect my phonegap/cordova application (android et IOS).
Usually in Phonegap we use InAppBrowser for include web popup. It's done but suppose the user log with email and password with web UI. So in Android, we used google play for that and the same for IOS.
In january, it's now possible to use Chrome Apps inside Cordova.
http://blog.chromium.org/2014/01/run-chrome-apps-on-mobile-using-apache.html
Many cordova plugins are available and particulary chrome.identity : https://github.com/MobileChromeApps/mobile-chrome-apps/tree/master/chrome-cordova/plugins/chrome.identity
How to use this plugin outside the ChromeApps for native google signIn ?
I'm installed the plugins but none samples to access chrome object and Api.
Thanks for your help
This is an old-ish question but I thought I should post my solution since I hit this tonight... below is how I used the plugin to authenticate and call a service API. Apologies if it's not that efficient, it's been a long night :P (this is built for now on the Cordova starter template)
var app = {
onDeviceReady: function() {
/*********************
* I attached an EventListener to a link so I kept this binding
* Helps when testing to have a link handy to revoke the token
**********************/
app.receivedEvent('deviceready');
/****************************************************************************
* The documentation is a little odd here, but since this isn't
* a Chrome app, we need to set the Manifest JSON manually.
*
* The scopes are to only modify and read a calendar, not sure I need both
* but what the hell...
****************************************************************************/
chrome.runtime.setManifest({
oauth2: {
// ClientID obtained from the Developers Console
client_id: clientID,
scopes: [ 'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.readonly' ]
}
},function(){
// callback for setMainfest, empty..
});
/***********************************************************************
* Because I don't have Google Play Services setup yet I have to use
* the 'interactive' mode which will prompt the user to select the account,
* then show a permission screen.
*
* I have multiple (Google) accounts on my phone so I set the 'accountHint'
* to try to force authenticating my primary account and avoid having to deal
* with a popup.
******************************************************************************/
// Just checking if I already have grabbed it, if so, no need to do it again
if(!bToken){
chrome.identity.getAuthToken(
{
'interactive': true,
'accountHint': ACCOUNT_EMAIL,
},
function(token, acct) {
// set a global variable or debug...
});
}
},
}
var calendar = {
list: function(token) {
// Simple AJAX call, passing the token through and dealing with the results...
// This function just pulls calendar info...
$.ajax({
type: "GET",
url: listURL,
data: encodeURI("access_token="+token),
cache: false,
success:function(result) {
// do something....
}
})
}
}
Hope this helps!

Create a link that opens the appropriate map app on any device, with directions to destination

I rather thought this would not be so hard to find out but appearantly it is not easy to find an awesome cross device article, like you'd expect.
I want to create a link which opens either the mobile device's browser and surf to google maps OR open a maps app (Apple Maps or Google Maps) and directly starting a route, i.e.: start at the current location, end at a given point (lat/long).
I can test on two devices (beside browserstack), an Android and an iPhone.
The following link works only on the Android:
Take me there!
Clicking this link in iPhone's Chrome, this weirdly opens Google Maps in desktop version with ads on the mobile app...
This one only works on iOS, opening Apple Maps asking me to enter a start location (i can pick "Current Location") and start the route = desired behavior. Clicking this link completely fails on Android:
Take me there!
Notice the maps:// protocol.
Is there an elegant cross device way of creating such a link? One link that works on all main mobiles?
Thanks
UPDATE: Solution found (kinda)
Here is what I've come up with. It's not quite what I imagined, though it's working.
var ua = navigator.userAgent.toLowerCase(),
plat = navigator.platform,
protocol = '',
a,
href;
$.browser.device = ua.match(/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera/i) ? ua.match(/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera/i)[0] : false;
if ($.browser.device) {
switch($.browser.device) {
case 'iphone':
case 'ipad':
case 'ipod':
function iOSversion() {
if (/iP(hone|od|ad)/.test(navigator.platform)) {
// supports iOS 2.0 and later: <http://bit. ly/TJjs1V>
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
}
var ver = iOSversion() || [0];
if (ver[0] >= 6) {
protocol = 'maps://';
}
else {
protocol = 'http://maps.google.com/maps';
}
break;
case 'android':
default:
protocol = 'http://maps.google.com/maps';
break;
}
a.attr('href', protocol + href)
the maps:// protocol is the url scheme for the apple maps app, which will only start working on ios 6 or higher. There are ways to test if gmaps is installed and then chose what to do with the url, but that was kind of too much for what I intended. So i just ended up creating a maps:// OR maps.google.com/ link, using the above parameters.
** UPDATE **
sadly, $.browser.device don't work since jquery 1.9
(source - http://api.jquery.com/jquery.browser )
I haven't worked much with phones, so I dont't know if this would work. But just from a html/javascript point of view, you could just open a different url depending on what the user's device is?
<a style="cursor: pointer;" onclick="myNavFunc()">Take me there!</a>
function myNavFunc(){
// If it's an iPhone..
if( (navigator.platform.indexOf("iPhone") != -1)
|| (navigator.platform.indexOf("iPod") != -1)
|| (navigator.platform.indexOf("iPad") != -1))
window.open("maps://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=[YOUR_LAT],[YOUR_LNG]");
else
window.open("https://www.google.com/maps/dir/?api=1&travelmode=driving&layer=traffic&destination=[YOUR_LAT],[YOUR_LNG]");
}
Interestingly, http://maps.apple.com links will open directly in Apple Maps on an iOS device, or redirect to Google Maps otherwise (which is then intercepted on an Android device), so you can craft a careful URL that will do the right thing in both cases using an "Apple Maps" URL like:
http://maps.apple.com/?daddr=1600+Amphitheatre+Pkwy,+Mountain+View+CA
Alternatively, you can use a Google Maps url directly (without the /maps URL component) to open directly in Google Maps on an Android device, or open in Google Maps' Mobile Web on an iOS device:
http://maps.google.com/?daddr=1+Infinite+Loop,+Cupertino+CA
just bumped in this question and found here all the answers
I took some of the codes above and made simple js function that works on
android and iphone (it supports almost every android and iphones).
function navigate(lat, lng) {
// If it's an iPhone..
if ((navigator.platform.indexOf("iPhone") !== -1) || (navigator.platform.indexOf("iPod") !== -1)) {
function iOSversion() {
if (/iP(hone|od|ad)/.test(navigator.platform)) {
// supports iOS 2.0 and later
var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)];
}
}
var ver = iOSversion() || [0];
var protocol = 'http://';
if (ver[0] >= 6) {
protocol = 'maps://';
}
window.location = protocol + 'maps.apple.com/maps?daddr=' + lat + ',' + lng + '&ll=';
}
else {
window.open('http://maps.google.com?daddr=' + lat + ',' + lng + '&ll=');
}
}
The html:
<a onclick="navigate(31.046051,34.85161199999993)" >Israel</a>
This works for me on all devices [ iOS, Android and Window Mobile 8.1 ].
Does not look like the best way by any means... but cannot be more simpler :)
<a href="bingmaps:?cp=18.551464~73.951399">
<a href="http://maps.apple.com/maps?q=18.551464, 73.951399">
Open Maps
</a>
</a>
http://jsbin.com/dibeq
if (navigator.geolocation) { //Checks if browser supports geolocation
navigator.geolocation.getCurrentPosition(function (position) {
var latitude = position.coords.latitude; //users current
var longitude = position.coords.longitude; //location
var coords = new google.maps.LatLng(latitude, longitude); //Creates variable for map coordinates
var directionsService = new google.maps.DirectionsService();
var directionsDisplay = new google.maps.DirectionsRenderer();
var mapOptions = //Sets map options
{
zoom: 15, //Sets zoom level (0-21)
center: coords, //zoom in on users location
mapTypeControl: true, //allows you to select map type eg. map or satellite
navigationControlOptions:
{
style: google.maps.NavigationControlStyle.SMALL //sets map controls size eg. zoom
},
mapTypeId: google.maps.MapTypeId.ROADMAP //sets type of map Options:ROADMAP, SATELLITE, HYBRID, TERRIAN
};
map = new google.maps.Map( /*creates Map variable*/ document.getElementById("map"), mapOptions /*Creates a new map using the passed optional parameters in the mapOptions parameter.*/);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('panel'));
var request = {
origin: coords,
destination: 'BT42 1FL',
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
});
}
Well no, from an iOS developer prospective, there are two links that I know of that will open the Maps app on the iPhone
On iOS 5 and lower: http://maps.apple.com?q=xxxx
On iOS 6 and up: http://maps.google.com?q=xxxx
And that's only on Safari. Chrome will direct you to Google Maps webpage.
Other than that you'll need to use a URL scheme that basically beats the purpose because no android will know that protocol.
You might want to know, Why Safari opens the Maps app and Chrome directs me to a webpage?
Well, because safari is the build in browser made by apple and can detect the URL above. Chrome is "just another app" and must comply to the iOS Ecosystem. Therefor the only way for it to communicate with other apps is by using URL schemes.
Simple URL :
https://www.google.com/maps/dir/?api=1&destination=[LAT],[LNG]
This url is specific for routing.
Reference
I found that this works across the board:
<a href="https://www.google.com/maps/place/1+Fake+Street,+City+Province/State>Get Directions</a>
For desktops/laptops the user has to click Directions when that map loads, but from my testing all mobile devices will load that link in the Google Maps app without difficulty.
Based on the documentation the origin parameter is optional and it defaults to the user's location.
... Defaults to most relevant starting location, such as user location, if available. If none, the resulting map may provide a blank form to allow a user to enter the origin....
ex: https://www.google.com/maps/dir/?api=1&destination=Pike+Place+Market+Seattle+WA&travelmode=bicycling
For me this works on Desktop, IOS and Android.
The URL syntax is the same regardless of the platform in use
String url = "https://www.google.com/maps/search/?api=1&query=" + latitude + ","+
longitude;
In Android or iOS the URL launches Google Maps in the Maps app, If the Google Maps app is not installed, the URL launches Google Maps in a browser and performs the requested action.
On any other device, the URL launches Google Maps in a browser and performs the requested action.
here's the link for official documentation
https://developers.google.com/maps/documentation/urls/guide

Categories

Resources