build.gradle
file:
AndroidManifest.xml
and add the internet permission:
strings.xml
resource located in /res/values/strings.xml
:
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
AndroidManifest.xml
and add the LoginActivity
:
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, , and scope to the WebAuthProvider
. For this implementation we will use:
demo
https://api.exampleco.com/timesheet
s (the Node.JS API)code
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 .login()
method, upon successful authentication we’ll redirect the user to the TimeSheetActivity
.
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 if they are expired.
login()
method so that credentials are stored via the CredentialsManager
after a successful authentication.
UserProfileManager
and UserActivity
.
UserProfileManager
. The UserProfileManager
will use SharedPreferences to store data.
login()
method in the LoginActivity
to retrieve the and get the user profile from the token with the JWTDecode.Android library. Then store the user profile with the UserProfileManager
.
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.
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:
UserProfileManager
to store the extra field:
LoginActivity
to pass along the scope
so it can be stored in the User
object:
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:
AndroidManifest.xml
and add the TimeSheetActivity
:
timesheet_activity.xml
, the layout for the TimeSheetsActivity
:
ListView
widget will contain individual entries which are represented by the item_entry.xml
layout:
TimeSheetActivity
, we’ll create the timesheet_action_menu.xml
menu resource (/res/menu/
):
TimeSheetAdapter
is a utility class which will take an array of timesheet entries and apply them to the ListView
on the TimeSheetActivity
.
TimeSheetActivity
displays the timesheet entries for the logged in user which are stored on the server.
@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
.callAPI()
method retrieves timesheets from the Node.JS API.processResults()
method takes the JSON response from callAPI()
and converts it TimeSheet
objects.onCreateOptionsMenu(
) and onOptionsItemSelected(
) methods handle the Toolbar widget navigation functionality.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.
AndroidManifest.xml
and add the UserActivity
:
user_activity.xml
, the layout for the UserActivity
, with an ImageView
for the profile picture and TextViews
for the user’s name and email.
user_actions_menu.xml
for the UserActivity
Toolbar:
AsyncTask
and executes in the background.
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.
FormActivity
and layout to handle creating new timesheet entries.
AndroidManifest.xml
and add the FormActivity
:
form_activity.xml
layout with EditText
for the project name and hours worked inputs, and a DatePicker
for the day worked.
form_actions_menu.xml
for the FormActivity
Toolbar:
@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
.onCreate()
method initializes the form and collects the input for the postAPI()
method when the submit button is pressed.postAPI()
method will send the user input retrieved from the form to the Node.JS API in JSON format.clearForm()
method clears the input forms.onCreateOptionsMenu()
and onOptionsItemSelected()
methods handle the Toolbar widget navigation functionality.node server
command.