简体   繁体   English

如何从BroadcastReceiver更新RecyclerView?

[英]How to update RecyclerView from BroadcastReceiver?

In AndroidManifest.xml I have a BroadcastReceiver : AndroidManifest.xml我有一个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. 在我的MainActivity ,我具有RecyclerView以及接收到的SMS列表。

My question is - How I can update the RecyclerView from my BroadcastReceiver "SmsMonitor" in case new SMS received when the application is running? 我的问题是-如果在应用程序运行时收到新的SMS,如何从BroadcastReceiver “ SmsMonitor”更新RecyclerView

UPD: I mean I need solution for both states - for running application AND for state when application is not running, in one receiver. UPD:我的意思是我需要在一个接收器中同时解决这两种状态-运行应用程序以及运行未运行状态的问题。 Because I have to take SMS all time while phone is working. 因为我必须在电话工作时始终接收短信。 And in case the application is running I want to update RecyclerView . 如果应用程序正在运行,我想更新RecyclerView

You need to have the BrodcastReceiver in your MainActivity or Fragment as well which hosts the RecyclerView . 您还需要在MainActivityFragment中托管BrodcastReceiver ,以托管RecyclerView So that when the new SMS is received, you can call the notifyDataSetChanged on the adapter of your RecyclerView to update it. 因此,在收到新短信时,你可以调用notifyDataSetChanged你的适配器上RecyclerView更新它。

Declare a BroadcastReceiver in your Activity like the following. 像下面这样在您的Activity声明一个BroadcastReceiver This can be an inner class of your MainActivity class. 这可以是MainActivity类的内部类。

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. 现在,在MainActivityonCreate函数中创建此BroadcastReceiver的实例并注册接收器。

You need to ask for SMS permission first in your Activity like the following. 您需要先在“ Activity请求SMS许可,如下所示。

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 . 不要忘记在MainActivityonDestroy功能中注销接收器。

Hope that helps! 希望有帮助!

Update 更新资料

Based on the comment below this answer, you have two cases. 根据此答案下方的评论,您有两种情况。

Case 1. The app is running. 情况1.该应用程序正在运行。
Case 2. The app is not running. 情况2。应用未运行。

For case 1: The local BroadcastReceiver like I shown above, is good enough to update the RecyclerView instantly when a new SMS arrives. 对于情况1:如上所示,本地BroadcastReceiver足以在新SMS到达时立即更新RecyclerView As you are handling the BroadcastReceiver from the MainActivity this should not be a problem, as you have the reference to your RecyclerView . 当您从MainActivity处理BroadcastReceiver ,这应该没有问题,因为您可以引用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. 现在针对情况2:如果您能够检测到任何新的SMS到达,则可以将收到的新SMS保存在本地数据库中。 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. 您需要为您的应用程序提供一个SQLite数据库,该数据库将存储所有SMS,并且应用程序中的RecyclerView应该从存​​储SMS的数据库表中填充数据。 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 . 我希望您能想到这一点-只需将SMS存储在与应用程序关联的本地数据库中,然后在运行该应用程序并启动MainActivity ,从本地数据库中读取SMS并将其显示在RecyclerView

I tried to do it through the Service , but I did not succeed. 我试图通过Service来做到这一点,但没有成功。 But I found simple solution: 但是我找到了简单的解决方案:

I still have BroadcastReceiver SmsMonitor , registered in AndroidManifest.xml 我仍然在AndroidManifest.xml注册了BroadcastReceiver SmsMonitor

And in the point where I create instance of my RecyclerAdapter : 在创建RecyclerAdapter实例的时候:

mainAdapter = new MainAdapter(this);

After this I register another BroadcastReceviver : 之后,我注册了另一个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 . setInitialData()我为RecyclerView重新创建所有数据列表。

And now I have two independently working BroadcastReceiver . 现在我有两个独立工作的BroadcastReceiver The first working the BroadcastReceiver from the AndroidManifest.xml , and then working the BroadcastReceiver registered in MainActivity. 第一个工作BroadcastReceiverAndroidManifest.xml ,然后工作BroadcastReceiver在MainActivity注册。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM