Android Services , Usage of PendingIntent Class and startService Method

Hello fellas, today I’d like to share with you the information on how to implement an Android Service that runs on background tasks. We use the startService method of Context for executing background tasks and Pending Intent as a callback method. Here is a code snippet from my Android Project.

ApiService.class

    public static void RequestApi(WeakReference<Activity> contextRef, int request_type, HashMap<String,Object> extraInfos) {

        Activity context = contextRef.get();
        if(context == null) {
            Log.wtf("API SERVICE", "Context is null");
        }
        Intent apiService = new Intent(context,ApiService.class);
        PendingIntent pendingResult = ((Activity)context).createPendingResult(request_type,new Intent(),0);
        apiService.putExtra(PENDING_RESULT_EXTRA,pendingResult);
        apiService.putExtra(REQUEST_TYPE_EXTRA,request_type);
        if (extraInfos != null) {
            apiService.putExtra(STRING_EXTRA_INFO, extraInfos);
        }
        context.getApplicationContext().startService(apiService);
    }
First we create an Intent to run on background. Then we create a PendingIntent instance with parameter of request_type which is a static constant variable in our ApiService class. Then we pass this pendingResult instance to our ApiService instance. Then we pass the request_type as a type and indicates the type of request. Finally we are ready to call startService for ApiService instance. Here are the constant variables of ApiService.class that are used in the code snippet above.

ApiService.class


    public static final String PENDING_RESULT_EXTRA = "pending_result";
    public static final String REQUEST_TYPE_EXTRA = "request";
    public static final String STRING_EXTRA_INFO = "extra_info";

Now we need to implement pending Intent call back onHandleIntent.
Here we override callBack method of Service Intent. I’ll share full code for this method for people who are interested in my service calls.

ApiService.class

@Override
    protected void onHandleIntent(@Nullable Intent intent) {
        PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT_EXTRA);
        int request = intent.getIntExtra(REQUEST_TYPE_EXTRA,-1);
        Intent result = new Intent();

        try {
            switch (request) {
                case IS_SERVER_ALIVE_REQUEST:
                    boolean isServerAlive = this.isServerAlive();
                    result.putExtra(BOOLEAN_RESULT_EXTRA, isServerAlive);
                    break;
            /* CODES ARE REMOVED FOR BACKEND SERVICE SECURITY*/
            }
            /*Send result to caller*/
            try {
                reply.send(this, SUCCESS_CODE, result);
            } catch (Exception e) {
                Log.e(TAG, e.toString());
            }
        } catch (Exception ex) {
            result.putExtra(STRING_RESULT_EXTRA , ex.toString());
            try {
                reply.send(this, ERROR_CODE, result);
            } catch (Exception e) {
                result.putExtra(STRING_RESULT_EXTRA,e.toString());
                Log.e(TAG, e.toString());
            }
        }

In the above code, you can see switch case usage for handling different kinds of service requests. We handle the returned information from Api Service Pending Intent instance here and then send this information with another pending intent instance with name reply which will be handled in caller instance.

ApiService.class

            try { /* Sen*/
                reply.send(this, ERROR_CODE, result);
            } catch (Exception e) {
                result.putExtra(STRING_RESULT_EXTRA,e.toString());
                Log.e(TAG, e.toString());
            }

Now let us have a look at the caller instance’s method of how we handle returned information from API service. First, we will show how we call the API service RequestApi method of ApiService class.

MainActivity.class

With below code we ,call RequestApi method from MainActivity instance.
        ApiService.RequestApi(activityRef,ApiService.IS_SERVER_ALIVE_REQUEST,null);

Then we need to handle the returned information from ApiService’s insntace. it’s the same basic of how we handle PendingIntent callback.

In Main Activity we have overriden again ,

MainActivity.class


 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult requestCode:" + requestCode + "resultCode:"  + resultCode);
        WeakReference<MainActivity> mainActivityRef = myContextPool.getMainActivityRef();
        if (mainActivityRef == null || mainActivityRef.get() == null) {
            Log.wtf(TAG,"Main activity is null");
        }
        MainActivity mainActivity = mainActivityRef.get();
/*Code will be continued*/

As you can see in above code snippet we override OnAcitivtyResult method.

Here we again will have same basic sets of rule. We have a switch case to determine which type of request is returned from ApiService Pending Intent instance.

MainActivity.class

 switch (resultCode) {
            case ApiService.SUCCESS_CODE:
                switch (requestCode) {
                    case ApiService.GET_ALL_STATISTIC_REQUEST:
                        String statisticType;
****
If result Code is ApiService.SUCCESS_CODE, which means everything is all right. Then we can determine the type of ApiService Request.

MainActivity.class

*****

                    case ApiService.IS_SERVER_ALIVE_REQUEST:
                        String result = data.getStringExtra(ApiService.STRING_RESULT_EXTRA);
                        if (result.toLowerCase().contains("error") == false) {
                            MainActivity.API_IS_WORKING = true;
                            Toast.makeText(getApplicationContext(),  result,Toast.LENGTH_SHORT).show();
                        } else {
                            String errMessage = result;
                            MainActivity.API_IS_WORKING = false;
                            closeApplicationDueToError(this,"Server is not responding Ret:" + errMessage);
                        }
                        break; /*case ApiService.IS_SERVE_ALIVE_REQUEST:*/

That’s it folks, In above code snippet we handle the ApiService.IS_SERVE_ALIVE_REQUEST and we do necessary jobs on mainActivity instance.

Leave a Reply

Your email address will not be published. Required fields are marked *