Search code examples
javaandroidandroid-fragmentsbroadcastreceiver

Notify activity's callback state to fragment


I have a MainActivity which has a boolean variable mMonthlySubscribed. This activity has an onPurchasesUpdated callback method which sets true or false to the mMonthlySubscribed variable. Also loadFragment method to navigate between Fragments.

I have 2 Fragments in my app as FragmentSubscribed and FragmentUnsubscribed. How can i notify that mMonthlySubscribed value has changed to the Fragment.

Currently I'm checking the mMonthlySubscribed value and navigating to the appropriate fragment using below methods. I want to call one of the below methods from my Fragments when onPurchasesUpdated callback is triggered in MainActivity and change boolean mMonthlySubscribed.

((MainActivity) getActivity()).loadFragment(new FragmentUnsubscribed()); 

and

((MainActivity) getActivity()).loadFragment(new FragmentSubscribed());  

Simply, my question is when activity's onPurchasesUpdated callback is triggered, How can I notify this to the current fragment so that I can call above method accordingly.

MainActivity's Callback

    @Override
    public void onPurchasesUpdated(List<Purchase> purchaseList) {

        for (Purchase purchase : purchaseList) {
            if (purchase.getSku().equals(SKU_MONTHLY)) {
                Toast.makeText(getApplicationContext(), "Subscription is valid! - server", Toast.LENGTH_SHORT).show();
                mMonthlySubscribed = true;
            } else {
                Toast.makeText(getApplicationContext(), "Subscription is invalid! - server", Toast.LENGTH_SHORT).show();
                mMonthlySubscribed = false;
            }
        }
        // save state 
        saveSubscriptionStateSharedPreference();

        // todo : notify the current state to the fragment

    }

MainActivity's navigation method

public void loadFragment(Fragment fragment) {
    // load passed fragment within the frame_container of activity_main
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.frame_container, fragment);
    transaction.commit();
}

Solution

  • I managed to get this done using LocalBroadcastManager. I will post my answer for the purpose of being helpful to anyone else who is looking for a solution to this kind of an use case.

    In my MainActivity, I implemented sendMessage() method to send local broadcast.

    private void sendMessage() {
        Log.d("sender", "Broadcasting message subscription state update");
        Intent intent = new Intent("subscription_state");
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
    

    Then in the callback of onPurchasesUpdated() I'm sending the above broadcast message. As given below,

    @Override
    public void onPurchasesUpdated(List<Purchase> purchaseList) {
    
            for (Purchase purchase : purchaseList) {
                if (purchase.getSku().equals(SKU_MONTHLY)) {
                    Log.d(TAG, "Subscription is valid! - server");
                    mMonthlySubscribed = true;
                }
            }
            //// save state and notify the current state to the fragment
            saveSubscriptionStateSharedPreference();
            sendMessage();
    } 
    

    In each Fragment I implemented below listener to listen to the above broadcast message as given below.

    @Override
    public void onStart() {
        super.onStart();
        LocalBroadcastManager.getInstance(activity).registerReceiver(mMessageReceiver,
                new IntentFilter("subscription_state"));
        activity.queryPurchases();
        Log.d("receiver", "Receiver created " + TAG);
    
    }
    
    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // if subscription state is true, load subscribe screens
            if (mMonthlySubscribed)
                activity.loadFragment(new SubscriptionFragment());
            Log.d("receiver", "Subscription state update received " + TAG);
        }
    };
    

    The onReceive() implemented in each fragment will be triggered when broadcast receiver receives a broadcast message.

    Therefore when onPurchasesUpdated() callback method is triggered, MainActivity sends a local broadcast message using sendMessage(). Each fragment listens to this broadcast message and once the message is received, it triggers loadFragment() and navigate to the appropriate fragment.