Intro:
So I use accountManager to get a token I need:
am.getAuthToken(account,
scope,
null,
this,
new OnTokenAcquired(),
new Handler(new OnError()));
When I use "View your tasks" as the scope (just like it described here) Android shows up a permission request and tells that my application is asking for "View your tasks".
But I need to use "oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile" as the scope. When I do so, Android does not replace these URLs with the human-readable descriptions I found here.
Question:
Is there anyway to force Android to replace the scope with a custom description or description defined by Google?
Is there anyway to declare a custom permission and use it in the manifest so Android will ask for user's permission (such as "View your email address" and "View basic information about your account") during the installation?
Is there any way achieve what I'm trying to achieve?
What I'm trying to achieve:
I just want to ask for the permission I need so users will be able to understand what kind of the permission I'm asking for.
Thanks.
Is there anyway to force Android to replace the scope with a custom
description or description defined by Google?
No it's not possible to use a custom description. When you use the Oauth2 scopes on Android versions lower than 4 (I think, I'm not sure about 3) the exact scope will be shown to the user instead of something more user friendly. On Android 4 and newer you will get a description instead so this description seems to be part of Android itself.
Is there any way achieve what I'm trying to achieve?
You could try to use Google play's GoogleAuthUtil instead of the account manager for this as it gives a much better user experience. For a comparison between using the account manager and GoogleAuthUtil see: In a nutshell what's the difference from using OAuth2 request getAuthToken and getToken
Related
We would like to provide a list of reference from a public sheets that everyone can view in android.
I tried the Quickstart sample from Google which works just fine.
But we would like to minimize the steps (steps like allow access to contacts, choosing google account) since this apps is designed for people who's considering suicide. The list is fill of info about where to ask for help.
I did find a article about how to read a sheet as a InputStream
I would really appreciate if there's more elegant way with Google Sheet API V4
If the Sheets are shared to "anyone with link" or "public", it might not be necessary to go through the account flow in Android. Choosing an account is mainly to get access to the right credentials, but public sheets can be read anonymously (without credentials) with the API.
If you are still looking for an answer, only a single line replacement is needed for this to work:
Credential credential = new GoogleCredential().createScoped(SCOPES);
instead of
Credential credential = authorize();
then you can remove the method authorize() and the corresponding variables
I found out there's a setKey method in com.google.api.services.sheets.v4.Sheets. For the third parameter in Builder, as credential, can be null. But will have error "Requests from this Android client application are blocked" if the Key restricted to Android.
I am currently developing an app where I have been using temboo to search a user on Facebook. I am able to get the basic results which do not need any additional permissions.
But for fields like education history, about_me etc, I need to include additional permissions to retrieve these fields.
Could you please let me know how to add these permissions to the temboo FQLinputsets?
Thanks!
I work at Temboo.
I would recommend using our OAuth Helper Choreos to go through the OAuth process, and request an additional set of permissions:
https://www.temboo.com/library/Library/Facebook/OAuth/
In the first step of the OAuth process, you'll run the InitializeOAuth choreo. This is where you can specify the permissions you need to request by passing a comma-separated list of permissions to the "Scope" input. You'll want to pass user_education_history,about_me along with any other permissions you'd like to request. Here's an example of the input set:
// Set inputs
initializeOAuthInputs.set_AppID("YOUR_FACEBOOK_APP_ID");
initializeOAuthInputs.set_Scope("user_education_history,about_me");
Then you can complete the OAuth process by running the FinalizeOAuth choreo. This will return an access token that should have the permission you need to retrieve those fields.
https://www.temboo.com/library/Library/Facebook/OAuth/FinalizeOAuth/
There is a video tutorial about the OAuth Choreos here:
https://www.temboo.com/videos#oauthchoreos
Hope this helps. Let us know if you have any other questions.
Cormac
I want to implement Facebook login option to my app. I have gone through this getting started tutorial https://developers.facebook.com/docs/getting-started/facebook-sdk-for-android/3.0/ .
Everything works fine but I need to add permissions to ask for user to give access to his email and location.
How can I do that? I want to do that with my own custom button without using facebook sdk's LoginButton.
Are you talking about email + location on Facebook or email and location on your Android tablet.
If you're talking about FB permissions you pretty much have to use the FB SDK, and request the permissions see this list of FB permissions. FB doesn't like developers to roll their own interfaces, and will block you if you app gets popular, and you broke the TOU.
If you want to get that from Android, you'll need to add
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
to get location. You can use an Intent to send an email.
You can also reference the entire list of android permissions here
Okay, so the thing with that default style is it looks like that is only applied when you inflate the layout from XML, which is nice if you want to work around the default styles. What you could do is put a FrameLayout into your XML layout to define the bounding box for the LoginButton and then add the LoginButton programatically using the LoginButton(Context ctx, AtrributeSet attrs, int styleDef) constructor.
That solution is pretty hacky, as it requires you to put all of your styling information into a style as opposed to XML, but it should get the job done.
Edit: I also think it behooves me to echo the above poster in saying that this probably is not the best idea for a number of reasons. From a purely cosmetic perspective a lot of users have gotten used to that blue Facebook button meaning something very specific. If your app overrides that look it could end up having more negative effects on your UI than just keeping the standard FB button. Also, I haven't fully read the TOU, but it could become a violation there as well.
I'm in a situation where I need to request access tokens for two scopes (from my android application), https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.userinfo
I would like to get both permissions on a single call to getAuthToken, but can't figure out the string to pass in the authTokenType parameter. I tried several reasonable combinations with no positive results :(
Has anyone solved this issue? Is it possible?
I was having the same issue. Shah is almost right, but his scope string is wrong. It should be
"oauth2:<scope_url> <scope_url>"
not
"oauth2:<scope_url> oauth2:<scope_url>"
If you need multiple OAuth 2.0 scopes, use a space-separated list.
oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.userinfo
You asked for sample code, so have a look at the Google Docs Upload Sample application, and in this application have look at the authentication flow done in this sample Android screen (ignore that it's about Google Docs, it still authorizes first). You can get the whole application and run it in an emulator with Google APIs present or run it on your phone. The authorization workflow starts with the buttonAuthorize click, Authorize() and you are specifically interested in this method:
private void gotAccount(Account account)
{
Bundle options = new Bundle();
accountManager.getAuthToken(
account, // Account retrieved using getAccountsByType()
"oauth2:https://www.googleapis.com/auth/userinfo.email oauth2:https://www.googleapis.com/auth/userinfo.userinfo", // Auth scope
//"writely", // Auth scope, doesn't work :(
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
null); // Callback called if an error occurs
}
The user gets this access request screen:
Note that this is using the 'local' OAuth2 mechanism, not opening a web browser, but using the authentication provided when you first activated the Android phone.
Also note that the user sees the full URL of the scope instead of a friendly name, I haven't found a way around this and if you do find out it would be great if you could share the answer.
I need to fetch some data over the cloud from my app. I've watched the google IO video on RESTful android apps # http://www.youtube.com/watch?v=xHXn3Kg2IQE&t=43m58s It recommends in the final slides to use a SyncAdapter to integrate with the Android System.
Later I learned that one has to use an Account to implement SyncAdapter. My app does not use an account. Users can freely download data without registration. Can I still use SyncAdapter? Is there a stock dummy account that I could use?
Edit: I do have a content provider for my app so that's not a problem
Edit2: I've just looked at the Weather and Stock apps under Settings -> Accounts & Sync. You can see that they allow syncing, but don't have a remove account button. On the other hand, Google, Facebook and Skype apps allow syncing PLUS they have a remove account button. This means Weather and Stock don't use accounts, whereas Google, Facebook and Skype do.
The tutorials I found # http://ericmiles.wordpress.com/2010/09/22/connecting-the-dots-with-android-syncadapter/ and # http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/ say that one MUST have an account to use Sync Adapter. :S ???
As the Android Developer docs say
Even if your app doesn't use accounts, you still need to provide an authenticator component. If you don't use accounts or server login, the information handled by the authenticator is ignored, so you can provide an authenticator component that contains stub method implementations. You also need to provide a bound Service that allows the sync adapter framework to call the authenticator's methods.
There is an entire article on Creating a Stub Authenticator. I realise that this question is old and an answer was accepted long ago, but I felt that a recent addition to the official docs should be included here.
I have created a contact sync adapter where I don't have a account authorization and or configuration screens. It wasn't that hard. I don't think having to deal with the Android Account stuff was that much of a deal.
Quote from your tutorial link:
The bad news is that there is no
“stock” functionality to give you an
easy way to provide an Account to the
system. However, in the same Sync
Adapter Example that comes with the
SDK there is a lot of code you can
borrow to give you Account
functionality. Unless you desire a
custom credentials screen, you can
heist all the code in the
com.example.android.samplesync.authenticator
package with only a few minor changes.
So it's basically just a copy and paste from the example, that's pretty much what I did and it worked fine.
I don't know for sure but all the adapters that don't have "Remove Account" seems to be built-in ROM adapters on all the devices I've looked at. I'm not sure you have to worried about it.
I keep getting lots of notifications from this question, so I thought I'll share this info. This is how you add SyncAdapter without Account. You can put this in onCreate of MyApplication extends Application class. This assumes you already have a SyncAdapter and ContentProvider implemented. You can do that by following the tutorials listed in the question.
final String ACCOUNT_NAME = "MyApp";
final String ACCOUNT_TYPE = "com.myapp.account";
final String PROVIDER = "com.myapp.provider";
Account appAccount = new Account(ACCOUNT_NAME,ACCOUNT_TYPE);
AccountManager accountManager = AccountManager.get(getApplicationContext());
if (accountManager.addAccountExplicitly(appAccount, null, null)) {
ContentResolver.setIsSyncable(appAccount, PROVIDER, 1);
ContentResolver.setMasterSyncAutomatically(true);
ContentResolver.setSyncAutomatically(appAccount, PROVIDER, true);
}
res/xml/syncadapter.xml
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="#string/provider"
android:accountType="#string/account_type"
android:userVisible="true"
android:supportsUploading="true"
/>
res/xml/authenticator.xml
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="#string/account_type"
android:icon="#drawable/app_icon"
android:smallIcon="#drawable/app_icon"
android:label="#string/app_label"
/>