Android IntentService using ResultReceiver

Filed Under: Android

In this tutorial, we’ll be using IntentService with a ResultReceiver in our Android Application. We’ll be creating an application which downloads the image from the url, stores it and adds it to a ListView.

Android ResultReceiver

Android ResultReceiver is used to receive callback results from someone. It’s different from a BroadcastReceiver.

A BroadcastReceiver receives all kinds of messages. It can receive messages from outside the activity too.

A ResultReceiver is specifically used for receiving messages internal to the application. It then can check the result type from the list of result types defined in it. Based on that it can forward the information to the Activity.

The IntentService can use the send method to pass on the data to the ResultReceiver.

The ResultReceiver has the onReceiveResult callback method which gets called whenever a new result is received. Based on the result code in the onReceiveResult, it performs the action.

In the following section we’ll be creating an application in which we download the image from the url in the IntentService and then the Service would send the results to the ResultReceiver where based on the result code (type) we’ll do the necessary action.

Android ResultReceiver Example Project Structure

android IntentService ResultReceiver project

Android ResultReceiver Layout code

The code for the activity_main.xml layout file is given below:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/inEnterUrl"
        android:layout_width="match_parent"
        android:hint="Enter URL"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/button" />


    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/inEnterUrl" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="Button" />

</RelativeLayout>

listview_item_row.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

The code for the IntentService.java class is given below:


package com.journaldev.androidintentserviceresultreceiver;

import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.ResultReceiver;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class MyIntentService extends IntentService {

    public static final int DOWNLOAD_SUCCESS = 2;
    public static final int DOWNLOAD_ERROR = 3;

    public MyIntentService() {
        super(MyIntentService.class.getName());
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String url = intent.getStringExtra("url");
        final ResultReceiver receiver = intent.getParcelableExtra("receiver");
        Bundle bundle = new Bundle();

        File downloadFile = new File(Environment.getExternalStorageDirectory() + "/journaldevFile.png");
        if (downloadFile.exists())
            downloadFile.delete();
        try {
            downloadFile.createNewFile();
            URL downloadURL = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) downloadURL
                    .openConnection();
            InputStream is = conn.getInputStream();
            FileOutputStream os = new FileOutputStream(downloadFile);
            byte buffer[] = new byte[1024];
            int byteCount;
            while ((byteCount = is.read(buffer)) != -1) {
                os.write(buffer, 0, byteCount);
            }
            os.close();
            is.close();

            String filePath = downloadFile.getPath();
            bundle.putString("filePath", filePath);
            receiver.send(DOWNLOAD_SUCCESS, bundle);

        } catch (Exception e) {
            receiver.send(DOWNLOAD_ERROR, Bundle.EMPTY);
            e.printStackTrace();
        }
    }
}

Here we download the url string we get from the Activity via Intent and store it in a file. We later send it to the ResultReceiver.

DO NOT forget to set the service in the Manifest file. Also add the Internet Permission.

In our MainActivity.java we do the following:


package com.journaldev.androidintentserviceresultreceiver;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.ResultReceiver;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Context mContext;

    public static final int PERMISSION_EXTERNAL_STORAGE = 101;
    ListView listView;
    ArrayList<Bitmap> bitmapArrayList = new ArrayList<>();
    ImageResultReceiver imageResultReceiver;

    Button button;
    EditText inputText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_EXTERNAL_STORAGE
            );
        }

        button = findViewById(R.id.button);
        inputText = findViewById(R.id.inEnterUrl);
        inputText.setText("https://www.android.com/static/2016/img/share/andy-lg.png");
        listView = findViewById(R.id.listView);

        imageResultReceiver = new ImageResultReceiver(new Handler());

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent startIntent = new Intent(MainActivity.this,
                        MyIntentService.class);
                startIntent.putExtra("receiver", imageResultReceiver);
                startIntent.putExtra("url", inputText.getText().toString().trim());
                startService(startIntent);

            }
        });


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_EXTERNAL_STORAGE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                } else {
                    Toast.makeText(getApplicationContext(), "We need the above permission to save images", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    private class ImageResultReceiver extends ResultReceiver {

        public ImageResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            switch (resultCode) {
                case MyIntentService.DOWNLOAD_ERROR:
                    Toast.makeText(getApplicationContext(), "Error in Downloading",
                            Toast.LENGTH_SHORT).show();
                    break;

                case MyIntentService.DOWNLOAD_SUCCESS:
                    String filePath = resultData.getString("filePath");
                    Bitmap bmp = BitmapFactory.decodeFile(filePath);

                    if (bmp != null) {
                        bitmapArrayList.add(bmp);
                        Log.d("API123", "bitmap " + bitmapArrayList.size());
                        listView.setAdapter(new ImagesAdapter(mContext, bitmapArrayList));
                        //imagesAdapter.setItems(bitmapArrayList);
                        Toast.makeText(getApplicationContext(),
                                "Image Download Successful",
                                Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(getApplicationContext(),
                                "Error in Downloading",
                                Toast.LENGTH_SHORT).show();
                    }

                    break;
            }
            super.onReceiveResult(resultCode, resultData);
        }

    }
}

  • We first ask for the Permission for External Storage. For this, we need to add the WRITE_EXTERNAL_STORAGE permission in the Manifest file.
  • In our edit text we set the URL for the image to be downloaded.
  • On Button click the IntentService is invoked and the url is passed.
  • The IntentService returns the result to the ResultReceiver.
  • In the ResultReceiver we check for the result code.
  • If it’s a success we add the bitmap to the ListView Adapter and update it.

The code for the ImagesAdapter.java class is given below:


package com.journaldev.androidintentserviceresultreceiver;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

public class ImagesAdapter extends ArrayAdapter<Bitmap> {

    private Context mContext;
    private List<Bitmap> bitmapList;

    public ImagesAdapter(@NonNull Context context, ArrayList<Bitmap> list) {
        super(context, R.layout.listview_item_row, list);
        mContext = context;
        bitmapList = list;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        if (convertView == null)
            convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item_row, parent, false);

        Bitmap bitmap = bitmapList.get(position);

        ImageView image = convertView.findViewById(R.id.imageView);
        image.setImageBitmap(bitmap);

        return convertView;
    }


    @Override
    public int getCount() {
        return bitmapList.size();
    }
}

Android ResultReceiver App Output

The output of the above application in action is given below:

android ResultReceiver App

This brings an end to this tutorial. You can download the final AndroidIntentServiceResultReceiver project from the link below:

You can also download Android Studio project code from our GitHub Repository.

Comments

  1. Pranjul Dhiman says:

    public class MyReciever extends BroadcastReceiver {
    ActivityRecognizedService service;

    public MyReciever() {

    }

    @Override

    public void onReceive(Context context, Intent intent) {

    service = new ActivityRecognizedService();
    ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
    Log.i(MyService.class.getSimpleName(), “Service Stops! Oooooooooooooppppssssss!!!!”);
    if (intent.getAction().equals(“activity_intent”)) {
    handleUserActivity(result.getProbableActivities(), context);
    context.startService(new Intent(context, MyService.class));

    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

    context.startForegroundService(new Intent(context, MyService.class));
    } else {
    context.startService(new Intent(context, MyService.class));
    }

    }

    private void handleUserActivity(List probableActivities, Context context) {

    for (DetectedActivity activity : probableActivities) {

    if (activity.getType() == DetectedActivity.WALKING) {
    if (activity.getConfidence() >= 30) {
    Log.e(“walking::—“, “yes”);

    } else {
    Log.e(“walking::—“, “NOT yes”);

    }
    }

    }

    }

    }
    This is my code but I want to start an activity in this but not a single toast is working in this

Leave a Reply

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

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages