使用ResultReceiver的Android IntentService

时间:2020-02-23 14:29:00  来源:igfitidea点击:

在本教程中,我们将在Android应用程序中将IntentService与ResultReceiver结合使用。
我们将创建一个应用程序,该应用程序将从url下载图像,并将其存储并添加到ListView中。

Android ResultReceiver

Android ResultReceiver用于接收某人的回调结果。
它与BroadcastReceiver不同。

BroadcastReceiver接收各种消息。
它也可以从活动外部接收消息。

ResultReceiver专门用于接收应用程序内部的消息。
然后,它可以从其中定义的结果类型列表中检查结果类型。
基于此,它可以将信息转发给活动。

IntentService可以使用send方法将数据传递给ResultReceiver。

ResultReceiver具有onReceiveResult回调方法,该方法在接收到新结果时被调用。
根据onReceiveResult中的结果代码,它执行操作。

在下面的部分中,我们将创建一个应用程序,在该应用程序中,我们从IntentService中的url下载图像,然后Service将结果发送到ResultReceiver,其中根据结果代码(类型),我们将执行必要的操作。

Android ResultReceiver布局代码

下面给出了" activity_main.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="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>

下面给出了IntentService.java类的代码:

package com.theitroad.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() + "/theitroadFile.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();
      }
  }
}

其中我们通过Intent下载从Activity获得的url字符串,并将其存储在文件中。
稍后我们将其发送到ResultReceiver。

不要忘记在列表文件中设置服务。
还添加Internet权限。

在我们的MainActivity.java中,执行以下操作:

package com.theitroad.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/2015/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);
      }

  }
}
  • 我们首先要求外部存储许可。
    为此,我们需要在列表文件中添加WRITE_EXTERNAL_STORAGE权限。

  • 在我们的编辑文本中,我们设置要下载图像的URL。

  • 在"按钮"上单击,将调用IntentService并传递url。

  • IntentService将结果返回到ResultReceiver。

  • 在ResultReceiver中,我们检查结果代码。

  • 如果成功,则将位图添加到ListView适配器并进行更新。

下面给出了ImagesAdapter.java类的代码:

package com.theitroad.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();
  }
}