Docs

Mobile + API: Android Implementation for the Mobile App

This document is part of the Mobile + API Architecture Scenario and it explains how to implement the mobile application in Android. Please refer to the scenario for information on the implemented solution.

1. Set Up the Application

Sample Project

Download a sample project specific to this tutorial configured with your Auth0 API Keys.

System Requirements
  • Android Studio 2.3
  • Android SDK 25
  • Emulator - Nexus 5X - Android 6.0
Show requirements

Set the Dependencies

For this implementation, we will use the following dependencies within the app’s build.gradle file:

  • Auth0.Android: this package enables integration with Auth0 to authenticate users.
  • OkHttp: this package provides an HTTP application to make requests to the Node.JS API.
  • JWTDecode.Android: this package will assist with decoding JWTs.
  • AppCompat: this package lets us use the toolbar widget for navigation in our activities.

Update the Manifest

Open the application's AndroidManifest.xml and add the internet permission:

We’ll also update the application details to utilize the Toolbar widget:

Set Configuration Values

Set your Auth0 Client ID, Auth0 Domain, and API’s url in the strings.xml resource located in /res/values/strings.xml:

Create Package Structure

For this implementation, create directories for activities, models, and utils in the application package.

  • activities/: this package will contain the LoginActivity.java, TimeSheetActivity.java, FormActivity.java, and UserActivity.java.
  • models/: this package will contain the TimeSheet.java and User.java data models.
  • utils/: this package will contain the UserProfileManager.java, TimeSheetAdapter.java, and ImageTask.java

2. Authorize the User

Update the Manifest

Open the app's AndroidManifest.xml and add the LoginActivity:

Create the Login Activity Layout

Next create login_activity.xml, the layout for the LoginActivity:

Create the Login Activity

The LoginActivity will handle user authorization and be the initial screen users see. We'll create a login() method to initialize a WebAuthProvider and start authentication. Ensure you provide the correct scheme, audience, and scope to the WebAuthProvider. For this implementation we will use:

  • scheme: demo
  • audience: https://api.exampleco.com/timesheets (the Node.JS API)
  • response_type: code
  • scope: create:timesheets read:timesheets openid profile email offline_access. These scopes will enable us to POST and GET to the Node.JS API, as well as retrieve the user profile and a Refresh Token.

In the login() method, upon successful authentication we'll redirect the user to the TimeSheetActivity.

Store the Credentials

To store the credentials received after login, we’ll use the CredentialsManager from the Auth0.Android library and SharedPreferences for storage.

Before initializing the WebAuthProvider in the login() method, we can create the CredentialsManager. Passing an AuthenticationAPIClient to the CredentialsManager enables it to refresh the Access Tokens if they are expired.

Now update the login() method so that credentials are stored via the CredentialsManager after a successful authentication.

3. Get the User Profile

Create the User Model

Create a simple User model that will be utilized by the UserProfileManager and UserActivity.

Store the User Profile

To handle storing user profile information we'll create a manager class UserProfileManager. The UserProfileManager will use SharedPreferences to store data.

Next, update the login() method in the LoginActivity to retrieve the ID Token and get the user profile from the token with the JWTDecode.Android library. Then store the user profile with the UserProfileManager.

4. Display UI Elements Conditionally Based on Scope

To determine whether a user has permissions to perform certain actions, we can look at the scope that was granted to the user during the authentication process. The scope will contain a string with all the scopes granted to a user, so to determine whether a particular scope was granted, we simply need to look whether the string of scopes contain the substring for that particular scope.

Store the Scope

First, we can update the User class to store the granted scopes, and then provide a helper method, hasScope() which can be used to determine whether the granted scopes contain a particular scope:

Also remember to update the UserProfileManager to store the extra field:

Next, update the LoginActivity to pass along the scope so it can be stored in the User object:

Display Approval Menu Based on Scope

Now, we can display certain UI elements based on whether the user was granted a particular scope. As an example, we have an approval menu item which should only be visible to users who have been granted the approve:timesheets scope.

Below you can see the code from the BaseActivity class which checks whether a user has the approve:timesheets scope, and based on that will set the visibility of the menu item which displays the approval activity:

5. Call the API

Update the Manifest

Open the app's AndroidManifest.xml and add the TimeSheetActivity:

Create the Timesheets Activity Layouts

Next create timesheet_activity.xml, the layout for the TimeSheetsActivity:

The ListView widget will contain individual entries which are represented by the item_entry.xml layout:

And for the Toolbar navigation on the TimeSheetActivity, we’ll create the timesheet_action_menu.xml menu resource (/res/menu/):

Create the Timesheet Model

Create a model for working with timesheet data in our views:

Create the Timesheet Adapter

The TimeSheetAdapter is a utility class which will take an array of timesheet entries and apply them to the ListView on the TimeSheetActivity.

Create the Timesheet Activity

The TimeSheetActivity displays the timesheet entries for the logged in user which are stored on the server.

  • The @string/api_url is set to http://10.0.2.2:8080/timesheets so the Android Emulator can connect to the Node.JS API running on http://localhost:8080.
  • The callAPI() method retrieves timesheets from the Node.JS API.
  • The processResults() method takes the JSON response from callAPI() and converts it TimeSheet objects.
  • The onCreateOptionsMenu() and onOptionsItemSelected() methods handle the Toolbar widget navigation functionality.

6. View the User Profile

To display the logged in user’s profile we’ll create the UserActivity, a corresponding user_activity.xml layout, and the user_action_menu.xml for the Toolbar navigation. The view will display the user’s name, email, and profile picture.

Update the Manifest

Open the app's AndroidManifest.xml and add the UserActivity:

Create the User Activity Layouts

Next create user_activity.xml, the layout for the UserActivity, with an ImageView for the profile picture and TextViews for the user's name and email.

And create the user_actions_menu.xml for the UserActivity Toolbar:

Load the Profile Picture from URL

In order to load the user profile picture from the URL, create a task which extends AsyncTask and executes in the background.

Create the User Activity

In the onCreate() method we'll retrieve the user information from the UserProfileManager and set the values in the view. As before, the onCreateOptionsMenu() and onOptionsItemSelected() methods handle the Toolbar widget navigation functionality.

7. Form for New Timesheets

Next create the FormActivity and layout to handle creating new timesheet entries.

Update the Manifest

Open the app's AndroidManifest.xml and add the FormActivity:

Create the Form Activity Layouts

Create the form_activity.xml layout with EditText for the project name and hours worked inputs, and a DatePicker for the day worked.

And create the form_actions_menu.xml for the FormActivity Toolbar:

Create the Form Activity

  • The @string/api_url is set to http://10.0.2.2:8080/timesheets so the Android Emulator can connect to the Node.JS API running on http://localhost:8080.
  • The onCreate() method initializes the form and collects the input for the postAPI() method when the submit button is pressed.
  • The postAPI() method will send the user input retrieved from the form to the Node.JS API in JSON format.
  • The clearForm() method clears the input forms.
  • The onCreateOptionsMenu() and onOptionsItemSelected() methods handle the Toolbar widget navigation functionality.

Test the App

Before continuing, ensure you have implemented the Node.JS API.

  1. Start the API by navigating to the API's directory in your terminal and entering the node server command.
  2. Open the mobile app in Android Studio and press the Run button.
  3. Select the Nexus 5X API 23 virtual device.
  4. Once the emulator has loaded the mobile app, you can login user then, create and view timesheet entries from the running Node.JS API.

That's it! You are done!