I've just started out and I'm following this tutorial
https://www.dropbox.com/developers/documentation/java#tutorial
But there's no login. Nothing asks you for a username, password. That means I can't actually get a GUI that every app with "Share to Dropbox" option has.
Am I stuck with one account? Do I have to find a way to get a person's ACCESS_TOKEN or is there a more elegant GUI solution out there(like with Google Drive and their intentsenders)?
To use the Dropbox API v2 in Android, you should use the API v2 Java SDK. There's an example Android app that uses it included with the SDK. You should refer to that as an example of how to implement the app authorization flow, which is accomplished via OAuth 2. That requires the user to authorize your app with Dropbox, by signing in to Dropbox if necessary. After that, your app can store and re-use the resulting access token for that user, as the example does here.
Implementing it that way allows any user to connect their Dropbox account to your app. You can also handle multiple accounts per instance of your app if you want.
Unfortunately, there isn't much out there in terms of documentation for this flow. Here is how I was able to successfully authenticate users. First, you want to launch the authentication flow with Dropbox's auth activity:
import com.dropbox.core.android.Auth
....
Auth.startOAuth2Authentication(context, context.getString(R.string.dbx_api_app_key))
After a user has successfully authenticated, call the following method in the onResume method of the activity you started the Dropbox activity from:
#Override
public void onResume() {
super.onResume();
String token = Auth.getOAuth2Token()
}
The token that you receive here should be used when you create your instance of the DbxClientV2 like so:
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder(MyUtils.getVersionText(context))
.withHttpRequestor(OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient()))
.build()
DbxClientV2 dbxClient = DbxClientV2(requestConfig, accessToken)
You'll also need the following dependencies in your build.gradle file:
implementation 'com.squareup.okhttp:okhttp:2.7.5'
implementation 'com.squareup.okhttp3:okhttp:3.7.0'
Related
For example, user is navigating to google.com in WebView.
Is it possible to authorize him there via Google Account Picker (something like described here https://developers.google.com/android/guides/http-auth) to simplify authorization instead of manually logging in via web form?
Android Web browsers (for example, Google Chrome) are authorizing user via this method).
Part I: Using the Google Plus Services API
If I understand your question correctly, you may be able to achieve what you are trying to do using the Google Plus Services API.
You create your GoogleSignInOptions and then create your GoogleApiClient using these sign-in options. From there, you use the Auth.GoogleSignInApi.getSignInIntent with your GoogleApiClient as the parameter.
This intent should launch a SignInIntent that presents the Google account picker (that will include accounts that have been accessed on the device previously, and the ability to add another account).
Once you get back the GoogleSignInResult, you can verify that the user was authenticated and then create the authentication flow as you would otherwise.
Even included in the Android SDK is the Google SignInButton, which you can use right in your layout instead of having to create a custom button for the sign-in.
Part II: Using WebViewClient
Now, if you are trying to use a WebView to authenticate them, your best bet is to extend the WebViewClient class.
Things you will need: clientId, clientSecret, and clientScope (all of these details will be given for you when you create your application in the Google Developer Console)
First things first, your URL to authorize will probably be as follows: https://accounts.google.com/o/oauth2/auth?response_type=code&clientId={your client id}&state={SOMESTATEINFO}&access_type=offline (access type if you want offline access). This should be the initial URL of your WebView
Next, you will want to modify your extended WebViewClient class. What you will want to do is override the shouldOverrideUrlLoading(WebView webView, String url) method to listen for your redirectURL. Probably the easiest thing to do is to use url.startsWith(<your redirect URL>) to detect this. You can then parse the response. If your response contains error, then it means something went wrong. Otherwise, you should get back two fields in the URL: code and state. If you do not get error back, then return true for shouldOverrideUrlLoading.
Once you get your code, you can create a new GoogleAuthorizationCodeFlow, using your client, scopes, and secrets.
Once you have your flow, you will need a GoogleTokenResponse, which you will be able to get using the code obtained above for your authorization code, using GoogleTokenResponse response = flow.newTokenResponse(<code>).setRedirectUri(<redirectUri>).execute().
Once you have done this, and you have your response, you can get your Credential using flow.createAndStoreCredential(response, null).
And voila, using this Credential, you can authenticate your calls.
Caveats I have not been able to get the WebView to recognize accounts that have been signed into on other web browsers, so the account picker may only show the accounts that have been signed into on the app-specific WebView.
tl;dr It is possible to do this with a WebView and WebViewClient, but it's messy and a little bit more roundabout than using the Google Plus Services API.
This example better illustrates the authorization flow/credential stuff once you get the authorization code and such.
And here's some documentation on the WebViewClient that may be useful as well.
Hope this helps point you in the right direction!
I'm searching the PlayServices equivalent of this call:
https://www.googleapis.com/plus/v1/people/<some_user_id>?key=<your_api_key>
The call above is documentation of the call above is here: https://developers.google.com/+/web/api/rest/latest/people/get
However this is a web API call and my keys are restricted to a limited set of IPs. I think it would be a bad idea to put that key in code. Do you think the same?
Just as a side note I would like get the data without "authorization". I mean I authenticate with my key, but I don't want to ask the user. With the HTTP call above this is possible, so what is the Android SDK equivalent? I'm not asking how to do the GoogleApiClient stuff I have this already working. I just want to know the right call of the plus API.
If there is nothing similar do you know how to authenticate myself at the rest service with my packagename and signature?
In summary I just want to know the (first and last) name of the local G+ accounts like in the Google Foto app.
To load a specific Google+ profile in Android use the load method for com.google.android.gms.plus.People.
public abstract PendingResult<People.LoadPeopleResult> load (GoogleApiClient googleApiClient, String... personIds)
Trying to integrate Facebook Android SDK 4.0 via a sample app.
Questions:
How can we check if the app has been de-authorized by the user in the app dashboard. Tried using the AccessTokenTracker in the new SDK documentation, but that doesn't seems to be getting called upon when i de-authorize the app.
The AccessTokenTracker is only called when i login or change the password on the account. Is there any other class for checking the de-authorization of an app?
The sample app: https://github.com/facebook/facebook-android-sdk/blob/b384c0655fe96db71229bfdcb981a522f3f1e675/samples/Scrumptious/src/com/facebook/scrumptious/MainActivity.java
Where exactly is the AccessToken stored in our app?
The documentation on the developer.facebook is real poor as of now.
I only want to use the SDK. I don't intend to use the Graph API along with that.
Any ideas is appreciated.
Thanks!
1) You won't get a call on the client when the user de-auths your app. What will happen is when you do a call, it will fail. The GraphResponse's getError will be not null. In this case, the FacebookRequestError's category is LOGIN_RECOVERABLE, as you need to take the user to the login flow again. You can call one of these methods to start that process with the response you received: https://github.com/facebook/facebook-android-sdk/blob/b384c0655fe96db71229bfdcb981a522f3f1e675/facebook/src/com/facebook/login/LoginManager.java#L96-L115
2) The access token is stored in your application's shared preferences under the key com.facebook.AccessTokenManager.CachedAccessToken
I have folowing scenario.
My client (local tv publisher) publishes some article and embeds tweet in it. ID of embeded tweet is sent through api to android application.
On android side i have integrated Fabric/TwitterKit and by following steps on twitter developers page i managed to show tweet in my android app on (i admit) easy way (Show tweet exp).
Now i have published application to Alpha and noticed one "little" problem :-). TwitterKit was using my local twitter account to authenticate and to show tweets. If you dont have Twitter application installed or signed out of it, my show tweet functionality wont work..
This is TwitterLogin explanation for obtaining TwitterKit auth token:
"When attempting to obtain an authentication token, the Kit will use the locally installed Twitter app to offer a single sign-on experience. If the Kit is unable to access the authentication token through the Twitter app, it falls back to using a web view to finish the OAuth process.
The simplest way to authenticate a user is using TwitterLoginButton, inside your layout..."
What i want is to simply show content of tweet by given tweetID. No sending tweets, or any other action with it. Just show data from given url. Is it possible without authentication, or what should i do now, so that current implementation works without user authentication (or with some non-single-signon-inside-app authentication)
Thank you.
UPDATE 1:
I have created MyApp extends Application class, and placed code below inside onCreate method. In application tag inside AndroidManifest file, added line:
AndroidManifest.xml
android:name=".MyApp"
onCreate:
TwitterAuthConfig authConfig =
new TwitterAuthConfig(DeveloperKey.TWITTER_CONSUMER_KEY, DeveloperKey.TWITTER_CONSUMER_SECRET_KEY);
Fabric.with(this, new TwitterCore(authConfig),
new TweetUi());
It works so far, but i am not sure if this implementations is valid.
DeveloperKey.TWITTER_CONSUMER_KEY and DeveloperKey.TWITTER_CONSUMER_SECRET_KEY are static values obtained from application created at apps.twitter.com.
You need to use Application Only authentication.
That will generate a set of keys which can be used by the application. It won't be able to post messages to Twitter (because no user is associated with it) but you will be able to read Tweets.
If you build the keys into the app, your user won't have to sign in.
All the documentation is at https://dev.twitter.com/oauth/application-only
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.