uber requestRide() method Response Error 401: Unauthorized - android

I am getting Error when I try to call requestRide() method on Uber api. The response body is null and the response message is "Unauthorized" with error code 401; whereas the onResponse() callback method is executing but onFailure() callback method is not executing.
Here is my code for calling requestRide() and implementing the callback interface...
private void requestForNewRide(RidesService service, int position){
RideRequestParameters rideRequestParameters = new RideRequestParameters.Builder().setPickupCoordinates(PICKUP_LATITUDE, PICKUP_LONGITUDE)
.setProductId(productIds.get(position))
.setFareId(fareIds.get(position))
.setDropoffCoordinates(DROPOFF_LATITUDE, DROPOFF_LONGITUDE)
.build();
service.requestRide(rideRequestParameters).enqueue(new Callback<Ride>() {
#Override
public void onResponse(Call<Ride> call, Response<Ride> response) {
if (response.isSuccessful()) {
Toast.makeText(CustomActivity.this, "Request ride success", Toast.LENGTH_SHORT).show();
try {
//ride details
String rideId = response.body().getRideId();
String rideStatus = response.body().getStatus();
Integer rideEta = response.body().getEta(); //estimated time of arrival in min
Float rideSurgeMultiplier = response.body().getSurgeMultiplier(); //rise in price
Driver rideDriver = response.body().getDriver();
Location rideLocation = response.body().getLocation();
Vehicle rideVehicle = response.body().getVehicle();
//ride driver details
String driverName = rideDriver.getName();
String driverPhoneNumber = rideDriver.getPhoneNumber();
String driverPictureUri = rideDriver.getPictureUrl();
Float driverRating = rideDriver.getRating();
//ride Location details
Float rideLocationLatitude = rideLocation.getLatitude();
Float rideLocationLongitude = rideLocation.getLongitude();
Integer rideLocationBearing = rideLocation.getBearing();
//ride Vehicle details
String rideVehicleLicencePlate = rideVehicle.getLicensePlate();
String rideVehicleMake = rideVehicle.getMake();
String rideVehicleModel = rideVehicle.getModel();
String rideVehiclePictureUrl = rideVehicle.getPictureUrl();
//Log
Log.d("uberridedetails", "rideId: " + rideId);
Log.d("uberridedetails", "rideStatus: " + rideStatus);
Log.d("uberridedetails", "rideEta: " + rideEta);
Log.d("uberridedetails", "rideSurgeMultiplier: " + rideSurgeMultiplier);
Log.d("uberridedetails", "driverName: " + driverName);
Log.d("uberridedetails", "driverPhoneNumber: " + driverPhoneNumber);
Log.d("uberridedetails", "driverPictureUri: " + driverPictureUri);
Log.d("uberridedetails", "driverRating: " + driverRating);
Log.d("uberridedetails", "rideLocationLatitude: " + rideLocationLatitude);
Log.d("uberridedetails", "rideLocationLongitude: " + rideLocationLongitude);
Log.d("uberridedetails", "rideLocationBearing: " + rideLocationBearing);
Log.d("uberridedetails", "rideVehicleLicencePlate: " + rideVehicleLicencePlate);
Log.d("uberridedetails", "rideVehicleMake: " + rideVehicleMake);
Log.d("uberridedetails", "rideVehicleModel: " + rideVehicleModel);
Log.d("uberridedetails", "rideVehiclePictureUrl: " + rideVehiclePictureUrl);
} catch (Exception e) {
e.printStackTrace();
}
}else {
Toast.makeText(CustomActivity.this, "Error: "+response.message(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Ride> call, Throwable t) {
Toast.makeText(CustomActivity.this, "Failed to request ride", Toast.LENGTH_SHORT).show();
}
});
}
I have already checked the param productId and FareId is valid, which I am getting from the api itself (by calling estimateRide() I get Price object from that I have got the fareId. And by calling getProducts() on RideService object I have got the productId.
This is the code for set up...
SessionConfiguration config = new SessionConfiguration.Builder()
.setClientId(getResources().getString(R.string.client_id))
.setRedirectUri(getResources().getString(R.string.redirect_url))
.setEnvironment(SessionConfiguration.Environment.SANDBOX)
.setScopes(Arrays.asList(Scope.PROFILE, Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.REQUEST_RECEIPT))
.build();
UberSdk.initialize(config);
And ...
LoginCallback loginCallback = new LoginCallback() {
#Override
public void onLoginCancel() {
// User canceled login
Toast.makeText(CustomActivity.this, "User canceled login", Toast.LENGTH_SHORT).show();
}
#Override
public void onLoginError(#NonNull AuthenticationError error) {
// Error occurred during login
Toast.makeText(CustomActivity.this, "Error occurred during login", Toast.LENGTH_SHORT).show();
}
#Override
public void onLoginSuccess(#NonNull AccessToken accessToken) {
// Successful login! The AccessToken will have already been saved.
Toast.makeText(CustomActivity.this, "Successful login! The AccessToken will have already been saved.", Toast.LENGTH_SHORT).show();
createSession();
}
#Override
public void onAuthorizationCodeReceived(#NonNull String authorizationCode) {
Toast.makeText(CustomActivity.this, "Authorization code received", Toast.LENGTH_SHORT).show();
createSession();
}
};
AccessTokenManager accessTokenManager = new AccessTokenManager(getApplicationContext());
LoginManager loginManager = new LoginManager(accessTokenManager, loginCallback);
loginManager.setRedirectForAuthorizationCode(true);
loginManager.login(this);
mAccessTokenManager = accessTokenManager;
mLoginManager = loginManager;
Note1: These are the scopes I am using...
Scope.PROFILE, Scope.RIDE_WIDGETS, Scope.REQUEST, Scope.REQUEST_RECEIPT
Note2: I am logging in with my developer account.
Let me know if I should mention any other details.

Absolutely I have found out the solution on my own.
I noticed that the onLoginSuccess() callback method is being called only when I am using GENERAL SCOPEs.
Whenever I am using a RESTRICTED SCOPE, the method is not being called, instead another callback method named onAuthorizationCodeReceived() is being called.
Then I have found out, whenever the onAuthorizationCodeReceived() method is called, there is no access token saved in the AccessTokenManager object. Thus without the access token, when I try to request a ride Error returns "Unauthorized".
So, I tried to figure out how to generate Access token using the authorization code. I found no doc regarding this process in the Android section. Then I have found out the solution in the REST web service api.
Here is the LINK of my answer...
NOTE: There is no mention of the callback method onAuthorizationCodeReceived() in the Uber Doc.

Related

Safetynet Issue Status{statusCode=NETWORK_ERROR, resolution=null}

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.

Truecaller sdk implementation getting trueError.getErrorType() 3 and can't delete previous ADD APP from developer.truecaller.com

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.

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?

TWILIO call issue due to 2 missing digit

I am working on an Android application that uses Twilio to make phone calls and to send SMS.
While making a call I get the IVRS message "Your call cannot be completed because of two missing digits".
The FROM number is "+18669135337" and TO number is "(949) 439-7570" or "+19494397570"
What could be the reason thats causing this issue?
This is the code snippet thats making the call
public void connect(String toNumber, ConnectionListener listener) {
Map<String, String> parameters = new HashMap<String, String>();
Log.e(TAG, "Calling from " + mFromNumber);
Log.e(TAG, "Calling to " + toNumber);
Log.e(TAG, "mDevice State is " + mDevice.getState());
parameters.put(Constants.KEY_TO_NUMBER, toNumber);
parameters.put(Constants.KEY_FROM_NUMBER, mFromNumber);
mConnection = mDevice.connect(parameters, listener);
Log.e(TAG, "Connection status " + mConnection);
if (mConnection == null) {
Log.w(TAG, "Failed to create new connection");
}
}

Categories

Resources