We have follow Scottyab Safetynet Library.
We are facing error of “Status{statusCode=NETWORK_ERROR, resolution=null}” event though 4G internet connectivity available in our android device with package name com.safetynet.sample where as sample project is working fine with package name com.scottyab.safetynet.sample. We have check this solution but not work.
Below code where we have facing this issue
private void runSafetyNetTest() {
Log.v(TAG, "running SafetyNet.API Test");
requestNonce = generateOneTimeRequestNonce();
requestTimestamp = System.currentTimeMillis();
writeLog("running SafetyNet.API Test");
SafetyNet.SafetyNetApi.attest(googleApiClient, requestNonce)
.setResultCallback(new ResultCallback<SafetyNetApi.AttestationResult>() {
#Override
public void onResult(final SafetyNetApi.AttestationResult result) {
writeLog("running SafetyNet.API Result");
//result = Status{statusCode=NETWORK_ERROR, resolution=null}
if (!validateResultStatus(result)) {
return;
}
final String jwsResult = result.getJwsResult();
final SafetyNetResponse response = parseJsonWebSignature(jwsResult);
lastResponse = response;
writeLog("Res :: " + response);
//validate payload of the response
if (validateSafetyNetResponsePayload(response)) {
if (!TextUtils.isEmpty(googleDeviceVerificationApiKey)) {
//if the api key is set, run the AndroidDeviceVerifier
AndroidDeviceVerifier androidDeviceVerifier = new AndroidDeviceVerifier(googleDeviceVerificationApiKey, jwsResult);
androidDeviceVerifier.verify(new AndroidDeviceVerifier.AndroidDeviceVerifierCallback() {
#Override
public void error(String errorMsg) {
callback.error(RESPONSE_ERROR_VALIDATING_SIGNATURE, "Response signature validation error: " + errorMsg);
}
#Override
public void success(boolean isValidSignature) {
if (isValidSignature) {
callback.success(response.isCtsProfileMatch(), response.isBasicIntegrity());
} else {
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION, "Response signature invalid");
}
}
});
} else {
Log.w(TAG, "No google Device Verification ApiKey defined");
callback.error(RESPONSE_FAILED_SIGNATURE_VALIDATION_NO_API_KEY, "No Google Device Verification ApiKey defined. Marking as failed. SafetyNet CtsProfileMatch: " + response.isCtsProfileMatch());
}
} else {
callback.error(RESPONSE_VALIDATION_FAILED, "Response payload validation failed");
}
}
}
);
}
This might be related to the fact that the attestation API has been marked as deprecated. The new one doesn't depend on the google client API, you should check this. Also Google released an example app using the new api, you can check here.
As per this discussion, the wrong API_KEY may be the reason for the error.
Related
I am using reCaptcha API on android through SafetyNet API as given on Android Developer site.
My application is multilingual application. When I all together change phones language setting, my reCaptcha appears in that language. But I want to change language according to selected locale on app level without changing phone language settings. Google docs has given language codes here. Can anyone help me with implementing this thing. Any help or any suggestion will be appreciated.
This is my current code. This works with default phone language very well. I explored available methods for specifying language but no luck.
public void verify() {
SafetyNetClient client = SafetyNet.getClient(activity);
Task<SafetyNetApi.RecaptchaTokenResponse> verifierTask = client.verifyWithRecaptcha(activity.getResources().getString(R.string.site_key));
verifierTask.addOnSuccessListener(activity, new OnSuccessListener<SafetyNetApi.RecaptchaTokenResponse>() {
#Override
public void onSuccess(SafetyNetApi.RecaptchaTokenResponse recaptchaTokenResponse) {
String userResponseToken = recaptchaTokenResponse.getTokenResult();
if (!userResponseToken.isEmpty()) {
new CaptchaVerificationTask().execute(userResponseToken);
} else {
captchaVerificationListener.onFailure();
}
}
}
).addOnFailureListener(activity, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ApiException) {
// An error occurred when communicating with the
// reCAPTCHA service. Refer to the status code to
// handle the error appropriately.
ApiException apiException = (ApiException) e;
int statusCode = apiException.getStatusCode();
Log.d("Login ReCaptcha", "Error: " + CommonStatusCodes
.getStatusCodeString(statusCode));
} else {
// A different, unknown type of error occurred.
Log.d("Login ReCaptcha", "Error: " + e.getMessage());
}
captchaVerificationListener.onFailure();
}
});
}
want to start development with AWS IOT using Android app
I am seeking for example for IOT in android. need to start basic configuration on AWS console and android app. i already tested temperature demo but didn't get any clue from that! need a basic steps on shadow, policy , role. how to configure them step by step and use of cognito.
below getshadow() method is called onCreate , need to update value on real time basis not ony onCreate.
public void getShadows() {
GetShadowTask getControlShadowTask = new GetShadowTask("TemperatureControl");
getControlShadowTask.execute();
}
private class GetShadowTask extends AsyncTask<Void, Void, AsyncTaskResult<String>> {
private final String thingName;
public GetShadowTask(String name) {
thingName = name;
}
#Override
protected AsyncTaskResult<String> doInBackground(Void... voids) {
try {
GetThingShadowRequest getThingShadowRequest = new GetThingShadowRequest()
.withThingName(thingName);
GetThingShadowResult result = iotDataClient.getThingShadow(getThingShadowRequest);
// Toast.makeText(getApplication(),result.getPayload().remaining(),Toast.LENGTH_LONG).show();
byte[] bytes = new byte[result.getPayload().remaining()];
result.getPayload().get(bytes);
String resultString = new String(bytes);
return new AsyncTaskResult<String>(resultString);
} catch (Exception e) {
Log.e("E", "getShadowTask", e);
return new AsyncTaskResult<String>(e);
}
}
#Override
protected void onPostExecute(AsyncTaskResult<String> result) {
if (result.getError() == null) {
JsonParser parser=new JsonParser();
JsonObject jsonObject= (JsonObject) parser.parse(result.getResult());
response=result.getResult();
setPoint=jsonObject.getAsJsonObject("state").getAsJsonObject("reported")
.get("current_date").getAsString();
textView.setText(setPoint);
// Toast.makeText(getApplication(),setPoint,Toast.LENGTH_LONG).show();
Log.i(GetShadowTask.class.getCanonicalName(), result.getResult());
} else {
Log.e(GetShadowTask.class.getCanonicalName(), "getShadowTask", result.getError());
Toast.makeText(getApplication(),result.getError().toString(),Toast.LENGTH_LONG).show();
}
}
}
UPDATE
Thing Shadow
{
"desired": {
"welcome": "aws-iot"
},
"reported": {
"welcome": "aws-iot",
"current_date": "06-Sep-2017 1:26:40 PM"
}
}
AWS has provided a complete Github repo of Android samples. In the samples do the PubSubWebSocket to connect, subscribe and publish the data to the shadow.
If you have a closer look into the PubSubWebSocket example you will find a detailed information on how to to make a thing policy and role. It cannot be more concise and clear than that.
For understanding and using Cognito follow AmazonCognitoAuthDemo example to make the identity pool and use it in the PubSubWebSocket example.
To get a better understanding of roles and Cognito. Please read the AWS documentation.
Update:
In the IoT thing policy did you give appropriate permissions to connect, subscribe and publish. The option can be found in AWS IoT->Security->Policy->Create Policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iot:*",
"Resource": "arn:aws:iot:us-east-2:293751794947:topic/replaceWithATopic"
}
]
}
The above policy gives all access to the user. Also, make sure your pool which you created is for unauthenticated users.
To get the changes to the shadow type the following in the sample android(WebSocketAwsPubSub) edit box $aws/things/thing_name/shadow/update/accepted
And to publish the data to the shadow type $aws/things/thing_name/shadow/update
Update 2:
Android Code where you will receive the reported messaged. Its suscribing to the device. Its the copy of the snippet from PubSubWebSocketSample.
public void AwsSubscribe(){
final String topic = "$aws/things/D1/shadow/update/accepted";
Log.d(LOG_TAG, "topic = " + topic);
try {
mqttManager.subscribeToTopic(topic, AWSIotMqttQos.QOS0,
new AWSIotMqttNewMessageCallback() {
#Override
public void onMessageArrived(final String topic, final byte[] data) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
String message = new String(data, "UTF-8");
Log.d(LOG_TAG, "Message arrived:");
Log.d(LOG_TAG, " Topic: " + topic);
Log.d(LOG_TAG, " Message: " + message);
tvLastMessage.setText(message);
} catch (UnsupportedEncodingException e) {
Log.e(LOG_TAG, "Message encoding error.", e);
}
}
});
}
});
} catch (Exception e) {
Log.e(LOG_TAG, "Subscription error.", e);
}
}
If you want to create a topic, just change the value of this variable final String topic = "YOUR TOPIC" then subscribe to it by using the sample code.
Implement TrueCaller SDK in my app but returns the 'trueError.getErrorType() 3' 'onFailureProfileShared()'. I have also add
#Override
public void onSuccesProfileShared(#NonNull final TrueProfile trueProfile) {
final String fullName = trueProfile.firstName + " " + trueProfile.lastName;
mProfileName.setText(fullName);
mProfilePhone.setText(trueProfile.phoneNumber);
mProfileEmail.setText(trueProfile.email);
mProfileAddress.setText(trueProfile.city);
final List<String> jobComponents = new ArrayList<>(2);
if (!TextUtils.isEmpty(trueProfile.jobTitle)) {
jobComponents.add(trueProfile.jobTitle);
}
if (!TextUtils.isEmpty(trueProfile.companyName)) {
jobComponents.add(trueProfile.companyName);
}
mProfileJob.setText(TextUtils.join(" # ", jobComponents));
if (mTruecallerRequestNonce.equals(trueProfile.requestNonce)) {
Toast.makeText(this, "The request nonce matches", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailureProfileShared(#NonNull final TrueError trueError) {
Toast.makeText(this, "Failed sharing - Reason: " + trueError.getErrorType(), Toast.LENGTH_LONG).show();
}
android:value="YOUR_PARTNER_KEY_HERE"/>
my app AndroidManifest.xml.
AND also unable to delete or edit previous App credential from https://developer.truecaller.com/dashboard/applications , documentation not provide in truecaller developer site.
I am trying to use 'Authenticate using Cognito-Identity with Cognito user pool' in my Android application. My Cognito user pool authentication works well, when I run that separately and I had seen a JWTToken as well. When I run the the 'PubSub' sample application with Unauthenticated role, it worked as expected. When I integrate these two features in one application, the application threw following error.
W/System.err: MqttException (0) - java.io.IOException: Already connected
W/System.err: at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
W/System.err: at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:664)
W/System.err: at java.lang.Thread.run(Thread.java:761)
W/System.err: Caused by: java.io.IOException: Already connected
W/System.err: at java.io.PipedOutputStream.connect(PipedOutputStream.java:100)
W/System.err: at java.io.PipedInputStream.connect(PipedInputStream.java:195)
W/System.err: at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketReceiver.<init>(WebSocketReceiver.java:42)
W/System.err: at org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketSecureNetworkModule.start(WebSocketSecureNetworkModule.java:78)
W/System.err: at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650)
W/System.err: ... 1 more
I have been trying to resolve this issue since last Thursday and still stuck at the same place. Really No idea where should i check.!
I am adding my Authentication(Cognito user pool authentication) activity and Connect activity.
AmazonCognitoIdentityProviderClient identityProviderClient = new
AmazonCognitoIdentityProviderClient(new AnonymousAWSCredentials(), new ClientConfiguration());
identityProviderClient.setRegion(Region.getRegion(Regions.US_WEST_2));
CognitoUserPool userPool = new CognitoUserPool(getApplicationContext(), "us-west-2_ghtcc6ho9", "4t0mk45hNso69dp2j4jvel5ghm", "1jmq0lhhq721oif9k6nug31c29i760vihua8hvrgu5umfr2a1vd7", identityProviderClient);
cogUser = userPool.getUser();
authenticationHandler = new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
String ids = userSession.getIdToken().getJWTToken();
Log.d("MyToken","session id___"+userSession.getIdToken().getExpiration()+"___"+userSession.getIdToken().getIssuedAt());
Intent pubSub = new Intent(MainActivity.this, PubSubActivity.class);
pubSub.putExtra("token",""+ids);
startActivity(pubSub);
//MainActivity.this.finish();
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {
Log.d("MyToken","getAuthenticationDetails");
AuthenticationDetails authenticationDetails = new AuthenticationDetails("shone", "172737", null);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
// Allow the sign-in to continue
authenticationContinuation.continueTask();
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
Log.d("MyToken","getMFACode");
multiFactorAuthenticationContinuation.continueTask();
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
Log.d("MyToken","authenticationChallenge"+continuation.getChallengeName());
newPasswordContinuation.continueTask();
}
#Override
public void onFailure(Exception exception) {
exception.printStackTrace();
Log.d("MyToken","onFailure");
}
};
cogUser.getSessionInBackground(authenticationHandler);
When It reaches 'OnSuccess' I am launching my connect activity and passing my session token along with the Intent. Moving to the next activity
private static final String COGNITO_POOL_ID = "us-west-2:a153a090-508c-44c0-a9dd-efd450298c4b";
private static final Regions MY_REGION = Regions.US_WEST_2;
AWSIotMqttManager mqttManager;
String clientId;
AWSCredentials awsCredentials;
CognitoCachingCredentialsProvider credentialsProvider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
if(null == intent){
Toast.makeText(getApplicationContext(), "Token is null", Toast.LENGTH_SHORT).show();
}else {
token = intent.getStringExtra("token");
}
clientId = UUID.randomUUID().toString();
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
COGNITO_POOL_ID,
MY_REGION
);
mqttManager = new AWSIotMqttManager(clientId, CUSTOMER_SPECIFIC_ENDPOINT);
Map loginsMap = new HashMap();
loginsMap.put("cognito-idp.us-west-2.amazonaws.com/us-west-2_ghtcc6ho9", token);
credentialsProvider.setLogins(loginsMap);
Log.d("SESSION_ID", ""+token);
new Thread(new Runnable() {
#Override
public void run() {
credentialsProvider.refresh();
awsCredentials = credentialsProvider.getCredentials();
Log.d("SESSION_ID B: ", ""+awsCredentials.getAWSAccessKeyId());
Log.d("SESSION_ID C: ", ""+awsCredentials.getAWSSecretKey());
}
}).start();
}
View.OnClickListener connectClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(LOG_TAG, "clientId = " + clientId);
try {
mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status)+"______"+((null !=throwable)?throwable.getMessage():""));
runOnUiThread(new Runnable() {
#Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
tvStatus.setText("Connecting...");
} else if (status == AWSIotMqttClientStatus.Connected) {
tvStatus.setText("Connected");
} else if (status == AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
}
tvStatus.setText("Reconnecting");
} else if (status == AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.", throwable);
throwable.printStackTrace();
}
tvStatus.setText("Disconnected");
} else {
tvStatus.setText("Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
}
}
};
What is wrong in my code? Why it throws exception when the MQTT connect is being invoked? Any help would be appreciated.
I beat my head up with this almost a week.
Full course of action ->
After succesfull login you will have a jwt token
String idToken = cognitoUserSession.getIdToken().getJWTToken();
put it into a map
Map<String, String> logins = new HashMap<String, String>();
//fill it with Cognito User token
logins.put("cognito-idp.<REGION>.amazonaws.com/<COGNITO_USER_POOL_ID>", idToken);
then use it to set in two places (not stated in any documentation!)
CognitoCachingCredentialsProvider credentialsProvider = new
CognitoCachingCredentialsProvider(context, IDENTITY_POOL_ID, REGION);
credentialsProvider.setLogins(logins);
and
AmazonCognitoIdentity cognitoIdentity = new AmazonCognitoIdentityClient(credentialsProvider);
GetIdRequest getIdReq = new GetIdRequest();
getIdReq.setLogins(logins); //or if you have already set provider logins just use credentialsProvider.getLogins()
getIdReq.setIdentityPoolId(COGNITO_POOL_ID);
GetIdResult getIdRes = cognitoIdentity.getId(getIdReq);
after that you still nedd to make some call
AttachPrincipalPolicyRequest attachPolicyReq = new AttachPrincipalPolicyRequest(); //in docs it called AttachPolicyRequest but it`s wrong
attachPolicyReq.setPolicyName("allAllowed"); //name of your IOTAWS policy
attachPolicyReq.setPrincipal(getIdRes.getIdentityId());
new AWSIotClient(credentialsProvider).attachPrincipalPolicy(attachPolicyReq);
and only after that you can enable connect button and continue like that
mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {
Really for this small piece of code i spent a lot of time...
I was also getting same error -
Feb 27, 2019 10:23:09 AM com.amazonaws.services.iot.client.mqtt.AwsIotMqttConnectionListener onFailure
WARNING: Connect request failure
MqttException (0) - java.io.IOException: Already connected
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:38)
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:664)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Already connected
at java.io.PipedOutputStream.connect(PipedOutputStream.java:100)
but the problem was different.
First of all, you do not need to call attachPrincipalPolicy from code. You can use the command line as well. You can do something like -
aws iot attach-principal-policy --principal us-east-1:1c973d17-98e6-4df6-86bf-d5cedc1fbc0d --policy-name "thingpolicy" --region us-east-1 --profile osfg
You will get the principal ID from identity browser of your identity pool. Now lets come to the error -
To successfully connect to mqtt with authenticated Cognito credentials, you need 2 correct policies -
Authenticated role corresponding to your identity pool should allow all mqtt operations.
AWS IoT policy should allow the same operations and you need to associate your cognito identity with this policy. We use attachPrincipalPolicy to do so.
If anyone step is missed we get above error. I agree the error is misleading - Already connected makes no sense to me for this. I would normally think it has to do with clientId, which should be unique. But anyways hopefully AWS folks would make this better at some point.
For my particular case issue was point 1. Though my IoT policy had all the required permissions, the auth role corresponding to the identity pool did not. So make sure you do that.
I have created a youtube video to show this as well: https://www.youtube.com/watch?v=j2KJVHGHaFc
When a client connected to broker it has a unique client ID. If clients tried to connect with same client id then this error occur. Use different client IDs like foo1, foo2, foo3, etc.
Im triying to authenticate with google, I´m currently using the way i´t is recomended on his documentation, but.. is there any EASY way to get the refresh token?, I make the auth and get the token, but it have been impossible for me to take the refresh token , and I need id.
I have tried lots of ways, I have spend more than a week with this issue, is it possible to get that token? I´ve tried with lots of manuals, tutorials... but I can´t.
Anyone Knows any place where I can Know how to get the resfresh_token and it is good explained and that is currently working?.
Thanks a lot!!
Pd: is a native android App.
EDIT:
Ok, for More info, I´m making the auth as is in google´s documentation to auth with GoogleApiClient with little variations( because I´m using it as a cain of manager) . THIS PART RUN´S OK:
Firs instead of calling on create I call:
public void logginGooglePlus(GooglePlusAuthCallback googlePlusAuthCallback) {
gPAuthCallback = googlePlusAuthCallback;
// Initializing google plus api client
String scope = "audience:server:client_id:" + SERVER_CLIENT_ID;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
mGoogleApiClient.connect();
mSignInClicked = true;
signInWithGplus(gPAuthCallback);
}
I continue just with copy&paste with the google´s:
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
// GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
// this,
// 0).show();
if (gPAuthCallback != null) {
gPAuthCallback.onLoginError(result.toString());
}
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
public void onActivityResult(int requestCode, int responseCode,
Intent intent) {
super.onActivityResult(requestCode, responseCode, intent);
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
// Get user's information
if (gPAuthCallback != null) {
gPAuthCallback.onLoginSuccesful();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
/**
* Sign-in into google
* */
public void signInWithGplus(GooglePlusAuthCallback googlePlusAuthCallback) {
gPAuthCallback = googlePlusAuthCallback;
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
And finally I call to get the persons data:
public void getProfileInformation(
GooglePlusGetPersonCallback getPersonCallback) {
this.googlePlusGetPersonCallback = getPersonCallback;
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e("GPlus", "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
new getTokenAsyncTask().execute();
}
} catch (Exception e) {
if (googlePlusGetPersonCallback != null) {
// googlePlusGetPersonCallback.ongeGooglePersonError(e.getCause()
// .toString());
}
e.printStackTrace();
}
}
Ok, leaving here is easy, now It starts the funny part: I need the Refresh Token because I have to sign in with a server, and I have to pass the access_token, refresh_token and user_id.
reading this: https://developers.google.com/accounts/docs/CrossClientAuth
I understand that I have to make the getToken call with a different Scope, so I change it: the method for get token is :
// GET TOKEN 2o plano
public class getTokenAsyncTask extends AsyncTask<Void, Boolean, String> {
#Override
protected String doInBackground(Void... params) {
try {
String acountname = Plus.AccountApi
.getAccountName(mGoogleApiClient);
// agregamos el scope del server para que me loguee para la app
// "crossclient"
String serverScope = "audience:server:client_id:"
+ SERVER_CLIENT_ID;
String token = GoogleAuthUtil.getToken(GooglePlusManager.this,
acountname, serverScope);
return token;
} catch (UserRecoverableAuthException e) {
// startActivityForResult(e.getIntent(), "NECESITA AUT");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace(); // TODO: handle the exception
}
return null;
}
#Override
protected void onPostExecute(String code) {
String token = code;
if (googlePlusGetPersonCallback != null) {
googlePlusGetPersonCallback.ongeGooglePersonSuccesful(
currentPerson, token);
}
}
}
According to documentation, with this I´ll get a token that: "The ID token will contain several data fields", and I´m only retrieving a string token ( but it does not give any crash or issue so I suppose it is Ok). I haven´t got access to the Server, but I´ve suppose that it is ok, because the ios app is running ok already ( another company have done it in Ios), do I have to ask them to make in the server any thing so I can authenticate my android app with the server?
The ios app is passing to the server the parameter I´ve already said (acces, refres, id) So I Imagine that I have to pass the same in android, I have acces to the console and I have declared the android app in the same project.
well, from the part I am, that I have an supposed valid token.. how can I get the refresh token? I´m completely lost...
If anyone knows how to get it.. I´ll invite as much beer as you can ( I have lost so many hours with this :S ).
xcuses for the really really big post :( ( it´s my first one!).
According to the google documentation you can exchange tokens.
So, if you post required parameters to below link, then you will obtain a refresh token
https://www.googleapis.com/oauth2/v3/token
Parameters,
var params = {
code: 'FROM ANDROID [ONE TIME CODE]',
client_id: 'FROM YOUR GOOGLE CONSOLE',
client_secret: 'FROM YOUR GOOGLE CONSOLE',
redirect_uri: 'FROM YOUR GOOGLE CONSOLE',
grant_type: 'authorization_code'
access_type:'offline'
};
The only thing you must send from android is one-time code. Other parameters are static, store they in a config file.
var params = {
code: 'FROM ANDROID [ONE TIME CODE]',
Android side, Enable server-side API access for your app, after implementing this, you will have an one-time code
I hope these will be helpful for you.