Search code examples
androiddialogandroid-dialogfragment

Show DialogFragment even when Context changes


I have app in which message is sent and its report is received after sometime through BroadcastReceiver. This report is to be shown to the user through dialog for which I am using DialogFragment as shown below.

myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(firstTime)
            firstTime = false; 

        boolean anyError = false;
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
            case SmsManager.RESULT_ERROR_NO_SERVICE:
            case SmsManager.RESULT_ERROR_NULL_PDU:
            case SmsManager.RESULT_ERROR_RADIO_OFF:
                anyError = true;
                break;
        }

        sent.add(anyError);
        CustomAlertDialogFragment customAlertDialogFragment = CustomAlertDialogFragment.newInstance("Title",logMessage);
        customAlertDialogFragment.show(getActivity().getSupportFragmentManager(),"TAG");
        sent.clear();
    }
};

The code for CustomDialog is below.

public class CustomAlertDialogFragment extends DialogFragment {

    public static CustomAlertDialogFragment newInstance(String title, String content) {
        CustomAlertDialogFragment customAlertDialogFragment = new CustomAlertDialogFragment();
        Bundle args = new Bundle();
        args.putString("title",title);
        args.putString("content", content);
        customAlertDialogFragment.setArguments(args);
        return customAlertDialogFragment;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String title = getArguments().getString("title");
        String content = getArguments().getString("content");
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        // title bar string
        builder.setTitle(title);
        builder.setPositiveButton(R.string.ok, null);

        builder.setMessage(content);
        AlertDialog errorDialog = builder.create();
        // return the Dialog object
        return errorDialog;
    }
}

If the user moves to any other Fragment or Activity meanwhile, the dialog is not shown. It should throw NullPointerException if its not getting context but its not. What can be the possible alternative or solution to this. I have referred other SO questions where members have asked to use notification instead but my requirement is dialog. Please help.


Solution

  • The Dialogue is throwing an exception named window leaked I guess. In your case I think you may think of using the Application class.

    Anyway, you may register the BroadcastReceiver in your Application class for your case, which will receive the broadcast and will show the dialog on demand.

    To retrive the Context you may use getApplicationContext().

    public class MyApplication extends Application {
    
        // Declare the BroadcastReceiver in your Application class
        BroadcastReceiver myReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if(firstTime)
                    firstTime = false; 
    
                boolean anyError = false;
                switch (getResultCode()) {
                    case Activity.RESULT_OK:
                        break;
                    case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    case SmsManager.RESULT_ERROR_NO_SERVICE:
                    case SmsManager.RESULT_ERROR_NULL_PDU:
                    case SmsManager.RESULT_ERROR_RADIO_OFF:
                        anyError = true;
                        break;
                }
    
                sent.add(anyError);
                CustomAlertDialogFragment customAlertDialogFragment = CustomAlertDialogFragment.newInstance("Title",logMessage);
                customAlertDialogFragment.show(getApplicationContext().getSupportFragmentManager(), "TAG");
                sent.clear();
            }
        };
    
        @Override
        public void onResume() {
            super.onCreate();
            // Register the receiver here 
        }
    
        @Override
        public void onPause() {
            super.onCreate();
            // Un-register the receiver here 
        }
    }
    

    To register the Application class in your manifest you need to define the name

    <application
        android:name="Yourpackage.MyApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:logo="@drawable/your_logo"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:icon">
    
        <!-- Your activities -->
    </application>