Android oAuth Refresh Token returns null - android

I've been trying to figure this out for awhile now, cant seem to get with anything I've tried.
I cant seem to retrieve the refresh token, it would come out as blank.
public class oaUTH extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... unused) {
try {
JsonFactory jsonFactory = new JacksonFactory();
HttpTransport transport = new NetHttpTransport();
CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
AccessTokenResponse accessTokenResponse = credentialStore.read();
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessTokenResponse.accessToken,
transport,
jsonFactory,
OAuth2ClientCredentials.CLIENT_ID,
OAuth2ClientCredentials.CLIENT_SECRET,
accessTokenResponse.refreshToken+"&access_type=offline");
final Latitude latitude = new Latitude(transport, accessProtectedResource, jsonFactory);
latitude.apiKey=OAuth2ClientCredentials.API_KEY;
Log.i("AGENTPORTAL", "Access Token = " + accessTokenResponse.accessToken + ", Expires in = " + accessTokenResponse.expiresIn + ", Refresh Token = " + accessTokenResponse.refreshToken + ", Scope = " + accessTokenResponse.scope);
LatitudeCurrentlocationResourceJson currentLocation = latitude.currentLocation.get().execute();
String locationAsString = convertLocationToString(currentLocation);
Log.i("TAG", locationAsString);
//textView.setText(locationAsString);
} catch (Exception ex) {
ex.printStackTrace();
//textView.setText("Error occured : " + ex.getMessage());
startActivity(new Intent().setClass(getApplicationContext(),OAuthAccessTokenActivity.class));
}
Here is the log: Access Token = **AHES6ZTeqgwdxjll6Gb4Cf9I0_n5bO_OdgR2OR**WLPCPzJ5xtO5M, Expires in = 3599, Refresh Token = , Scope =
Any idea where refresh token = " " ? I've added "&access_type=offline" but still no luck. Any help is deeply appreciated!

I just figured out how to get the refresh token, I'll tell you what I did just in case someone ever runs into the same problem...
String authorizationUrl = new GoogleAuthorizationRequestUrl(
OAuth2ClientCredentials.CLIENT_ID,
OAuth2ClientCredentials.REDIRECT_URI,
OAuth2ClientCredentials.SCOPE).build();
That piece of code is what is first called to start the whole authorization process. Whats missing in it is what several people here on SO had suggested, you need to include "access_type=offline&approval_prompt=force" in the URL link.
To make it work, I simply changed the authorizationUrl to
String authorizationUrl = "https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&client_id=" + OAuth2ClientCredentials.CLIENT_ID + "&redirect_uri=" + OAuth2ClientCredentials.REDIRECT_URI + "&response_type=code&scope=" + OAuth2ClientCredentials.SCOPE

Related

Intent failed with Canceled on SpeechFactory.fromSubscription (LUIS azure, android sdk)

I am getting the following message when trying to analyze an utterance with LUIS using the cognitive service android SDK:
Final result received: Intent failed with Canceled. Did you enter your Language Understanding subscription? WebSocket Upgrade failed with an authentication error (403). Please check the subscription key or the authorization token, and the region name., intent:
I am able to get an utterance evaluation via REST using the same Subscription key , and App ID passed to the SpeechFactory methods.
Moreover, continuous recognition through the Android SDK works as well.
Anyone is getting my same issue ?
source available at https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/samples/java/android/sdkdemo/app/src/main/java/com/microsoft/cognitiveservices/speech/samples/sdkdemo/MainActivity.java .
Code here:
recognizeIntentButton.setOnClickListener(view -> {
final String logTag = "intent";
final ArrayList<String> content = new ArrayList<>();
disableButtons();
clearTextBox();
content.add("");
content.add("");
try {
final SpeechFactory intentFactory = SpeechFactory.fromSubscription(LanguageUnderstandingSubscriptionKey, LanguageUnderstandingServiceRegion);
final IntentRecognizer reco = intentFactory.createIntentRecognizerWithStream(createMicrophoneStream());
LanguageUnderstandingModel intentModel = LanguageUnderstandingModel.fromAppId(LanguageUnderstandingAppId);
for (Map.Entry<String, String> entry : intentIdMap.entrySet()) {
reco.addIntent(entry.getKey(), intentModel, entry.getValue());
}
reco.IntermediateResultReceived.addEventListener((o, intentRecognitionResultEventArgs) -> {
final String s = intentRecognitionResultEventArgs.getResult().getText();
Log.i(logTag, "Intermediate result received: " + s);
content.set(0, s);
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
});
final Future<IntentRecognitionResult> task = reco.recognizeAsync();
setOnTaskCompletedListener(task, result -> {
Log.i(logTag, "Continuous recognition stopped.");
String s = result.getText();
if (result.getReason() != RecognitionStatus.Recognized) {
s = "Intent failed with " + result.getReason() + ". Did you enter your Language Understanding subscription?" + System.lineSeparator() + result.getErrorDetails();
}
String intentId = result.getIntentId();
String intent = "";
if (intentIdMap.containsKey(intentId)) {
intent = intentIdMap.get(intentId);
}
Log.i(logTag, "Final result received: " + s + ", intent: " + intent);
content.set(0, s);
content.set(1, " [intent: " + intent + "]");
setRecognizedText(TextUtils.join(System.lineSeparator(), content));
enableButtons();
});
} catch (Exception ex) {
System.out.println(ex.getMessage());
displayException(ex);
}
});
}

Google Fit Session title not "sticking"

My Referee watch creates a Google Fit Session using the following code:
private void insertFitSession(final Game currentGame, final Period period,
final long periodStartTime, final long periodEndTime) {
//add the detailed Sensor data (using History API) if available
boolean activityWasInserted = false;
if (!RefWatchUtil.isRefWatchFree()) {
//If there are speeds then we will insert an activity
//4.5.09: Unfortunately mFitnessDataSets[] can have leftover data from a period where you did track fitness
//So we had to replace with period-by-period dataSets
activityWasInserted = (period.getFitnessDataSet(SPEED_LISTENER_IDX) != null)
&& !period.getFitnessDataSet(SPEED_LISTENER_IDX).isEmpty();
}
//create a Session in Google Fit for the period that just completed
//(this happens even for Free)
try {
String sessionBaseName = currentGame.getTitle();
if (sessionBaseName.isEmpty()) sessionBaseName = currentGame.getLocation();
if (sessionBaseName.isEmpty()) sessionBaseName = RefWatchUtil.timeMillisToDefaultShortDateTime(currentGame.getStartTimeMillis());
final String sessionName = sessionBaseName + ": " + String.format(getResources().getString(R.string.fitness_period_label), period.getPeriodNum());
final Session.Builder fitnessSessionBuilder = new Session.Builder();
fitnessSessionBuilder
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getDescription())
.setStartTime(periodStartTime, TimeUnit.MILLISECONDS)
.setEndTime(periodEndTime, TimeUnit.MILLISECONDS);
//If we're Free, then we don't have real fitness session data and just guess at Jogging
// (also if we have no Activity data in Pro)
if (RefWatchUtil.isRefWatchFree() || !activityWasInserted) {
fitnessSessionBuilder.setActivity(FitnessActivities.RUNNING_JOGGING);
}
final Session fitSession = fitnessSessionBuilder.build();
SessionInsertRequest insertRequest = new SessionInsertRequest.Builder()
.setSession(fitSession)
.build();
Fitness.SessionsApi.insertSession(mFitnessApiClient, insertRequest)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "Successfully inserted Session " + sessionName);
} else {
Log.d(TAG, "There was a problem inserting the session " + sessionName
+ ": " + status.getStatusCode() + " " + status.getStatusMessage());
}
}
});
} catch (RuntimeException e){
Log.e(TAG, "There was a runtime exception inserting the session: " + e.getLocalizedMessage());
}
}
Note the sessionName defaults to either Title, Location, or Time appended with the current Period. This has been working great.
Recently (last month or so?) the Fit session is correctly inserted (I can track it in the log) but the Name doesn't stick. Instead I get "25 min running" for some, but not all, of them.
Has anybody else experienced this type of override by Fit?

Possible race condition or programmer error in Google Fitness startSession

I am attempting to record Google Fit Sessions for periods in sports activity in my Referee Watch. I start a session at the beginning of a period and then stop it at the end of the period.
I sometimes get an interesting exception when I start a Fitness session using this code:
private Session startFitSession(final Game currentGame) {
final Session fitSession;
try {
String sessionBaseName = currentGame.getGameTitle();
if (sessionBaseName.isEmpty()) sessionBaseName = currentGame.getGameLocation();
if (sessionBaseName.isEmpty()) sessionBaseName = RefWatchUtil.timeMsToString(currentGame.getActualStartMs(),RefWatchUtil.dateTimeFormatStart);
final String sessionName = sessionBaseName + ": "
+ String.format(getResources().getString(R.string.fitness_period_label),mCurrentPeriod);
//use this to try to avoid error message about creating a session in the future
final long startTime = System.currentTimeMillis()-TimeUnit.SECONDS.toMillis(10);
fitSession = new Session.Builder()
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getGameDescription())
.setStartTime(startTime, TimeUnit.MILLISECONDS)
.setActivity(FitnessActivities.RUNNING_JOGGING)
.build();
Fitness.SessionsApi.startSession(mGoogleApiClient, fitSession)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Successfully started Session " + sessionName);
} else {
Log.i(TAG, "There was a problem starting the session " + sessionName
+ ": " + status.getStatusMessage());
}
}
});
} catch (RuntimeException e){
Log.i(TAG, "There was a runtime exception starting the session: " + e.getLocalizedMessage());
return null;
}
return fitSession;
}
The exception is:
There was a runtime exception starting the session: Cannot start a session in the future
So it occurred to me that perhaps Session.Builder() looks at the "present" as when the new Builder() call, so I changed to the following code:
...
final long startTime = System.currentTimeMillis();
fitSession = new Session.Builder()
.setName(sessionName)
.setIdentifier(sessionName)
.setDescription(mCurrentGame.getGameDescription())
.setStartTime(startTime, TimeUnit.MILLISECONDS)
...
Same error.
So now I subtract an arbitrary 10 seconds from the startTime and that seems to have fixed the problem.
But (a) is there a better way of making this call (afaict, you can't call setStartTime with a 0 argument to get "current time") and (b) is this a common pattern for Builder type calls?

Get email of an account using google plus and how to check the session while logging using OAuth

I am using webview to authenticate the user using this https://github.com/imellon/Google-Plus-Android-Sample/blob/master/src/com/imellon/android/googleplus/OAuthActivity.java to access my app and after he his succesfully authorized I need to get the user email.
I couldn't find out the way to get the email.
This is what I have now:
private void retrieveProfile() {
try {
JsonFactory jsonFactory = new JacksonFactory();
HttpTransport transport = new NetHttpTransport();
SharedPreferencesCredentialStore credentialStore = SharedPreferencesCredentialStore
.getInstance(prefs);
AccessTokenResponse accessTokenResponse = credentialStore.read();
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(
accessTokenResponse.accessToken, transport, jsonFactory,
SharedPreferencesCredentialStore.CLIENT_ID,
SharedPreferencesCredentialStore.CLIENT_SECRET,
accessTokenResponse.refreshToken);
Builder b = Plus.builder(transport, jsonFactory)
.setApplicationName("Simple-Google-Plus/1.0");
b.setHttpRequestInitializer(accessProtectedResource);
Plus plus = b.build();
profile = plus.people().get("me").execute();
updateViews();
} catch (Exception ex) {
ex.printStackTrace();
}
}
This is how I get the Id, name and url
private void updateViews() {
Drawable image = loadImage(this, profile.getImage().getUrl());
profile_photo.setImageDrawable(image);
profile_id.setText("Id: " + profile.getId());
profile_name.setText("Name: " + profile.getDisplayName());
profile_url.setText("Url: " + profile.getUrl());
}
And finally each time when he logins to my app how do I check the session ?
Any help is greatly appreciated
Use profile.getEmails() as documented in https://developers.google.com/resources/api-libraries/documentation/plus/v1/java/latest/. The result is a list of type java.util.List<Person.Emails>.
You need to make sure your client asked for the scope plus.profile.emails.read to allow your client to retrieve that information.

Android: Google Data API - 401 Token Invalid Error

Well, I tried using Account Manager and I am getting "401 Token Invalid" error. What can be the reason.
Debug Log
Account name = xxxxxx#gmail.com
Token is : DQAAALIAAAAh-xxxxxxx
Starting Google DATA API loader-----------------
Inside Google Notebook loader-----------------
Setting Token : DQAAALIAAAAh-xxxxx
Url is : https://docs.google.com/feeds/default/private/full
Exception getting docs feed : 401 Token invalid
Done Google DATA API loader-----------------
Sample Code:
Log.d("Main","\tInside GoogleDATA API -----------------");
HttpTransport transport = new NetHttpTransport();
GoogleHeaders headers = new GoogleHeaders();
Log.d("Main","\tSetting Token : " + authToken);
headers.setGoogleLogin(authToken);
headers.gdataVersion="3.0";
transport.defaultHeaders = headers;
AtomParser parser = new AtomParser();
parser.namespaceDictionary = Namespace.DICTIONARY;
transport.addParser(parser);
try {
DocsUrl url = DocsUrl.forDefaultPrivateFull();
DocumentListFeed feed = DocumentListFeed.executeGet(transport,url);
List<DocumentListEntry> docs = feed.docs;
Log.d("Main","\tDocs count = " + docs.size());
for (Iterator iterator = docs.iterator(); iterator.hasNext();) {
DocumentListEntry documentListEntry = (DocumentListEntry) iterator
.next();
Log.d("Main","\t\tDocument title is : " + documentListEntry.title);
}
} catch (IOException e) {
Log.d("Main","Exception getting docs feed : " + e.getMessage());
//handleException(e);
}
Log.d("Main","\tDone GoogleDATA API -----------------");
you should see how it works on this website http://n01se.net/gmapez/start.html

Categories

Resources