如何从 BroadcastReceiver 更新 RecyclerView?

How to update RecyclerView from BroadcastReceiver?

AndroidManifest.xml 我有一个 BroadcastReceiver:

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

在我的 MainActivity 中,我 RecyclerView 列出了收到的短信。

我的问题是 - 我如何从我的 BroadcastReceiver "SmsMonitor" 更新 RecyclerView 以防在应用程序 运行 时收到新的短信?

UPD:我的意思是我需要针对两种状态的解决方案——针对 运行 应用程序和当应用程序不是 运行 时的状态,在一个接收器中。因为我必须在 phone 工作时一直接收 SMS。如果应用程序是 运行 我想更新 RecyclerView.

您的 MainActivityFragment 中还需要有 BrodcastReceiver 以及承载 RecyclerViewBrodcastReceiver。这样当收到新的短信时,您可以调用 RecyclerView 适配器上的 notifyDataSetChanged 来更新它。

在您的 Activity 中声明一个 BroadcastReceiver,如下所示。这可以是 MainActivity class 的内部 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
                }
            }
       }
}

现在在 MainActivityonCreate 函数中创建此 BroadcastReceiver 的实例并注册接收器。

您需要先在 Activity 中请求短信许可,如下所示。

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);
    }
}

不要忘记在 MainActivityonDestroy 函数中注销接收器。

希望对您有所帮助!

更新

根据此答案下方的评论,您有两种情况。

案例 1. 应用 运行ning.
情况2.应用不是运行ning.

对于情况 1:如上所示的本地 BroadcastReceiver 足以在新短信到达时立即更新 RecyclerView。当您处理 MainActivity 中的 BroadcastReceiver 时,这应该不是问题,因为您有对 RecyclerView 的引用。

现在案例 2:如果您能够检测到任何新的 SMS 到达,您可以将收到的新 SMS 保存在您的本地数据库中。您的应用程序需要有一个 SQLite 数据库,它将存储所有 SMS,并且应用程序中的 RecyclerView 应该从存储 SMS 的数据库 table 中填充数据。我希望你明白这个想法 - 只需将 SMS 存储在与你的应用程序关联的本地数据库中,当你 运行 应用程序并启动 MainActivity 时,从你的本地数据库读取 SMS 并将它们显示在你的RecyclerView

我尝试通过Service来做,但是没有成功。 但我找到了简单的解决方案:

我还有BroadcastReceiverSmsMonitor,注册在AndroidManifest.xml

在我创建 RecyclerAdapter:

实例的那一刻
mainAdapter = new MainAdapter(this);

之后我又注册了一个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);

setInitialData() 中,我重新创建了 RecyclerView 的所有数据列表。

现在我有两个独立工作的 BroadcastReceiver。首先处理 AndroidManifest.xml 中的 BroadcastReceiver,然后处理在 MainActivity 中注册的 BroadcastReceiver