Android Google Maps Direction Api - Api key restriction not working - android

When we are setting a Key restriction to NONE for Google Maps Direction Api, It works fine.
But When we set Key restriction to Android apps and provide a proper Package name & SHA-1 certificate - It says Request Declined from Google Api response.
Any known solution to this?

Directions API is a web service. The restrictions that will work with an API keys for web services are IP restrictions.
It is supposed that web services requests are executed on your backend servers. If you need to restrict an API key, the workaround is to create an intermediate server. Your Android application should send requests to the intermediate server, intermediate server should send requests to Google and pass responses back to your app. In this case you can restrict an API key by IP address of your intermediate server.
Have a look at this document:
https://developers.google.com/maps/faq#using-google-maps-apis
Hope this clarifies your doubt.

You will usually have more than one certificate. One for debug and one for release.
Ensure that you add both fingerprints or that the certificate fingerprint you are using matches the one for the buildType you specified

Please try with
compile 'com.akexorcist:googledirectionlibrary:1.1.1'
flow the doc or try this method
And 2nd method Set CameraWithCoordinationBounds for animate Camera:
private void drawMap(double s_lat,double s_lng,double e_lat,double e_lng) {
GoogleDirectionConfiguration.getInstance().setLogEnabled(true);
Log.e("map", "++");
List<LatLng> waypoints = Arrays.asList(
new LatLng(22.626390800000003, 88.4313014), new LatLng(22.619708499999998, 88.4369083)
);
GoogleDirection.withServerKey("AIz... your google api key")
.from(new LatLng(s_lat, s_lng))
.and(waypoints)
.to(new LatLng(e_lat, e_lng))
.transportMode(TransportMode.DRIVING)
.execute(new DirectionCallback() {
#Override
public void onDirectionSuccess(Direction direction, String rawBody) {
if (direction.isOK()) {
mMap.setMinZoomPreference(8f);
com.akexorcist.googledirection.model.Route route = direction.getRouteList().get(0);
int legCount = route.getLegList().size();
for (int index = 0; index < legCount; index++) {
Log.e("map", "++++" + index);
Leg leg = route.getLegList().get(index);
// mMap.addMarker(new MarkerOptions().position(leg.getStartLocation().getCoordination()));
if (index == 0) {
Log.e("position","0" + leg.getStartLocation().getCoordination());
// mMap.addMarker(new MarkerOptions().position(leg.getEndLocation().getCoordination()).title("User"));
mMap.addMarker(new MarkerOptions().position(leg.getStartLocation().getCoordination()).icon(BitmapDescriptorFactory
.fromResource(R.drawable.start_pointer)));
} else if (index == legCount - 1) {
// mMap.addMarker(new MarkerOptions().position(leg.getEndLocation().getCoordination()).title("User"));
mMap.addMarker(new MarkerOptions().position(leg.getEndLocation().getCoordination()).icon(BitmapDescriptorFactory
.fromResource(R.drawable.stop_pointer)));
} else {
mMap.addMarker(new MarkerOptions().position(leg.getEndLocation().getCoordination()).icon(BitmapDescriptorFactory
.fromResource(R.drawable.user_point)));
}
List<Step> stepList = leg.getStepList();
ArrayList<PolylineOptions> polylineOptionList = DirectionConverter.createTransitPolyline(MainActivity.this, stepList, 5, Color.RED, 3, Color.BLUE);
for (PolylineOptions polylineOption : polylineOptionList) {
mMap.addPolyline(polylineOption);
}
}
setCameraWithCoordinationBounds(route); // animateCamera
}
}
#Override
public void onDirectionFailure(Throwable t) {
Log.e("error", t.getLocalizedMessage() + t.getMessage() + "");
// Do something
}
});
}
private void setCameraWithCoordinationBounds(com.akexorcist.googledirection.model.Route route) {
LatLng southwest = route.getBound().getSouthwestCoordination().getCoordination();
LatLng northeast = route.getBound().getNortheastCoordination().getCoordination();
LatLngBounds bounds = new LatLngBounds(southwest, northeast);
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
}

Related

Google Direction API cannot find my API Key

I am developing an android app where a customer requests a worker for pickuplocation, so i am using google direction library to show routes between the customer and worker but direction API keeps throwing error saying that you must use an API key to make requests to google cloud platform, already i have created a project in google cloud console and generated my key.
Here is what i have done;
First of all i started my project without a billing account, then in the process of my project i was required to create a billing account in order to make direction request so i linked my project what
What i did;
i added my API key to manifest
i have already enabled places API and direction API
in the direction part i am using google direction library, this one
i added it to app build-gradle
compile 'com.github.jd-alexander:library:1.1.0'
and here is a sample of code in my activity for direction request since i am using the above library i dont know whether it is because i created the project then billing account, what might be the problem?
Even places API does not function properly
private void getRouteToMarker(LatLng customerpickuplocation) {
Routing routing = new Routing.Builder()
.travelMode(AbstractRouting.TravelMode.DRIVING)
.withListener(this)
.alternativeRoutes(false)
.waypoints(new LatLng(lat, lng), customerpickuplocation)
.build();
routing.execute();
}
#Override
public void onRoutingFailure(RouteException e) {
if (e != null) {
Toast.makeText(this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Something went wrong, Try again", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onRoutingSuccess(ArrayList<Route> route, int shortestRouteIndex) {
if (polylines.size() > 0) {
for (Polyline poly : polylines) {
poly.remove();
}
}
polylines = new ArrayList<>();
//add route(s) to the map.
for (int i = 0; i < route.size(); i++) {
//In case of more than 5 alternative routes
int colorIndex = i % COLORS.length;
PolylineOptions polyOptions = new PolylineOptions();
polyOptions.color(getResources().getColor(COLORS[colorIndex]));
polyOptions.width(10 + i * 3);
polyOptions.addAll(route.get(i).getPoints());
Polyline polyline = mMap.addPolyline(polyOptions);
polylines.add(polyline);
Toast.makeText(getApplicationContext(), "Route " + (i + 1) + ": distance - " + route.get(i).getDistanceValue() + ": duration - " + route.get(i).getDurationValue(), Toast.LENGTH_SHORT).show();
}
}
i have come up with a solution but not a good security measure, by adding key to getRouteToMarker() method
private void getRouteToMarker(LatLng customerpickuplocation) {
Routing routing = new Routing.Builder()
.travelMode(AbstractRouting.TravelMode.DRIVING)
.withListener(this)
.alternativeRoutes(false)
.waypoints(new LatLng(lat, lng), customerpickuplocation)
.key("your api key")
.build();
routing.execute();
}

"This ip site or mobile application is not authorized to use this api key"

I use this https://github.com/akexorcist/Android-GoogleDirectionLibrary library and my code is in below;
GoogleDirection.withServerKey("MyApiKey")
.from(new LatLng(Double.parseDouble(work.getAxCor()), Double.parseDouble(work.getAyCor())))
.to(new LatLng(Double.parseDouble(work.getBxCor()), Double.parseDouble(work.getByCor())))
.execute(new DirectionCallback() {
#Override
public void onDirectionSuccess(Direction direction, String rawBody) {
if(direction.isOK()) {
Route route = direction.getRouteList().get(0);
Leg leg = route.getLegList().get(0);
Info distanceInfo = leg.getDistance();
Info durationInfo = leg.getDuration();
distance = distanceInfo.getText();
duration = durationInfo.getText();
} else {
}
}
#Override
public void onDirectionFailure(Throwable t) {
// Do something
}
});
But i get a mistake ""This ip site or mobile application is not authorized to use this api key"". Map is shown. There is no problem on map. Geocoding, Geolocation and places Api's are enable. Thanks.
Directions API it's a web service and bundle restrictions can't be applied.
From the documentation you can either use a proxy, obfuscate the key or certificate pinning.

Turn by turn directions in android app using Mapbox

A colleague of mine is currently working on implementing turn by turn directions into an app that is being developed for the company we are working in. I have been tasked with trying to assist him but neither of us have been able to make any progress.
He is using Mapbox to create the map. I have never used mapbox before so I am not much help.
He has code implemented that should give us turn by turn directions but it does not seem to be doing anything whatsoever.
Sorry if I am bringing up old questions or am not stating my situation clearly but this is the best I can explain myself. We have done much searching but nothing we found seems to help.
Here is the code that he has tried using that is supposed to implement turn by turn directions.
private void getRoute(Waypoint origin, Waypoint destination) throws ServicesException {
MapboxDirections client = new MapboxDirections.Builder()
.setOrigin(origin)
.setDestination(destination)
.setProfile(DirectionsCriteria.PROFILE_DRIVING)
.setSteps(true)
// .setOverview(DirectionsCriteria.OVERVIEW_FULL)
.setInstructions(DirectionsCriteria.INSTRUCTIONS_TEXT)
.setAccessToken("pk.eyJ1IjoibnRyY3N2ZyIsImEiOiJCUmc4OHhjIn0.shHWdNg3Q32QUHJ1nOCs3A")
.build();
client.enqueue(new retrofit.Callback<DirectionsResponse>() {
#Override
public void onResponse(Response<DirectionsResponse> response, Retrofit retrofit) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().getRoutes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
}
#Override
public void onFailure(Throwable t) {
Log.e(TAG, "Error: " + t.getMessage());
Toast.makeText(MainActivity.this, "Error: " + t.getMessage(), Toast.LENGTH_SHORT).show();
}
public void onResponse(Response<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().getRoutes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
drawRoute(currentRoute);
}
private void drawRoute(DirectionsRoute route) {
// Convert LineString coordinates into LatLng[]
LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
List<Position> coordinates = lineString.getCoordinates();
LatLng[] points = new LatLng[coordinates.size()];
for (int i = 0; i < coordinates.size(); i++) {
points[i] = new LatLng(
coordinates.get(i).getLatitude(),
coordinates.get(i).getLongitude());
}
Polyline polyline = mMapboxMap.addPolyline(new PolylineOptions()
.add(points)
.color(Color.RED)
.width(5));
directionsOn = true;
}
Any help would be very much appreciated.
Thanks in advance.
I'd highly recommend changing from Directions v4 to v5 found in Mapbox Java. Once you make the switch, you can work off this example found on our website. Make sure you are also passing in coordinates in the correct order, longitude is given first followed by latitude.
Dear friend mapbox provides detailed document with sample code snippets as well.
I have build a working app for my requirement by following mapbox turn by turn navigation documents.
please follow the link and let me know if you face any issues.
Link : https://www.mapbox.com/android-docs/navigation/overview/navigation-ui/
Here you can use NavigationView component to customise the mapbox turn by turn features.

How to use Google maps search functionality api in my application?

Is it possible to use it as library project for my application,i want to use Android Google Maps real app search-ability functionality. How can i do it,is it possible?
Thanks in advance..
EDIT:
I have shown Google Map in my app successfully, I want to include Google Map search functionality means that I can able to search any location in the world in auto suggested field and by selecting a particular location and move marker to that location. so how can I?
I tried this and this but not getting auto suggested text why I don't know..
I want like:
step1: show map with search box
step2: while entering text it should auto suggest.
step3: when click on particular name move map to that location
You can easily provide that kind of search functionality by using Places API and Geocode API (Both will help you according to your usecase).
Read the below Documentation for your assistance.
GeoCode API
Places API
I would recommend to use Places API for your need ( As per my observation on your usecase). But you could also use geocode, If you needed.
Many working reference and examples are there.
For startup, below are my reference :
PlacesAPI AutoComplete feature, Hotel Finder with Autocomplete
GeocodeAPI Simple GeoCoding
NOTE :
I have suggested javascript API. But not sure whether it will help you in Android environment (I dont know anything about android environment).
No single Api can help you have to use multiple google api's
Step1. Implement Google Place autocomplete Read this
Step2. You have to geocode means you have to convert address to latitude and longitude check this
Step3. Now You can plot these lat-long on the map.
This works for me.
I think you should take a look at the Google Maps API for Android at https://developers.google.com/maps/documentation/android/
The Google Search Appliance doesn't have any mapping or geo search features right now.
This is how I did it ---
Android Manifest file should contain the following lines:
<uses-library
android:name="com.google.android.maps"
android:required="true" >
</uses-library>
<!-- You must insert your own Google Maps for Android API v2 key in here. -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="<put your api key value here>" />
Location XML file should have the following apart from anything extra:
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Location java file should have something like this:
View mapView = null;
private GoogleMap mMap;
mMap = supportMapFragment.getMap();
mapView = (View) view.findViewById(R.id.map);
SupportMapFragment supportMapFragment = (SupportMapFragment) fragmentManager
.findFragmentById(R.id.map);
if(mMap != null){
mMap.setMyLocationEnabled(true);
}
if(mMap != null)
mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng latLng) {
new EditMap().execute("", String.valueOf(latLng.latitude), String.valueOf(latLng.longitude));
}
});
class EditMap extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* getting Albums JSON
* */
protected String doInBackground(String... args) {
String address = args[0];
double latitude = Double.parseDouble(args[1]);
double longitude = Double.parseDouble(args[2]);
return editMap(address, latitude, longitude);
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String result) {
if(!result.equals(""))
ToastUtil.ToastShort(getActivity(), result);
else {
mMap.clear();
mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).title(attvalue));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 11));
}
}
}
NOTE:
These are the minimal requirements for the setting of location as you choose from Map that fills the location in your text.
There is a background thread that runs as you long press the location in a map.
The listener defined for that is setOnMapLongClickListener as you see above.
The execution will place the marker to the exact location you chose to mark as set.
There will be a done button after you have chosen the location by a marker. This done button will confirm what you have chosen and will set that on a textfield for you.
The above code uses the method editMap to edit the map location.
The implementation is as done here:
private String editMap(String address, double latitude, double longitude ) {
String keyword = null;
try {
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
if(!address.equals("")){
keyword = address;
java.util.List<android.location.Address> result = geocoder
.getFromLocationName(keyword, 1);
if (result.size() > 0) {
lat = (double) result.get(0).getLatitude();
lng = (double) result.get(0).getLongitude();
attvalue = address;
} else {
return "Record not found";
}
} else {
String sUrl = "http://google.com/maps/api/geocode/json?latlng="+latitude+","+longitude+"&sensor=true";
DefaultHttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(sUrl);
HttpResponse r = client.execute(get);
int status = r.getStatusLine().getStatusCode();
if(status == 200){
HttpEntity e = r.getEntity();
String data = EntityUtils.toString(e);
try{
JSONObject jsonObject = new JSONObject(data);
JSONArray results = jsonObject.getJSONArray("results");
JSONObject addressObject = results.getJSONObject(0);
JSONArray addressComp = addressObject.getJSONArray("address_components");
String city = "", state = "";
for(int i=0; i < addressComp.length(); i++){
JSONArray types = addressComp.getJSONObject(i).getJSONArray("types");
if(city.equals("") && types.getString(0).equals("locality"))
city = addressComp.getJSONObject(i).getString("long_name");
if(state.equals("") && types.getString(0).equals("administrative_area_level_1"))
state = addressComp.getJSONObject(i).getString("long_name");
if(!city.equals("") && !state.equals(""))
break;
}
attvalue = city + ", " + state;
} catch (JSONException e1) {
e1.printStackTrace();
}
lat = latitude;
lng = longitude;
}else{
return "Location Not Found";
}
}
} catch (IOException io) {
return "Connection Error";
}
return "";
}
I hope this is enough to help you out.

Google Maps Android -- Map suddenly no longer displayed

I'm working on integrating Google Maps into the app I'm working on and I've had a rather unpleasant time doing it thus far. Regardless, I finally got a SupportMapFragment displaying a map and set a location and zoom level.
Here is the functional bits of my code thus far:
#Override
public void onActivityCreated( Bundle savedInstanceState ) {
super.onActivityCreated( savedInstanceState );
Location location = BundleChecker.getExtraOrThrow( KEY_LOCATION, new Bundle[] { savedInstanceState, getArguments() } );
setLocation( location );
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
setMapFragment( new SupportMapFragment() );
getActivity().getSupportFragmentManager().beginTransaction().add( R.id.location_detail_mapFrame, getMapFragment() ).commit();
}
populateAddress();
attachButtonListeners();
Runnable initMap = new Runnable() {
#Override
public void run() {
if ( checkGooglePlayServicesStatus() == ConnectionResult.SUCCESS ) {
try {
GoogleMap map = getMapFragment().getMap();
LatLng latLng = getLocation().getAddress().getLatLng( getActivity() );
CameraUpdate update = CameraUpdateFactory.newLatLngZoom( latLng, DEFAULT_MAP_ZOOM );
map.animateCamera( update );
}
catch (IOException e) {
Log.e( TAG, e.getMessage(), e );
Toast.makeText( getActivity(), "Unable to find location", Toast.LENGTH_SHORT ).show();
}
}
}
};
Handler handler = new Handler();
handler.postDelayed( initMap, 200 );
}
Also, I wrote a simple convenience method to get a LatLng from my Address model that you may criticize as well:
/*
* Convenience method to easily check if there is a valid lat & lng in this address
*/
public boolean hasLatLng() {
return getLatitude() != null && getLongitude() != null;
}
/*
* Convenience method for use with Google Maps API
*/
public LatLng getLatLng( Context context ) throws IOException {
LatLng latLng = null;
if ( hasLatLng() ) {
latLng = new LatLng( getLatitude(), getLongitude() );
}
else {
String locationString = getStreet() + ", " + AddressUtil.makeCityStateZipString( this );
Geocoder geoCoder = new Geocoder( context );
try {
List<android.location.Address> matches = geoCoder.getFromLocationName( locationString, 2 );
if ( matches != null && matches.size() > 0 ) {
double lat = matches.get( 0 ).getLatitude();
double lng = matches.get( 0 ).getLongitude();
latLng = new LatLng( lat, lng );
}
}
catch (IOException e) {
throw new IOException( e );
}
}
return latLng;
}
I'm aware that this code is not ideal and needs to be refactored. This is my first time working with Google Maps so please feel free to offer suggestions as to how I might do that as well. I experienced a lot of problems when trying to use the MapFragment as a in my layout XML, so I'm creating it programmatically.
The heart of the matter:
I was getting some bogus address data from the staging server and this resulted in the Address#getLatLng method returning null which caused an exception when calling CameraUpdateFactory.newLatLngZoom. After I got this exception, I was no longer able to get map data from Google. The map fragment is blank now and messages are displayed in logcat:
05-21 18:11:42.903: I/Google Maps Android API(15747): Failed to contact Google servers. Another attempt will be made when connectivity is established.
05-21 18:11:43.093: E/Google Maps Android API(15747): Failed to load map. Error contacting Google servers. This is probably an authentication issue (but could be due to network errors).
I have created a new api key and replaced the current one in my manifest with no change. The only changes I had made to the above code were to account for a null LatLng and I have since undone those changes in a pointless attempt to get my code back to a functional state.
Additionally, to make things a bit stranger, I built the sample maps project that is included with the Google Play Services Extras and it works perfectly (has a separate API key, btw).
What might I have done wrong here? Am I overlooking something obvious?
This problem is usually derived from a problem in referencing google-play-service library.
Take a look at this blog post I wrote on how to integrate Google Maps in your application, especially the first 3 steps:
Google Maps API V2
another cause of this could be that you haven't configured the Google API Console properly, so I suggest you to take a look at this guide as well:
Google Maps API V2 Key
another reason that may cause this is if you have some kind of problem in your permissions in the manifest file. You can look at the first guide for the needed permissions as well.
Use Something like this:
Update the google play services in the SDK.
Manually uninstall the App from device and restart the device.
i have tried it and its going perfectly bro
Also do one thing get the new api key to edited the new sh1 code from https://code.google.com/apis/console/
you can get your sh1 code from window- preference-android-buid
Making Google maps work is a Googlemare. This worked for me:
-Update Google play services with the Android Manager
-Make a fresh apikey with: Sha1 keystore (Window->preferences->Android->Build) and project package name. Do this at: https://code.google.com/apis/console/
Somebody had changed the package name and was foiling the app!!
Try this before you need anger management therapy thanks to google maps.

Categories

Resources