I am creating a blood bank app in which I am showing the user, his current position and different donors available near him on a map. When the user clicks on the blood request button, I show him a list of different donors available near him. Now on the list with the names of donors, I want to show the distance of that donor from the user current location. Right now I am getting distance by line which always shows 56 KM less than the actual distance. For that I am doing this :
donarLat = profiles.getLatitude();
donarLong = profiles.getLongitude();
String distance = "";
if (currentLat != null && currentLong != null && donarLat != null && donarLong != null) {
origin = new LatLng(currentLat, currentLong);
dest = new LatLng(donarLat, donarLong);
float[] result = new float[1];
// Location.distanceBetween(currentLat, currentLong,donarLat, donarLong, result);
distance = String.valueOf(SphericalUtil.computeDistanceBetween(origin,dest));
System.out.println("d9" + profiles.getName()+ " : " + distance);
I have also got the distance using Location as you can see the commented line in code but it all gives location by line but I want to get the Location by road for which I have seen a lot of answers on StackOverflow which was answered minimum 6 years ago and also tried but sometimes it crashes app or some times it does nothing. I assume that for location by the road, I have to use google direction API but how I don't understand how to use it. I have tried that API in postman but first, it gave me an error to enable direction API after doing that it asked me to enable billing method. I am attaching the photo of Postman. And will be really thankful if someone shows me how to use API properly to get the exact distance by road.
Google API is not FREE now
Some API is free for some period but charge cost after that trial period.
And they require an API key with billing info to use trial.
In your case you have to your API key is not valid.
Create an API key with billing info form this link and be sure you can use it for a trial period. If not you may get changed.
Related
I am developing an android app and I am trying to check if the user's current location is the same with one of some addresses that I hold in a csv.
For example:
An address from the csv is a String like "Via dei Monti Tiburtini 385, Roma 00157 "
At first I have get the fully current location by the following code
Geocoder geocoder;
List<Address> addresses = null;
geocoder = new Geocoder(MainActivity.this, locale);
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
I thought to make just check if the Strings are equals but ofcourse this is not a right solution because the location addresses can differ in the way that been written.
For example:
csv file -> "Via dei Monti Tiburtini 385, Roma 00157 "
user's current loc -> "Via dei Monti Tiburtini 385, Roma 00157, ITALY "
Note: My addresses are not in english characters (both user's current loc and csv loc) but for now I would like to find a solution at least for english
I am trying to find something on the web but I am not able to find something similar to that.
I would appreciate any help, Thank you
Checking if GPS coordinates are equal might be too restrictive, I agree with you. What you could do is check if they are within a certain range, maybe 0.01% margin from what's in your DB. You can test it on Google Maps and see how much you think you can tolerate based on your application.
This page has some details about the numerical values for latitude and longitude:
https://en.wikipedia.org/wiki/Geographic_coordinate_system
From a user address perspective, in my experience with shipping applications, there is this concept of Address Standardization which tries to make the addresses conform in format so that other systems consistently find the same location.
This could help with how people enter their address for example "apartment #3" or "app #3" or "app 3", which could all result in different addresses. There are libraries for UPS and others that provide this.
https://www.ups.com/us/en/services/shipping/connectship.page
This is if you are starting from an address.
If you start from GPS location, you could use API-s available on the web, maybe Google Maps, to find the address of a specific GPS location.
https://www.google.com/maps/#44.4257258,-88.1063132
and this:
https://support.google.com/maps/answer/18539?hl=en&co=GENIE.Platform%3DDesktop
My application needs to know whether the phone is in the pocket or in hand based on which few parameters are set specific to individual than to move on to perform next tasks.
I have read various blogs and also SensorManager android developer but none helped me out. The only related link I found on stack is this with no solution, Though one comment on that question suggests using Awareness API. I am going through it, my understanding is that the User Activity is the context to find this- I may be wrong. There maybe someone worked or may be doing R&D on this, please share your observation that may help me out in some way to go further.
Is there any way to find is the phone in pocket or not?If yes, Can somebody tell me How do One do that?
Any guidance/links to the concepts are helpful.
Thanks.
I implemented this in my project. I got readings from the Light sensor, Accelerometer and Proximity sensor. Keep in mind that it approximately detects device presence in a pocket.
Getting the current parameteres from the sensors (accelerometer, proximity and light sensors):
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
g = new float[3];
g = event.values.clone();
double norm_Of_g = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2]);
g[0] = (float)(g[0] / norm_Of_g);
g[1] = (float)(g[1] / norm_Of_g);
g[2] = (float)(g[2] / norm_Of_g);
inclination = (int) Math.round(Math.toDegrees(Math.acos(g[2])));
accReading.setText("XYZ: " + round(g[0]) + ", " + round(g[1]) + ", " + round(g[2]) + " inc: " + inclination);
}
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
proximityReading.setText("Proximity Sensor Reading:" + String.valueOf(event.values[0]));
rp = event.values[0];
}
if (event.sensor.getType() == Sensor.TYPE_LIGHT) {
lightReading.setText("LIGHT: " + event.values[0]);
rl = event.values[0];
}
if ((rp != -1) && (rl != -1) && (inclination != -1)) {
main.detect(rp, rl, g, inclination);
}
}
Then based on this data I decide whether or not the device is in a pocket:
public void detect(float prox, float light, float g[], int inc){
if((prox<1)&&(light<2)&&(g[1]<-0.6)&&( (inc>75)||(inc<100))){
pocket=1;
//IN POCKET
}
if((prox>=1)&&(light>=2)&&(g[1]>=-0.7)){
if(pocket==1){
playSound();
pocket=0;
}
//OUT OF POCKET
}
}
Keep in mind that it's not fully accurate.
Code: https://github.com/IvanLudvig/PocketSword
Blog post: https://ivanludvig.github.io/blog/2019/06/21/detecting-device-in-a-pocket-android.html
The only way we can come somewhat near to the solution is using.Google Awareness API wont solve the problem as it has a entirely different usage.
Light sensor(Environment sensor)
Proximity sensor(Position sensor)
The Android platform provides four sensors that let you monitor various environmental properties. You can use these sensors to monitor
relative ambient humidity
luminescence
ambient pressure
ambient temperature
All four environment sensors are hardware-based and are available only if a device manufacturer has built them into a device. With the exception of the light sensor, which most device manufacturers use to control screen brightness, environment sensors are not always available on devices. Because of this, it's particularly important that you verify at run time whether an environment sensor exists before you attempt to acquire data from it.
Light sensor can be used to calculate the light intensity.For example many mobile phones having Auto brightness mode function, this function work on light sensor that will adjust screen brightness as per light intensity.
There are many unites such as Lux,candela,lumen etc, to measure light intensity.
Considering this there will be considerable difference in light intensity when you phone in in pocket or outside pocket.
Although the same will happen for the case when you are operating phone is dark room. or at those place where the light intensity is quite low. hence to distinguish among such cases is the real challenge.You can use other environments sensor in combination of light sensor to come to an effective outcome.But i assume an accurate solution is dicey.
To study more about these sensors kindly refer to following links
https://developer.android.com/guide/topics/sensors/sensors_environment.html
https://developer.android.com/guide/topics/sensors/sensors_position.html
Google awareness API wont work for this case. as provides entirely different solution.
It provides two API
Fence API
Snapshot API
You can use the Snapshot API to get information about the user's current environment. Using the Snapshot API, you can access a variety of context signals:
Detected user activity, such as walking or driving.
Nearby beacons that you have registered.
Headphone state (plugged in or not)
Location, including latitude and longitude.
Place where the user is currently located.
Weather conditions in the user's current location.
Using the Fence API, you can define fences based on context signals such as:
The user's current location (lat/lng)
The user's current activity (walking, driving, etc.).
Device-specific conditions, such as whether the headphones are
plugged in.
Proximity to nearby beacons.
For a cross-platform solution, you can now use the NumberEight SDK for this task.
It performs a wide variety of context recognition tasks on both iOS and Android including:
Real-time physical activity detection
Device position detection (i.e. presence in pocket)
Motion detection
Reachability
Local weather
It can also record user context for reports and analysis via the online portal.
How to detect whether a phone is in a pocket:
For example, to record user activity in Kotlin, you would do:
val ne = NumberEight()
ne.onDevicePositionUpdated { glimpse ->
if (glimpse.mostProbable.state == State.InPocket) {
Log.d("MyApp", "Phone is in a pocket!")
}
}
or in Java:
NumberEight ne = new NumberEight();
ne.onDevicePositionUpdated(
new NumberEight.SubscriptionCallback<NEDevicePosition>() {
#Override
public void onUpdated(#NonNull Glimpse<NEDevicePosition> glimpse) {
if (glimpse.mostProbable.state == State.InPocket) {
Log.d("MyApp", "Phone is in a pocket!");
}
}
});
Here are some iOS and Android example projects.
Disclosure: I'm one of the developers.
I have implemented the Google Places API. If I search for "Cafes near my location" in Google Maps I get a list of results, whereas, when I perform the same search with Google Places I get 0 results.
I also used a Place.TYPE_CAFE PlaceFilter (i.e. a filter for cafes) in my implementation of Google Places and it returns 0 results for cafes even though there are at least 2 cafes within 0.5 miles of my location according to Google Maps when I search for "Cafes near my location"
Here is my implementation of the PlaceFilter with the Places.PlaceDetectionApi
ArrayList<Integer> placeType = new ArrayList<Integer>();
placeType.add(Integer.parseInt(""+Place.TYPE_CAFE));
PlaceFilter placeFilter = new PlaceFilter(placeType,false,null,null) ;
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, placeFilter);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
Log.i("placesAPI", String.format("Place '%s' has likelihood: %g",
placeLikelihood.getPlace().getName(),
placeLikelihood.getLikelihood()));
}
likelyPlaces.release();
}
})
Problem in a nutshell: How do I make the Google Places' search functionality return as many places as Google Maps' ?
If you need any more code let me know,
Thanks in advance
The Google Places API may have improved since I asked this question but one solution to this problem is to use the Google Maps Web API.
You may use Place Autocomplete service in the Google Places API for Android and you can also get palces near by your location using Google Place API. Autocomplete returns place predictions in response to user search queries. As the user types, the autocomplete service returns suggestions for places to points of interest.
Here's a sample tutorial showing nearby places using Google Places API and Google Maps Android V2: http://wptrafficanalyzer.in/blog/showing-nearby-places-using-google-places-api-and-google-map-android-api-v2/
In my Android app I use Picasso to load images. This normally works perfectly well.
Today I tried loading a static image from the google maps api, but this doesn't seem to work. When I open the example link as provided on their info page, I get to see the static map image perfectly well. When I load it in my Android app using the line below, I get nothing at all.
Picasso.with(getContext()).load("http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=370x250&maptype=roadmap%20&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318%20&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false").into(mapView);
I also tried to download the image and uploading it to my personal webspace, from which it loads perfectly well, but somehow, it doesn't seem to load directly from the direct google API url.
Does anybody know why this is so, and how I can solve it?
The only programmatic point-of-failure that comes to mind is in parsing the URI. Looking at the current Picasso code (https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Picasso.java) I see the following:
public RequestCreator load(String path) {
if (path == null) {
return new RequestCreator(this, null, 0);
}
if (path.trim().length() == 0) {
throw new IllegalArgumentException("Path must not be empty.");
}
return load(Uri.parse(path));
}
So I'd first debug
Uri.parse("http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=370x250&maptype=roadmap%20&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318%20&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false")
and see what that Object looks like. Does it drop or confuse any of your parameters?
If that doesn't lead you anwhere, try downloading the file manually using a HttpClient [or similar]. Then at least you can fully debug the request/response.
Also, I know Google maps has some limits -- are you sure you haven't reached them?
replace http with https
replace | with %7C
add api key
The .loadMap() function has many declared variables. This is the heart of the whole process.
So what is required for the static maps API to give us an image is that we make an http request with a given url, for which an image response (URL) is received. Let us run through the meaning and utility of these variables. Yes, all of them have a completely different meaning!
The mapUrlInitial variable is always the same while making an API call. It has a query of center ( ?center ) which specifies that we want the location to be centered in the map.
The mapUrlProperties variable contains a string where you control the actual zooming of the image response you will get, the size ofthe image and the color of the marker which will point out our place.
The mapUrlMapType variable is a string where you can actually determine the marker size you want and the type of the map. We are using a roadtype map in the app.
Finally latLong is a string which concatenates the latitude and the longitude of the place we want to pinpoint!
We then concatenate all of these strings to form a feasible Url. The Url is then loaded as we have seen above, in the Picasso code. One thing we can notice is that an event object is always required for all of this to happen, because we are able to fetch the position details using the event object! Final Code:-
fun loadMap(event: Event): String{
//location handling
val mapUrlInitial = “https://maps.googleapis.com/maps/api/staticmap?center=”
val mapUrlProperties = “&zoom=12&size=1200×390&markers=color:red%7C”
val mapUrlMapType = “&markers=size:mid&maptype=roadmap”
val latLong: String = “” +event.latitude + “,” + event.longitude
return mapUrlInitial + latLong + mapUrlProperties + latLong + mapUrlMapType
}
//load image
Picasso.get()
.load(loadMap(event))
.placeholder(R.drawable.ic_map_black_24dp)
.into(rootView.image_map)
I know how to get the current GPS location of a mobile phone.
I also know how to save the GPS location to the photo when you take it. (Camera option Samsung galaxy s2).
But how can I get the GPS location of that photo (later)?
When I open the photo on the computer, I can see the GPS location data, but got no idea how to extract them later in android. So could someone put me in the good direction?
To make question more clearly:
How can I get the GPS location of a photo that is already taken?
Thanks already,
Bigflow
josnidhin made this answer possible, so be sure to give him credit too :)
Here we go:
import android.media.ExifInterface;
exif = new ExifInterface(filePath);
String lat = ExifInterface.TAG_GPS_LATITUDE;
String lat_data = exif.getAttribute(lat);
After that, lat_data will be something like: 51/1,58/1,32/1
This is the same as: 51, 58, 32. (typing this in google maps will give bad result)
To get the gps coordinates of this you need to do some math, here it comes:
Calculate the total number of seconds:
58′32″ = (58*60 + 32) = 3512
seconds.
The fractional part is total number of seconds divided by 3600:
3512 / 3600 = ~0.975556
Add fractional degrees to whole degrees to produce the final result:
51 + 0.975556 = 51.975556
If it is a West longitude coordinate, negate the result. (it isn't this time)
answer: 51.975556
This is also the same when you with TAG_GPS_LONGITUDE
I think the geotag is in the EXIF data of the photo taken. Find a suitable EXIF data reader which will help you extract the data you want.