I'm trying to retrieve the people in a user's circle that have installed the current application.
I have used the sample application "PlusSampleActivity" provided in the SDK and successfully managed to get the list of all people in the user's circles.
However, I'm not sure how to get if the person have installed the application or not. The documentation available seems to be very limited...
What I have found is
https://developer.android.com/reference/com/google/android/gms/plus/model/people/Person.html
I'm using below function but this is always returning false. (I have created a user that have installed the app and I can see this when visiting the user's profile on the web using Google+)
Is there some other API that should be used? Or some way to debug this better?
public abstract boolean isHasApp ()
If "true", indicates that the person has installed the app that is
making the request and has chosen to expose this install state to the
caller. A value of "false" indicates that the install state cannot be
determined (it is either not installed or the person has chosen to
keep this information private).
UPDATED
Seems like the hasapp field is not even included in the response?
When trying the API on below link, I never succeed to have the hasapp included in the response... Any suggestions what I might be doing wrong??
https://developers.google.com/apis-explorer/#p/plus/v1/plus.people.get
(I posted the same question on Google groups, here)
Unfortunately, the hasApp field doesn't get filled in the response - it's actually a legacy field from an older API. The best way of matching is to keep track of installed users in your database with their Google IDs, and compare that to the IDs in the people.list response.
The documentation should be updated to reflect this soon, sorry for the confusion!
Related
I'm building an Android app which syncs data to Google Fit and uses the Google Fit SDK to achieve that - but I'm pretty sure my question also applies when you are using the REST API.
Within my app users can also change data inserted to Google Fit. The Google Fit SDK has two distinct functions to handle those kind of things: insertData() and updateData().
Now, I don't want to keep track of whether a user changed an already synced data point vs whether it is an entirely new datapoint. I just want to have a simple Boolean flag which indicates whether a data point has already been uploaded to Google Fit or not - that's to keep things simple and reliable on the app's side.
So when a user creates a new data point in my app, I set a syncedToGoogleFit flag for that data point in my DB to 0. When the data point has been synced to Google Fit I set it to 1. When the user later changes the data point in my app I set it to 0 again and so on.
However, the Google Fit SDK distinguishes between inserting and updating which means a simple Boolean wouldn't be enough to track changes on my end as insertData() will fail if there already is a data point for a given timestamp. Is it possible to always call updateData() even if I am actually inserting new data and that way get by with just the Boolean flag on my end?
Looking at the documentation it should be okay, but I would feel safer if someone could confirm that. Also I'd like to know whether there are any potential performance implications of the approach outlined above, but I guess this is just something the SDK devs can answer.
I've played around quite a bit with the SDK now and from what I am seeing I can say, that using updateData() seems to work just fine.
Background
In the "Phone" app of Google, there is an option "Caller ID & spam" :
So, if you get a call from someone or some organization that isn't on the address book, yet it is identified somehow, you get a name for it, as such (called "+972-035283487") :
Ever since Android M (6.0 - API 23) , apps can replace the default phone app, and then also providing alternative UI when you call someone or get a phone call, by extending InCallService class, as demonstrated here which is based on here.
The problem
I want to try to show the same information as on the Phone app, meaning the name of the person/company in case it identified it (and it's not on the address book).
What I've tried
I tried to dig over the various things that I get via the API of the dialer, but failed:
Various fields and functions of: android.telecom.Call class
There is getDetails inside of the Call class, so I tried to get what's inside there, and there is also statusHints and "label" inside the "statusHints" . None of those had any information (returned null). The reason I tried to look at "statusHints" is because that's what I see on the docs :
Contains status label and icon displayed in the in-call UI.
On the "Phone" app, pressing "Learn more" goes to a website (here) full of links that I think might be sources of the data, but I don't think the app itself uses this. Instead I think it uses something of Google.
The questions
Is it possible to get this CallerId information? If so, how?
How does the Phone app do it? It's supposed to be open sourced, so there has to be something that gives it this information, right? Would cloning it somehow get this information? Maybe Google has its own service for CallerID?
What are the "callDetails" and "statusHints" used for? What do they provide?
I believe Android's native phone app is using Google's place search API. As you can easily search for a place by its phone number and get place details like name, place id, formatted_address and many other fields that you can find in the documentation
Request URL:
https://maps.googleapis.com/maps/api/place/findplacefromtext/json
Request method: GET
Request query parameters:
key: Your application's API key.
input: The text input specifying which place to search for (for example a name or phone number).
inputtype: The type of input. This can be
one of either textquery or phonenumber. Phone numbers must be in
international format (prefixed by a plus sign ("+"), followed by the
country code, then the phone number itself).
Example request:
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?input=%2B972035283487&inputtype=phonenumber&fields=place_id,name&key=API_KEY_HERE
Example response:
{
"candidates" : [
{
"name" : "מלך העופות",
"place_id" : "ChIJ78ko1zBKHRURpwbgUdWc4nU"
},
{
"name" : "Of Yaakov",
"place_id" : "ChIJv3myn4FMHRURUGffcXgxKuw"
}
],
"status" : "OK"
}
Note:
Such an API is not available at the current moment in Google places SDK for Android, but you can use the HTTP API directly in your app or you can make an API in the backend as a proxy to the places API. I prefer the later version as in the first solution the API key is deployed in the application code and hackers could decompile the APK and use it for malicious reasons. For security reasons you have to restrict the usage of the API key to the IP address of the server in case you are using the backend solution!
I tried to decompile the Dialer app, couldn't find the specific info about how the app is doing it.
But this info could be useful. Please check it.
In Dialer app, there are classes SpamCallDatabase_Impl.smali SpamCallDatabase.smali
and there is service running in package com.google.android.gms app, which provides spam lists
com.google.android.gms/.telephonyspam.sync.SpamListSyncTaskService
and for caller id check this commit
https://gitlab.e.foundation/e/os/android_packages_apps_Dialer/commit/420eb901ed1d64fdaf055cde4cc46d7a5c0b42fc
This looks dialer app of lineage os
and it uses different services for phone num lookup like
https://auskunft.at/
https://www.dastelefonbuch.de/
I believe Google has its own database of spam callers, and the Phone app sends the number to its server, and if there is a match, it shows the name.
Maybe, if your app can read notifications, there is a possibility to retrieve that name. Try this example out and modify it according to your needs
You could check the working of apps like Truecaller for this. Truecaller acts on a give and take scenario... You want those unknown numbers then you have to part with your phone book contacts.. Now apparently everyone who has installed the app has surrendered his phone book. The data is crowd-sourced from the millions of users who have downloaded the truecaller app on their smart phones. As part of the end user agreement, the truecaller app asks the user to allow access to the user's address book/contacts on the smart phone. This data is then uploaded by the app to the company's servers. After going through several data matching/refining algorithms, this data is made available to all truecaller users to search upon.
Google Phone app is provided a feature of Use caller ID & spam protection by default. Some of these steps work only on Android 6.0 and up.
When you make or get a call with caller ID and spam protection on, you can see information about callers or businesses not in your contacts or warnings about potential spam callers.
To use caller ID and spam protection, your phone may need to send information about your calls to Google.
Turn caller ID & spam protection off or back on
Caller ID and spam protection is on by default. You can choose to turn it off.
To use caller ID and spam protection, your phone may need to send information about your calls to Google. It doesn’t control whether your number shows when you make calls.
Caller ID by Google shows the names of companies and services with a Google My Business listing. It also looks for matches in any directory that shows caller information for work or school accounts.
As per your solution, Google does not provide this kind of support as you want. you need to create your own function and save spam and other contact detail at your side.
For example I expect this kind of situation: data in my application lost relevance and so it usless until update. And until update it have to show users some predefined message.
Is here any simple and free solution to this task?
Guess I can use some server to somehow send simple messages... but it sounds way too complicated.
If this is important I use Xamarin.
Update: main difficulty here is fact - my application can't in any way define if it's outdated or not. This may happen in random moment.
Although the requirement is not very clear I assume Update here means app update.
each time user launches app make call to an api on ur server to check if user needs to update app
If that returns true take user to a static view that says app needs update and redirects user to google play to install updates
If you want to avoid using a server, you should try Firebase (https://firebase.google.com/). More specifically, you should use Firebase Remote Config (https://firebase.google.com/features/remote-config/).
Define in a key-value pair of something like minimum_app_version_required in Firebase Remote Config. Every time user opens the your app, compare the values of app version and minimum_app_version_required that you are getting from Firebase console and show a dialog box accordingly. You can also change the value of minimum_app_version_required anytime you want.
Just set some internal flag. That when that situation occurs, you can set the flag to true and just edit whatever layout element you are using such as listView or any other element with your predefined messages saved in strings.xml. You can also build any custom pop up screen, depends how you want to show them. Let me know if you didn't understand or exactly how you want?
Need to implement versioning for this problem. To achieve this, you have to maintain a version number in server, this is the version number you app will have to save and use it to validate with server. If both are not same, then app will get the latest data from the server.
I am currently using Google Games Services trying to update the user score offline. This works fine as there is a cool feature for that:
http://developer.android.com/reference/com/google/android/gms/games/leaderboard/OnScoreSubmittedListener.html#onScoreSubmitted(int,
com.google.android.gms.games.leaderboard.SubmitScoreResult) if the
device is offline or was otherwise unable to post the score to the
server. The score was stored locally and will be posted to the server
the next time the device is online and is able to perform a sync (no
further action is required from the client).
So, imagine that the user has 100 points, The score gan grow to 200,300,etc. and will be updated when going online.
Unfortunately, when querying the score with getRawScore The score returned is not the Offline one, but rather the last value from the server.
Is there any way to fix this? Any workaround?
I think it's way worse than that: according to my tests, getRawScore() (or any other methods like getRank(), ...) return only the up-to-date data if you displayed the corresponding leaderboard with the default intent. If you never did, you won't even get a value.
See my post here: Play games loadLeaderboardMetadata() returns outdated data
[Update] Apparently, you can use the loadCurrentPlayerLeaderboardScore instead of the loadLeaderboardMetadata method. That one doesn't seem to return outdated data. Check it here
I am trying to implement the stream (news feed) paging function to my app, but it does not work as expected. I found many similar questions here but there are no solutions to solve this problem.
I tried both Graph API and FQL and the behavior was similar. It succeeds to get the result one or two times but after that, it fails to get the result (gets the empty JSON array).
Finally, I found this problem depends on access_token. If I just change the source code to use Android SDK Stream Example App ID rather than my own App ID for authentication, it works perfectly.
So, I believe the Facebook server checks the App ID and returns some weird or restricted access_token to my app.
Are there any condition to get the valid access_token? I tried the exact same permissions with Android SDK Stream example app, but it could not solve the problem.
Will changing the App ID (to get the valid access_token) solve the case?
Verify your app has the read_stream permission. Without it you will not get any non-public objects.
There also seems to be some general LIMIT OFFSET issues with FQL and stream. See Facebook FQL stream limit? and http://developers.facebook.com/bugs/303076713093995.
Try using the SDK on Facebook. Then get the access token.
Use the Facebook SDK for Android. It can be found here. There are getter and setter methods to get and set the access token. The first time you do a single sign-on (SSO), you must save the access token in SharedPreferences and there's no need to reauthenticate again and again.
Just set the access token from your preferences and make a call to the feed dialog. The offline_access permission is to be deprecated. The Facebook SDK for Android does the rest of the work. Just supply sufficient parameters through Bundle.
A couple of things on Android:
get right permissions "read_stream"
Use the android SDK
Check the sample that came w/ android. In the onCreate(), I authenticate Facebook object
this.facebook.authorize(this, new DialogListener() {....}
Test using Facebook's Graph API Explorer.
If you paste in some code I can help you debug further.
The access token returned by Facebook server is valid only for a particular period of time. After which you need to refresh your access token, which is a tedious job.
So, in order to avoid this and maintain your token, you need to add the permission "offline_access" to your permission list. This is the approach used by almost Facebook-related apps.