简体   繁体   中英

How to send a data from a broadcast receiver to fragment?

How to send a data from a broadcast receiver to fragment? Here I want to send the phonenumber (OriginatingAddress) to another fragment.

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

Just register another Broadcast receiver in your Fragment. Note code below works when your Fragment is attached to Activity and are in foreground.

If you want to send data to Fragment when your app is not running you will need to show notification on status bar and attach your data in pendingIntent of notification. As a target you need to specify your Activity class that holds Fragment of interest and then manually extract data in Activity's onCreate and pass it to Fragment.

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

The reason we register and unregister Broadcast receiver in onResume and onPause methods is because we don't want Fragment to receive data and act upon that when is it being in foreground. More in this link

In your BroadcastReceiver:

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

There can be two approaches to send data to Fragment in the current scenario.

Approach One:

You can register the BroadcastReceiver to the activity that is hosting the Fragment and after receiving the Data in onReceive() you can call the Fragment method from an Activity like below:

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

Approach Two:

You can directly register the BroadcastReceiver in Fragment and then call the fragment method defined there like below:

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

and then in onCreateView() Register BroadcastReceiver in Fragment like this :

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

and then in onDestroyView() unRegister BroadcastReceiver in Fragment like this :

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

Keep In Mind:

Fragment lifecycle will play an important role here. For receiving the Broadcast your Fragment needs to be Created and visible to the User. When Fragment will be destroyed or not Visible to the User then you won't receive the Broadcast.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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