How to update RecyclerView from BroadcastReceiver?

ⅰ亾dé卋堺 提交于 2021-01-28 08:31:04

问题


In AndroidManifest.xml I have a BroadcastReceiver:

<receiver android:name=".SmsMonitor">
    <intent-filter android:priority="-100">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

In my MainActivity, I have RecyclerView with a list of received SMS.

My question is - How I can update the RecyclerView from my BroadcastReceiver "SmsMonitor" in case new SMS received when the application is running?

UPD: I mean I need solution for both states - for running application AND for state when application is not running, in one receiver. Because I have to take SMS all time while phone is working. And in case the application is running I want to update RecyclerView.


回答1:


You need to have the BrodcastReceiver in your MainActivity or Fragment as well which hosts the RecyclerView. So that when the new SMS is received, you can call the notifyDataSetChanged on the adapter of your RecyclerView to update it.

Declare a BroadcastReceiver in your Activity like the following. This can be an inner class of your MainActivity class.

class SMSBroadcastReceiver extends BroadcastReceiver {

    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    private static final String TAG = "SMSBroadcastReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {

            if (intent.getAction() == SMS_RECEIVED) {
                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    // Update your RecyclerView here 
                    // by calling notifyDataSetChanged on the adapter
                }
            }
       }
}

Now create an instance of this BroadcastReceiver in the onCreate function of your MainActivity and register the receiver.

You need to ask for SMS permission first in your Activity like the following.

if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.RECEIVE_SMS}, 0);
} else {
        // register sms receiver
        IntentFilter filter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
        registerReceiver(smsReceiver, filter);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {

    } else {
        // register sms receiver
        IntentFilter filter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
        registerReceiver(smsReceiver, filter);
    }
}

Do not forget to un-register the receiver in the onDestroy function of your MainActivity.

Hope that helps!

Update

Based on the comment below this answer, you have two cases.

Case 1. The app is running.
Case 2. The app is not running.

For case 1: The local BroadcastReceiver like I shown above, is good enough to update the RecyclerView instantly when a new SMS arrives. As you are handling the BroadcastReceiver from the MainActivity this should not be a problem, as you have the reference to your RecyclerView.

Now for Case 2: If you are able to detect any new SMS arrival, you can save the new SMS received in your local database. You need to have an SQLite database for your application which will store all the SMS and the RecyclerView in your application should populate the data from the database table where the SMS are stored. I hope you get the idea - just store the SMS in your local database associated with your application and when you run the application and launch the MainActivity, read the SMS from your local database and show them in your RecyclerView.




回答2:


I tried to do it through the Service, but I did not succeed. But I found simple solution:

I still have BroadcastReceiver SmsMonitor, registered in AndroidManifest.xml

And in the point where I create instance of my RecyclerAdapter:

mainAdapter = new MainAdapter(this);

After this I register another BroadcastReceviver:

BroadcastReceiver br = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        setInitialData();
        mainAdapter.notifyDataSetChanged();
    }
};
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
this.registerReceiver(br, filter);

And in setInitialData() I recreate all list of data for RecyclerView.

And now I have two independently working BroadcastReceiver. The first working the BroadcastReceiver from the AndroidManifest.xml, and then working the BroadcastReceiver registered in MainActivity.



来源:https://stackoverflow.com/questions/54736055/how-to-update-recyclerview-from-broadcastreceiver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!