Broadcast receiver not working when closed app

Viewed 670

When the incoming call to the phone popup on the screen. The application is running when it is open. However, when I close the application completely, the phone does not show a popup even though there is a voice call. The broadcast receiver does not work after the application is closed.

My device is Xiaomi Mi8

This is my code:

public class CallBarring extends BroadcastReceiver {

    private CustomDialog dialog;
    private TelephonyManager telephonyManager;
    private PhoneStateListener listener;
    private Context context;
    private Button btnEndCall;
    private TextView incomingNumberName;
    private List<String> data;

    final NumberInfo numberInfo = new NumberInfo();
    Retrofit retrofit = NetworkClient.getRetrofitClient();
    NumberAPI numberAPI = retrofit.create(NumberAPI.class);
    @Override
    public void onReceive(Context context, Intent intent) {

        if (!intent.getAction().equals("android.intent.action.PHONE_STATE"))
            return;

        else {
            this.context = context;
            if(dialog == null){
                dialog = new CustomDialog(context);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
                }else{
                    dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
                }
                dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
                dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
                        WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
                        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
                dialog.show();
            }
            // Fetch the number of incoming call
            telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            listener = new PhoneStateListener() {
                @Override
                public void onCallStateChanged(int state, String incomingNumber) {
                    String stateString = "N/A";
                    switch (state) {
                        case TelephonyManager.CALL_STATE_IDLE:
                            stateString = "Idle";
                            dialog.dismiss();
                            break;
                        case TelephonyManager.CALL_STATE_OFFHOOK:
                            stateString = "Off Hook";
                            dialog.dismiss();
                            break;
                        case TelephonyManager.CALL_STATE_RINGING:
                            stateString = "Ringing";
                            dialog.show();
                            break;
                    }
                }
            };

            telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
            telephonyManager.listen(new PhoneStateListener(){
                @Override
                public void onCallStateChanged(int state, String incomingNumber) {
                    super.onCallStateChanged(state, incomingNumber);
                    System.out.println("incomingNumber : "+incomingNumber);
                    fetchUserInfo(incomingNumber);


                }
            },PhoneStateListener.LISTEN_CALL_STATE);

        }
    }
2 Answers

Many android device has power manager and dose mode concept. so background functionalities get stop when app is in background.

You can use foreground service to register you BroadcastReceiver to listen PHONE_STATE.

You seem to be registering your broadcast receiver in an Activity (I'm assuming). This means that your receiver only works when the Activity is alive. But when the activity dies, the receiver gets unregistered and so won't listen for anything.

You need to register the receiver in the Manifest instead. That way, even when your app is closed, your receiver receives PHONE_STATE events and can fire off your logic.

<receiver
    android:name=".CallBarring"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>

docs: manifest declared receivers

Related