Build real time tracking of deliveries in Android

With globalization of Uber, users across the world now expect to live track their deliveries. Services like food delivery, laundry pick up and delivery, grocery delivery, and couriers are booked with the tap of a button and the product is delivered by a rider who use an app to manage the deliveries.

Live location of such riders can be useful to assign deliveries based on location, track the delivery, measure productivity, share location with customers for a better product experience and track miles for expense management. Delivery companies around the world and across industries use HyperTrack to build live location use cases.

In this tutorial, we will talk about how to build:
PREREQUISITE
Make sure you have plugged in the Android SDK into your rider app
PLUG IN THE SDK
IMPLEMENTATION
Follow this 6-step guide to get your use case implemented. We have implemented an example app using this tutorial. It's open-sourced - so go ahead and fork it, add to it, test it, and even use it as the base for your own thing!
Developer Evangelist
Step 1: Set user
The very first step is to set user in your app. This could be done when the rider logs in to the app. 
    /**
     * Call this method to attempt login. This method will create a User on HyperTrack Server
     * and configure the SDK using this generated UserId.
     */
    private void attemptDriverLogin() {
        // Show Login Button loader
        loginBtnLoader.setVisibility(View.VISIBLE);
        // Get rider details, if provided
        final String name = driverNameText.getText().toString();
        final String phoneNumber = driverPhoneNumberText.getText().toString();
        // PhoneNumber is used as the lookup_id here but you can specify any other entity as the lookup_id.
        final String lookupId = phoneNumber;
        /**
         * Create a User on HyperTrack Server here to login your rider and configure HyperTrack SDK with
         * this generated HyperTrack UserId.
         * OR
         * Implement your API call for Driver Login and get back a HyperTrack UserId from your API Server
         * to be configured in the HyperTrack SDK.
         *
         * @NOTE:
         * Specify rider name, phone number and a lookup_id denoting your rider's internal id.
         * PhoneNumber is used as the lookup_id here but you can specify any other entity as the lookup_id.
         */
        HyperTrack.createUser(name, phoneNumber, lookupId, new HyperTrackCallback() {
            @Override
            public void onSuccess(@NonNull SuccessResponse successResponse) {
                // Hide Login Button loader
                loginBtnLoader.setVisibility(View.GONE);
                User user = (User) successResponse.getResponseObject();
                // Handle createUser success here, if required
                // HyperTrack SDK auto-configures UserId on createUser API call, so no need to call
                // HyperTrack.setUserId() API
                // On DriverLogin success
                onDriverLoginSuccess();
            }
            @Override
            public void onError(@NonNull ErrorResponse errorResponse) {
                // Hide Login Button loader
                loginBtnLoader.setVisibility(View.GONE);
                Toast.makeText(LoginActivity.this, R.string.login_error_msg + " " + errorResponse.getErrorMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
Developer Evangelist
Step 2: Start tracking
To start tracking the rider, use the startTracking method. Call this method when the rider logs in to the app. Alternatively, you can use AlarmManager to call this method at a predefined time, say at 7am everyday.
    /**
     * Call this method when rider has successfully logged in
     */
    private void onDriverLoginSuccess() {
        // To start tracking your rider, call HyperTrack's startTracking API
        HyperTrack.startTracking(new HyperTrackCallback() {
            @Override
            public void onSuccess(@NonNull SuccessResponse successResponse) {
                // Hide Login Button loader
                loginBtnLoader.setVisibility(View.GONE);
                // Handle startTracking API response
                SharedPreferenceStore.setDriverId(LoginActivity.this, HyperTrack.getUserId());
                Toast.makeText(LoginActivity.this, R.string.login_success_msg, Toast.LENGTH_SHORT).show();
                // Start Driver Session by starting MainActivity
                TaskStackBuilder.create(LoginActivity.this)
                        .addNextIntentWithParentStack(new Intent(LoginActivity.this, MainActivity.class)
                                .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                        .startActivities();
                finish();
            }
            @Override
            public void onError(@NonNull ErrorResponse errorResponse) {
                // Hide Login Button loader
                loginBtnLoader.setVisibility(View.GONE);
                Toast.makeText(LoginActivity.this, R.string.login_error_msg + " " + errorResponse.getErrorMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
Keep the SDK on throughout the day. Don’t worry about the battery - our SDK uses only 5-10 mAh per hour of tracking .
Developer Evangelist
Step 3: Create & assign delivery action
For every delivery order that you want to track, create and assign a Delivery action to the rider. Call createAndAssignAction method when you assign the delivery to a rider. In case your workflow requires the rider to accept a delivery order, call the above method when the rider taps the ACCEPT button.

Most developers want to additionally track the pickup associated with the order, if the order has to be picked up before getting delivered. To do so, create and assign a Pickup action to the rider. 

Use following parameters to build your Action object.
Parameter
Action #1 (Pickup)
Action #2 (Delivery)
expected_place
The Place object where the pickup action will be performed.
The Place object where the delivery action will be performed.
type
Pickup
Delivery
lookup_id
An id that you can specify based on your internal id of that order. This will help you search for the order on HyperTrack dashboard, and get custom views for the specific order.
Same as that for action #1
scheduled_at
The scheduled time by when the rider is supposed to pickup the order.
The scheduled time by when the rider is supposed to deliver the order.
 /**
     * This method creates and assigns PICKUP and DELIVERY actions to the current user on
     * HyperTrack API Server for the current order's orderID.
     *
     * @param orderID Internal order_id which maps to the current order being delivered
     */
    private void createActionsForJob(String orderID) {
        /**
         * Construct a place object for Action's expected place
         *
         * @NOTE: Either the coordinates for the pickup location
         * or it's address can be used to construct the expected place for the Action
         */
        Place expectedPlace = new Place().setLocation(28.56217, 77.16160)
                .setAddress("HyperTrack, Vasant Vihar")
                .setName("HyperTrack");
        /**
         * Create ActionParams object specifying the Visit Action parameters including ExpectedPlace,
         * ExpectedAt time and Lookup_id.
         */
        ActionParams visitTypeActionParams = new ActionParamsBuilder()
                .setExpectedPlace(expectedPlace)
                .setExpectedAt(new Date())
                .setType(Action.ACTION_TYPE_VISIT)
                .setLookupId(orderID)
                .build();
        /**
         * Call createAndAssignAction to assign Visit action to the current user configured
         * in the SDK using the ActionParams created above.
         */
        HyperTrack.createAndAssignAction(visitTypeActionParams, new HyperTrackCallback() {
            @Override
            public void onSuccess(@NonNull SuccessResponse response) {
                // Handle createAndAssignAction API success here
                Action action = (Action) response.getResponseObject();
                SharedPreferenceStore.setVisitActionId(MainActivity.this, action.getId());
                /**
                 * The PICKUP Action just created has the tracking url which can be shared with your customers.
                 * This will enable the customer to live track the rider.
                 *
                 * @NOTE You can now share this tracking_url with your customers via an SMS
                 * or via your Customer app using in-app notifications.
                 */
                String trackingUrl = action.getTrackingURL();
                /**
                 * Yay! PICKUP Type Action has been successfully created and assigned to current user.
                 * Now, we need to createAndAssignAction for DELIVERY Type Action using the same lookup_id.
                 */
                assignStopoverActionForJob(action.getExpectedPlace().getId(), action.getLookupID());
            }
            @Override
            public void onError(@NonNull ErrorResponse errorResponse) {
                if (mProgressDialog != null) {
                    mProgressDialog.dismiss();
                }
                Toast.makeText(MainActivity.this, "Action assigned failed: " + errorResponse.getErrorMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
    /**
     * This method creates and assigns DELIVERY type action using given expectedPlaceId and lookup_id
     *
     * @param expectedPlaceID  ExpectedPlace Id created on HyperTrack API Server for the PICKUP type action.
     * @param lookupID         Internal order_id which maps to the current job being performed.
     */
    private void assignStopoverActionForJob(String expectedPlaceID, String lookupID) {
        /**
         * Create ActionParams object specifying the DELIVERY Action parameters including
         * already created ExpectedPlaceId, ExpectedAt time and same Lookup_id as for the Visit type action.
         */
        ActionParams stopOverTypeActionParams = new ActionParamsBuilder()
                .setExpectedPlaceId(expectedPlaceID)
                .setExpectedAt(new Date())
                .setType(Action.ACTION_TYPE_STOPOVER)
                .setLookupId(lookupID)
                .build();
        /**
         * Call createAndAssignAction to assign DELIVERY action to the current user configured
         * in the SDK using the ActionParams created above.
         */
        HyperTrack.createAndAssignAction(stopOverTypeActionParams, new HyperTrackCallback() {
            @Override
            public void onSuccess(@NonNull SuccessResponse response) {
                if (mProgressDialog != null) {
                    mProgressDialog.dismiss();
                }
                // Handle createAndAssignAction API success here
                Action action = (Action) response.getResponseObject();
                SharedPreferenceStore.setStopoverActionId(MainActivity.this, action.getId());
                Toast.makeText(MainActivity.this, "Job (id = " + action.getId() + ") accepted successfully.",
                        Toast.LENGTH_SHORT).show();
            }
            @Override
            public void onError(@NonNull ErrorResponse errorResponse) {
                if (mProgressDialog != null) {
                    mProgressDialog.dismiss();
                }
                Toast.makeText(MainActivity.this, "Action assigned failed: " + errorResponse.getErrorMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
Developer Evangelist
Step 4: Complete delivery action
When the rider confirms that he/she has completed the pick-up  (e.g., when he/she taps on PICKUP COMPLETE button), call the completeAction method for the pickup action in our SDK.
// Complete action using actionId for the PICKUP action that you created
HyperTrack.completeAction(visitActionId);
Developer Evangelist
Step 5: Complete delivery action
When the rider confirms that he/she has completed the delivery (e.g., when he/she taps on DELIVERED button), call the completeAction method for the delivery action in our SDK.
// Complete action using actionId for the DELIVERY action that you created
HyperTrack.completeAction(stopoverActionId));  
Developer Evangelist
Step 6: Stop tracking
To stop tracking the rider, use the stopTracking method. Call this method when the rider logs out of the app. Alternatively, you can use AlarmManager to call this method at a predefined time, say at 9pm everyday.
//Stop tracking a user
HyperTrack.stopTracking();
RECAP
Yay! You just developed location tracking of your deliveries in Android. Let’s do a recap of what all you built in the process.
  • Live order tracking widgets that integrate with your customer service and operations dashboards
    In your customer service dashboard, you would have a list of all orders. You now have a link that opens up a dashboard view for that order, and shows details of both the actions (pickup & delivery) that you created for that order. To embed the widget, use the following URL: https://dasboard.hypertrack.com/widget/actions;lookup_id=<LOOKUP_ID>?key=<YOUR_SECRET_KEY>
  • Live order tracking experiences that integrate with your product experience
    As soon as you create & assign the delivery action to your rider, the API returns an unique trck.at URL. Share this URL with your end customer (via text message or email) so that they can live track the rider and know their real time ETA. You can also embed a native tracking experience within your end customer app by following this guide, or customize the web tracking experience by following this guide.
  • Location-based assignment of deliveries to nearest available rider
    Use our Nearest-N users API to get riders who are closest (by time) to the expected location of delivery/pickup.
  • Mileage tracking for expense management and logging of routes traveled
    Call the mileage API for the delivery and visit actions to get accurate distance that was travelled by the rider from the time of assignment to the time when he/she reached the pickup and delivery locations. In case of customer complaints, visit HyperTrack dashboard and search for the order by searching for LookUp Id. Replay the entire journey of the rider from the time of assignment to time when he/she completed the pickup to time when he/she completed the delivery.
How simple was that
Just a few steps and an hour, and you are now able to track live location of your deliveries. 

We are excited to see what live location feature you build in your product. Do ping us at help@hypertrack.io once you build one, and we would love to feature your app on our blog!