Android
This tutorial will walk you through the steps of using the Ride Request API in your Android app. In this guide, we’ll be going through the entire process to get a working app with the Rides SDK configured. We will set up and configure the SDK, then walk through an example Ride Request integration.
¶ Your Android Project
We can create a new Empty Activity project to demonstrate how to begin using the SDK. In Android Studio, choose Start a new Android Studio Project and when prompted to Add an Activity to Mobile, select Empty Activity and click Next.
In the next screen, set the Activity Name field to any name you want, leave everything else as the default and click Finish. You now have a boilerplate app with just one activity!
¶ Add the SDK to your project
The best way to integrate the SDK into your existing project is to use a dependency manager. The SDK can be added to Maven or Gradle based projects. The following sections will focus on the respective dependency manager you use within your project.
Using a dependency manager such as Maven or Gradle makes it easy to keep your app udpated with the latest version of the SDK.
¶ Gradle
The following steps assume that you have successfully set up a Gradle project. To learn about Gradle, please refer to the official user guide.
In your Gradle project, navigate to your build script (build.gradle
) and open it. Now, identify the dependencies
section in your file and add the SDK as an external module dependency:
dependencies {
compile 'com.uber.sdk:rides-android:0.5.3'
}
Now, use the IDE of your choice or a CLI like Gradlew to fetch the SDK resources and build your project.
¶ Maven
The following steps assume that you have successfully set up a Maven project. To learn about Maven, please refer to the official documentation.
In your Maven project, navigate to the pom.xml
file and open it. Now, identify the dependencies
section in your file and add the SDK as a new dependency project:
<dependencies>
<dependency>
<groupId>com.uber.sdk</groupId>
<artifactId>rides-android</artifactId>
<version>0.5.3</version>
</dependency>
</dependencies>
Finally, use the IDE of your choice or the maven command line interface mvn
to fetch the SDK resources and build your project.
¶ Configure the SDK
Congratulations, you’ve added the Uber Rides Android SDK into your project! Next, you have to configure the SDK. More specifically, you have to define your Uber app details obtained from the developer dashboard.
In your application, create a SessionConfiguration
builder object. Ultimately, this object will be passed to to the UberSdk
class to initialize a new client object with the correct configuration properties.
The configuration builder has several methods to define a variety of settings. To keep things simple, set them all for now (even though some features might use only a subset of them):
import com.uber.sdk.android.core.UberSdk;
import com.uber.sdk.core.auth.Scope;
import com.uber.sdk.rides.client.SessionConfiguration;
...
SessionConfiguration config = new SessionConfiguration.Builder()
// mandatory
.setClientId("<CLIENT_ID>")
// required for enhanced button features
.setServerToken("<TOKEN>")
// required for implicit grant authentication
.setRedirectUri("<REDIRECT_URI>")
// optional: set sandbox as operating environment
.setEnvironment(SessionConfiguration.Environment.SANDBOX)
.build();
Finally, you can initialize the SDK with the config
object:
UberSdk.initialize(config);
With that, you are all set to use the SDK!
¶ SDK Configuration
In order for the SDK to function correctly, you need to initialize the UberSdk
class with some information about your app. Add the following code snippet early on in your app, replacing “yourClientId” and “yourRedirectUri” with your app’s Client ID and Redirect URI from the developer dashboard.
SessionConfiguration config = new SessionConfiguration.Builder()
.setClientId("<CLIENT_ID>")
.setRedirectUri("<REDIRECT_URI>")
.setEnvironment(Environment.SANDBOX)
.setScopes(Arrays.asList(Scope.PROFILE, Scope.REQUEST))
.build();
UberSdk.initialize(config);
¶ Location Services
Requesting location services permission from user can be done using Android’s ActivityCompat class. The Android SDK checks permission for Manifest.permission.ACCESS_FINE_LOCATION
, which must be granted to be able to retrieve the user’s current location.
¶ Native Login with Uber (SSO)
The Uber SDK allows for three login flows: Implicit Grant (local web view), Single Sign On with the Uber App, and Authorization Code Grant (requires a backend to catch the local web view redirect and complete OAuth).
To use Single Sign On you must register a hash of your application’s signing certificate in the App Signature field under the Settings tab of the developer dashboard.
To get the hash of your signing certificate, run this command with the alias of your key and path to your keystore:
keytool -exportcert -alias <your_key_alias> -keystore <your_keystore_path> | openssl sha1 -binary | openssl base64
Before you can request any rides, you need to get an AccessToken
. The Uber Rides SDK provides the LoginManager
class for this task. Simply create a new instance and use its login method to present the login screen to the user.
LoginCallback loginCallback = new LoginCallback() {
@Override
public void onLoginCancel() {
// User canceled login
}
@Override
public void onLoginError(@NonNull AuthenticationError error) {
// Error occurred during login
}
@Override
public void onLoginSuccess(@NonNull AccessToken accessToken) {
// Successful login! The AccessToken will have already been saved.
}
}
AccessTokenManager accessTokenManager = new AccessTokenManager(context);
LoginManager loginManager = new LoginManager(accessTokenManager, loginCallback);
loginManager.login(activity);
The call to loginWithScopes()
presents an activity with a WebView where the user logs into their Uber account, or creates an account, and authorizes the requested scopes. In your Activity#onActivityResult()
, call LoginManager#onActivityResult()
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
loginManager.onActivityResult(activity, requestCode, resultCode, data);
}
The default behavior of calling LoginManager.login(activity)
is to activate Single Sign On, and if that is unavailable, fallback to Implicit Grant if privileged scopes are not requested, otherwise redirect to the Play Store. If Authorization Code Grant is required, set LoginManager.setRedirectForAuthorizationCode(true)
to prevent the redirect to the Play Store. Implicit Grant will allow access to all non-privileged scopes, where as the other two both grant access to privileged scopes. Read more about scopes.
¶ Login Errors
Upon a failure to login, an AuthenticationError
will be provided in the LoginCallback
. This enum provides a series of values that provide more information on the type of error.
¶ Custom Authorization / TokenManager
If your app allows users to authorize via your own customized logic, you will need to create an AccessToken
manually and save it in shared preferences using the AccessTokenManager
.
AccessTokenManager accessTokenManager = new AccessTokenManager(context);
Date expirationTime = 2592000;
List<Scope> scopes = Arrays.asList(Scope.PROFILE);
String token = "obtainedAccessToken";
String refreshToken = "obtainedRefreshToken";
String tokenType = "obtainedTokenType";
AccessToken accessToken = new AccessToken(expirationTime, scopes, token, refreshToken, tokenType);
accessTokenManager.setAccessToken(accessToken);
The AccessTokenManager
can also be used to get an access token or delete it.
accessTokenManger.getAccessToken();
accessTokenManager.removeAccessToken();
To keep track of multiple users, create an AccessTokenManager for each AccessToken.
AccessTokenManager user1Manager = new AccessTokenManager(activity, "user1");
AccessTokenManager user2Manager = new AccessTokenManager(activity, "user2");
user1Manager.setAccessToken(accessToken);
user2Manager.setAccessToken(accessToken2);
¶ User Profile
Session session = loginManager.getSession();
RidesService service = UberRidesApi.with(session).build().createService();
Response<UserProfile> response = service.getUserProfile().execute();
if (response.isSuccessful()) {
//Success
UserProfile profile = response.body();
} else {
//Failure
ApiError error = ErrorParser.parseError(response);
}
¶ Ride Requests
The Uber API gives you the ability to Request an Uber Product on behalf of users within your application. Given you know where a user currently is, where they want to go, and which Uber product they want to use to get there, you have all of the tools to make that happen with a few simple API endpoints.
- In the products endpoint
GET /products
, products will have theupfront_fare_enabled
field set totrue
. - Use the request estimate endpoint
POST /requests/estimate
with theproduct_id
to get afare_id
. Thefare_id
can be used to lock down an upfront fare and arrival time for a trip. Thefare_id
expires after two minutes. If thefare_id
is expired or not valid, we return a422
error. - Request the ride using the request endpoint
POST /requests
with thefare_id
returned in the previous step.
¶ The Sandbox
Because of the real-world nature of the Ride Request endpoints, which call active drivers on the system which result in financial transactions on Uber rider accounts, the Uber API provides a sandbox environment for testing. All ride requests made to the sandbox will result in a simulated ride request that can be programmatically updated. To get an understanding on how to set up your environment for making ride requests within the sandbox environment, see the sandbox guide.
¶ Request a Ride
The Android SDK uses the Java SDK underneath so requesting a ride with the API is the same as using the java implementation.
# Get products for location
Response<List<Product>> response = service.getProducts(37.79f, -122.39f).execute();
List<Product> products = response.body();
String productId = products.get(0).getProductId();
# Get upfront fare for product with start/end location
RideRequestParameters rideRequestParameters = new RideRequestParameters.Builder().setPickupCoordinates(37.77f, -122.41f)
.setProductId(productId)
.setDropoffCoordinates(37.49f, -122.41f)
.build();
RideEstimate rideEstimate = service.estimateRide(rideRequestParameters).execute().body();
String fareId = rideEstimate.getFareId();
# Request ride with upfront fare for product with start/end location
RideRequestParameters rideRequestParameters = new RideRequestParameters.Builder().setPickupCoordinates(37.77f, -122.41f)
.setProductId(productId)
.setFareId(fareId)
.setDropoffCoordinates(37.49f, -122.41f)
.build();
Ride ride = service.requestRide(rideRequestParameters).execute().body();
String rideId = ride.getRideId();
# Request ride details from request_id
Ride ride = service.getRideDetails(rideId).execute().body();
# Cancel a ride
Response<Void> response = service.cancelRide(rideId).execute();
As a Request is ongoing, you will want to display the details of the Request to the user in a way that helps them understand what is happening and give them the information they need to find or get in touch with their driver.
For instance, when a Request is processing
it’s probably best to let the user know Uber is attempting to find them a driver. Using a spinner or other loading indicator can convey this message well.
Once a Request status has changed to accepted
you can let your user know a vehicle is enroute, what the details of the driver are, and remind them their pickup location. You can even show them the location of the vehicle on a map because the Uber API provides this location information.
If the Request status becomes arriving
you probably want to indicate this to the user in a way that gets their attention. And once a Request is in_progress
you can provide the information a user might find useful once they are already in the vehicle.
Unfortunately, there are some times when a driver must cancel a Request, and your application should let the user know when this happens. This will be indicated when the status of a Request is returned as driver_canceled.
At this point it’s usually helpful to make it easy for a user to re attempt a Request.
Lastly, sometimes a user needs to get in touch with a driver to clarify their location, so please provide an easy way to call or SMS the driver from within your application.
The possible values for status are:
Status | Description |
---|---|
processing |
The Request is matching to the most efficient available driver. |
no_drivers_available |
The Request was unfulfilled because no drivers were available. |
accepted |
The Request has been accepted by a driver and is “en route” to start location. |
arriving |
The driver has arrived or will be shortly. |
in_progress |
The Request is “en route” from the start location to the end location. |
driver_canceled |
The Request has been canceled by the driver. |
rider_canceled |
The Request canceled by |
completed |
Request has been completed by the driver. |
Check out our detailed guide for best practices implementing ride requests for your users.