【问题标题】:How to send a data from a broadcast receiver to fragment?如何将数据从广播接收器发送到片段?
【发布时间】:2018-11-13 06:56:28
【问题描述】:

如何将数据从广播接收器发送到片段?在这里,我想将电话号码(OriginatingAddress)发送到另一个片段。

public void onReceive(Context context, Intent intent) {
    Bundle intentExtras = intent.getExtras();
    if (intentExtras != null) {
        Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
        String smsMessageStr = "";
        for (int i = 0; i < sms.length; ++i) {
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);

            String smsBody = smsMessage.getMessageBody().toString();
            String phonenumber = smsMessage.getOriginatingAddress();

            smsMessageStr += "SMS From: " + phonenumber + "\n";
            smsMessageStr += smsBody + "\n";                                
        }                                                                  
    }
}

【问题讨论】:

  • Intent intent1 = new Intent(context, MainActivity.class);&lt;br/&gt; intent1.putExtra("phonenumber", address); intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent1); context.sendBroadcast(intent1);
  • 以上内容使我可以将数据从接收器发送到活动,但我坚持将其发送到片段

标签: android android-fragments broadcastreceiver android-broadcast android-broadcastreceiver


【解决方案1】:

在当前场景下,可以有两种方式向 Fragment 发送数据。

方法一:

您可以将 BroadcastReceiver 注册到托管 Fragment 的 Activity,在接收到 onReceive() 中的数据后,您可以从 Activity 调用 Fragment 方法,如下所示:

ExampleFragment fragment = (ExampleFragment)getFragmentManager().
findFragmentById(R.id.example_fragment);
fragment.<specific_function_name_of_that_fragment>();

方法二:

您可以直接在 Fragment 中注册 BroadcastReceiver,然后调用其中定义的 Fragment 方法,如下所示:

private final BroadcastReceiver broadCastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
          //receive your data here
        }
    };

然后在 onCreateView() 在 Fragment 中注册 BroadcastReceiver,如下所示:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(broadCastReceiver,
                new IntentFilter("YOUR.INTENT.FILTER"));

        return inflater.inflate(R.layout.fragment_sub_categories, container, false);
    }

然后在 onDestroyView() 在 Fragment 中取消注册 BroadcastReceiver,如下所示:

@Override
    public void onDestroyView() {
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadCastReceiver);
        super.onDestroyView();
    }

记住:

片段生命周期将在这里发挥重要作用。为了接收广播,您的片段需要被创建并且对用户可见。当 Fragment 将被销毁或对用户不可见时,您将不会收到广播。

【讨论】:

    【解决方案2】:

    只需在您的 Fragment 中注册另一个广播接收器。当您的 Fragment 附加到 Activity 并处于前台时,下面的注释代码有效。

    如果您想在应用未运行时向 Fragment 发送数据,您需要在状态栏上显示通知并将您的数据附加到通知的 pendingIntent 中。作为目标,您需要指定包含感兴趣的 Fragment 的 Activity 类,然后在 Activity 的 onCreate 中手动提取数据并将其传递给 Fragment。

    在您的片段中:

    // receiver as a global variable in your Fragment class
    private BroadcastReceiver messagesReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null && intent.getExtras() != null) {
                String smsMessageStr = intent.getExtras().getString("smsMessageStr");
                if (smsMessageStr != null && ! smsMessageStr()) {
                    // do what you need with received data
                }
            }
        }
    };
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // ...
    }
    
    @Override
    public void onResume() {
        super.onResume();
        if (getActivity() != null) {
            LocalBroadcastManager.getInstance(getActivity()).registerReceiver(messagesReceiver,
                    new IntentFilter("your_intent_filter"));
        }
    }
    
    @Override
    public void onPause() {
        super.onPause();
        if (getActivity() != null) {
            LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(messagesReceiver);
        }
    }
    

    我们在 onResumeonPause 方法中注册和取消注册广播接收器的原因是因为我们不希望 Fragment 接收数据并在它处于前台时采取行动。更多内容在link

    在您的广播接收器中:

    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();
        if (intentExtras != null) {
            Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
            String smsMessageStr = "";
            for (int i = 0; i < sms.length; ++i) {
                SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);
    
                String smsBody = smsMessage.getMessageBody().toString();
                String phonenumber = smsMessage.getOriginatingAddress();
    
                smsMessageStr += "SMS From: " + phonenumber + "\n";
                smsMessageStr += smsBody + "\n";   
    
                // send data only if we have smsMessageStr
                Intent newIntent = new Intent("your_intent_filter");
                newIntent.putExtra("smsMessageStr", smsMessageStr);
                LocalBroadcastManager.getInstance(this).sendBroadcast(newIntent);                             
            }                                                                  
        }
    }
    

    【讨论】:

    • 听起来很傻,这是我的意图过滤器名称 android.provider.Telephony.SMS_RECEIVED &lt;receiver android:name=".MySMS_Reader"&gt; &lt;intent-filter&gt; &lt;action android:name="android.provider.Telephony.SMS_RECEIVED" /&gt; &lt;/intent-filter&gt; &lt;/receiver&gt;
    • 因为我只收到空值@Marat -Marat
    • 你能帮我找到意图过滤器名称吗?因为我得到空值
    • 不,它是单独的广播接收器,因此具有单独的 IntentFilter。正如您从我的代码中看到的那样,它只是一个字符串。只需将“”中的单词更改为您想要的任何内容。
    • 不,仍然得到空值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多