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.
Table of Contents
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 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="https://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="https://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.
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:
This brings an end to this tutorial. You can download the final AndroidIntentServiceResultReceiver project from the link below:
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