使用ResultReceiver的Android IntentService
在本教程中,我们将在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(); } }