How do I get distance using fitness api? - android

I am using Google Fit API, be specific using HistoryApi
I am using Fitness.HistoryApi.readDailyTotal to get steps, calories and distance. From that I got steps and calories but distance is creating problem. But onResult is not getting called. Any help would be highly appreciated.
PendingResult<DailyTotalResult> distanceResult = Fitness.HistoryApi
.readDailyTotal(mClient, DataType.TYPE_DISTANCE_DELTA);
distanceResult.setResultCallback(new ResultCallback<DailyTotalResult>() {
#Override
public void onResult(DailyTotalResult dailyTotalResult) {
if (dailyTotalResult.getStatus().isSuccess()) {
DataSet totalSet = dailyTotalResult.getTotal();
long distance = totalSet.isEmpty()? 0: totalSet.getDataPoints().get(0).getValue(Field.FIELD_DISTANCE).asInt();
Log.i("-------------", "distance= " + distance);
}
}
});
From above code if (dailyTotalResult.getStatus().isSuccess()) { this is false in case of distance and it returns true while I try to get steps and calories.
All above code is run in background thread.

Can you please try adding below scope ?
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
Also upgrade with new fit api:
compile 'com.google.android.gms:play-services-fitness:10.0.0'

Related

Android - Google map clustering bug with markers not being reclustered

Edit: Show what the mapManager.filter() method does.
I have an Android app with ~20k markers being draw on the map and with filters option so the markers are being drawn and remove a lot.
I'm currently using this clustering library because it's way more efficient for displaying a large amount of markers than the classic google map library. But it's not supported and hasn't been updated since 3 years and i haven't found any alternatives.
Here is a video of the bug.
Here is my code that is call when i click on an filtering option in my app:
private void filter(){
//currentMapManager contain all the filters option and also the array list
//of the unfiltered markers (~20,000 markers)
//it's filter method retrieve the current filtering option enable (marker type, and other specs)
//And return markers from the full arraylist that match those filters options.
ArrayList<MarkerModel> filteredList = currentMapManager.filter(currentMapManager.getAllMarkers());
if (clusterManager != null) {
clusterManager.setItems(new ArrayList<>());
clusterManager.onCameraIdle();
clusterManager.setItems(filteredList);
clusterManager.onCameraIdle();
}
Here the mapManager.filter() method.
public ArrayList<MarkerModel> filter(List<MarkerModel> currentMarkers) {
ArrayList<Object> filtersArray = filters.getFilters();
/* filtersArray is an array like this :
* ['type', ['typeFilter1', 'typeFilter2'],
* 'date', dateTimestamp,
* 'withPictures', true,
* ....]
*/
return filter(currentMarkers, filtersArray);
}
private ArrayList<MarkerModel> filter(List<MarkerModel> currentMarkers,
ArrayList<Object> fieldsAndValues) {
if (fieldsAndValues.size() % 2 == 1) {
throw new IllegalArgumentException("Missing value in call to filterList().
There must be an even number of arguments that alternate between
field names and values");
} else {
//Here the arraylist that we are returning
ArrayList<MarkerModel> filteredMarkers = new ArrayList<>();
List<Object> argumentList = new ArrayList();
Collections.addAll(argumentList, fieldsAndValues);
if (!currentMarkers.isEmpty()) {
for (int j = 0; j < currentMarkers.size(); j++) {
MarkerModel marker = currentMarkers.get(j);
boolean isInFilter = true;
//Check fieldsAndValue filters...
//If isInFilter stay to true we
filteredMarkers.add(marker);
}
}
return filteredMarkers;
}
}
I think the problem is that the cluster library is not supposed to have so much redrawn and it broke at some point from reading and working on 20k items arraylist.
I have look through all the forks branch of this library and look/try to understand the library source code but hasn't find any solution at my problem...
If you need other part of my source code to understand more tell me i will add it.
Thanks a lot if you can help me i have been struggling a lot with this issue...

Why GeoFire's GeoQuery's queryAtLocation not returning keys eventhough the lat & long within the given KMs?

I am creating an Android App , an Uber Clone. In this I am using Firebase to list the rides created by the user.
The Ride stored in the following format .
{
"category" : "NUVO",
"driverids" : "",
"drop_lat" : "40.7127753",
"drop_long" : "-74.0059728",
"estdate" : "Wed#Feb#28th",
"estmile" : "4.19",
"esttime" : "01:02#PM",
"esttotalfare" : "4.61",
"fareest" : "1.1",
"g" : "t9z83wv46x",
"l" : [ 40.674426, -73.944033 ],
"notes" : "Gv",
"orgin_lat" : "145 Brooklyn Ave, Brooklyn, NY 11213, USA%20New York, NY, USA",
"request_id" : "5a75579740d166e95b8b4567",
"requested_category" : "FAM_SUV",
"rider_id" : "5a507bf340d16660288b4567",
"status" : 1,
"trip_id" : 0
}
Now I am Using GeoFire's GeoQuery's queryAtLocation to pick all rides with in 5 KMs from his current location.
The query uses the lat & lang from the field "l" and compare it with the current location lat & lang of the driver.
If the list's lat & lang is within 5 KMs , it will return the key , that is the parent name of the child "l".
Now I am currently in India. I use Lockito App to fix a Mock GPS location in India. After that I create a Ride within 5 KMs radius.
Now , the ride successfully listed in the drivers list. No Problem.
My Issue
But When I fix a mock GPS location in USA , this flow not working. I fixed the driver location on Brookyln Childeren's Museum and also created a ride on the same museum. But GeoQuery not calling onKeyEntered . It simply exists after calling GeoQueryReady function .
I check my current Lat & Lang from the app and it returns as 40.67434763453142,-73.94402358680964. I checked this against the lat&lang on field "l" .(refer above JSON). Both pointing to same location.
But GeoQuery failed to retrieve it
My Question
Why this issue happening ?. If I use India's locations. Geoquery works perfectly .
But why it failing in USA.
You may tell ,"There will be an issue in lockito". But Lockito returning correct location lat lang . I checked it in Logcat. And , if there is a issue in Lockitto then How it working in India.
Here My GeoQoery Code :
try {
showDialog();
double nearByDistanceRadius = 5.00d;
com.firebase.geofire.GeoFire geoFire = new com.firebase.geofire.GeoFire(FirebaseDatabase.getInstance().getReference().child(childtype));
final com.firebase.geofire.GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(latitude, longitude), nearByDistanceRadius);
geoQueryEventListener=new GeoQueryEventListener() {
#Override
public void onKeyEntered(final String key, GeoLocation location) {
Toast.makeText (getApplicationContext(), "The key is = ",Toast.LENGTH_LONG).show();
}
#Override
public void onKeyExited(final String key) {
System.out.println("ON KEYEXITED"+key);
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
System.out.println("ON KEYMOVED"+key);
}
#Override
public void onGeoQueryReady() {
System.out.println("ON KEYQUERYREADY");
#Override
public void onGeoQueryError(DatabaseError error) {
System.out.println("ON KEYERROR"+error);
}
};
geoQuery.addGeoQueryEventListener(geoQueryEventListener);
} catch (Exception e) {
e.printStackTrace();
}
Above , except onGeoQueryReady , no method called if I use USA. But it's
working in India. Can anyone tell me why that is the case?
This maybe long gone n dusted but perhaps can help others.
Since u mention its mock GPS coordinates. and u probably manually entered them.
GeoFire uses a special g: "code" (10 digit code) which is area wise / city wise
if you use the same g code in the same city / country (India in ur case) it will work fine !
However,if you use the same code in another country , geoQuery will fail. To make it work. u need to add one line in your code
geoFire.SetLocation() and someone in USA needs to run that code once only. geoFire will save a special key in g: "" Location. After you have the key you can remove that line from your app.
You can use that key generated by geoFire to manually enter as many locations as you want in USA and geoQuery will always work on that !!! Make sure you use the same pattern as geoFire does.
g:
l:
0:
1:
It took a while but I figured. It's that buggy geofire dependency. Downgrade from 3.0.0 to 2.3.1 solved it.

Get all places around 2 kilometers using Google's PlaceDetectionApi

I am using following API to get all places from current location,
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
Log.v("App",
"2. likelyPlaces.getCount() : "
+ likelyPlaces.getCount() + ", placeType : "
+ placeType);
places.clear();
GooglePlace place;
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
place = new GooglePlace();
place.setAddress(placeLikelihood.getPlace()
.getAddress());
place.setId(placeLikelihood.getPlace().getId());
place.setLatLng(placeLikelihood.getPlace()
.getLatLng());
place.setName(placeLikelihood.getPlace().getName());
place.setPhoneNumber(placeLikelihood.getPlace()
.getPhoneNumber());
place.setPriceLevel(placeLikelihood.getPlace()
.getPriceLevel());
place.setRating(placeLikelihood.getPlace()
.getRating());
places.add(place);
}
mAdapter.notifyDataSetChanged();
likelyPlaces.release();
}
});
This one returns only 20 places, and also no photo of the place. So I want to know how to get all places around 2 kilometers from current location. Also how to get the place image.
I know we can get more than 20 results by using
https://maps.googleapis.com/maps/api/place/search/xml?location=Enter Latitude,Enter Longitude&radius=10000&types=store&hasNextPage=true&nextPage()=true&sensor=false&key=enter google_map_key &pagetoken="Enter the first page token Value"
But for this API we have to provide Server IP for get API key. So need to know how can we get more than 20 results by using
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
Any help will be highly appreciable.
Don't know if you found answer already but you should check this out if not:
The Places API will return up to 20 establishments per query; however, each search can return as many as 60 results, split across three pages
https://stackoverflow.com/a/9627664/3677394

Query between distances in Parse

I would like to search places between two given distances, using GeoPoints. Using the currently api, I think I could make something like this pseudo algorithm:
query.whereWithinKilometers("directions", GlobalData.ownerGeoPoint, MAXIMUM distance);
MINUS
query.whereWithinKilometers("directions", GlobalData.ownerGeoPoint, MINIMUM distance);
How can I translate to real code?
Finally I found a way to do it with a parse query.
// Do not want locations further than maxDistance
ParseQuery query = ParseQuery.getQuery("MyData");
query.whereWithinKilometers("location", userGeoPoint, maxDistance);
// Do not want locations closer than minDistance
ParseQuery<ParseObject> innerQuery = ParseQuery.getQuery("MyData");
innerQuery.whereWithinKilometers("location", userGeoPoint, minDistance);
query.whereDoesNotMatchKeyInQuery("objectId", "objectId", innerQuery);
Likely you'll have to pull in everything within the maximum distance from Parse to your app, then inside your app filter out anything that is closer than the minimum.
Thankfully Parse includes some distance measuring as part of PFGeoPoint. Check out the three methods here.
distanceInRadiansTo:
distanceInMilesTo:
distanceInKilometersTo:
So your pseudocode is:
(After you get back everything within the outer radius)
Make a new array (var) called finalList
For i = 0; i < objects.count; i++ {
var gp: PFGeoPoint = objects[i]
if gp.distanceInMilesTo:originalGeoPoint >= minimumRadiusInMiles {
finalList.push(gp)
}
}

Distance Travelled

I am creating a Phonegap App (using jQuery and Google Maps API V3) related to travelling and would like to show the user the distance he/she has travelled since starting the app.
Is there any Google function for this? Or can anyone recommend what I can do to get the total distance travelled?
It can be done easily. You have to understand, by using a Google Maps API for jQuery you have all needed tools to do it by yourself.
First, you need to define a time period (lets say 1 minute). We will need it to create a reference point of our movements. Next step is to use phonegap/cordova geolocation API to calculate our position (latitude and longitude):
http://docs.phonegap.com/en/1.0.0/phonegap_geolocation_geolocation.md.html
At this point choose do you want to:
Store a position (latitude and longitude) every 1 minute in some js array
Or do the same thing like in point 1 and also show it on the map with gmap addMarker ability.
At the end you need to calculate a distance. Loop through the position array and use latitude and longitude to calculate a distance between every available point. Here you will find function used for a such calculation (with a js example):
http://www.movable-type.co.uk/scripts/latlong.html
Or you can use Google Maps APi function:
google.maps.geometry.spherical.computeDistanceBetween (latLngA, latLngB);
EDIT:
Here's a working example for you: http://jsfiddle.net/Gajotres/6YpAG/
Code:
$(document).ready(function(){
// Chicago
var coordinateObject= new Object();
coordinateObject.lat = '41.83682786072714';
coordinateObject.lng = '-87.626953125';
geoLocationHandler.addLocation(coordinateObject);
// New York
var coordinateObject= new Object();
coordinateObject.lat = '40.58058466412761';
coordinateObject.lng = '-74.00390625';
geoLocationHandler.addLocation(coordinateObject);
// Toronto
var coordinateObject= new Object();
coordinateObject.lat = '43.70759350405294';
coordinateObject.lng = '-79.365234375';
geoLocationHandler.addLocation(coordinateObject);
var len = geoLocationHandler.arrLocations.length;
for (var i = 0; i < len; i++) {
if(i == 1){
geoLocationHandler.distance += geoLocationHandler.calcDistance(geoLocationHandler.arrLocations[i-1].lat,geoLocationHandler.arrLocations[i-1].lng,geoLocationHandler.arrLocations[i].lat,geoLocationHandler.arrLocations[i].lng);
}
}
alert(geoLocationHandler.distance);
});
var geoLocationHandler = {
arrLocations : [],
distance : 0,
addLocation:function(obj){
geoLocationHandler.arrLocations.push(obj);
},
calcDistance:function(fromLat, fromLng, toLat, toLng) {
return google.maps.geometry.spherical.computeDistanceBetween(new google.maps.LatLng(fromLat, fromLng), new google.maps.LatLng(toLat, toLng));
}
};
Final result is a distance expressed in meters.
Every time you have a new coordination use this to create a new object and add it to the array:
var coordinateObject= new Object();
coordinateObject.lat = '41.83682786072714'; // Change with your latitude
coordinateObject.lng = '-87.626953125'; // Change with your longitude
geoLocationHandler.addLocation(coordinateObject);

Categories

Resources