Skip to content Skip to sidebar Skip to footer

Listen To Calls Broadcast Receiver In Android Pie

I'm trying to make an app listen to calls (incoming and outgoing), what I have done for now is just register the receiver in the manifest, which worked perfectly in Android below 9

Solution 1:

i also created a CallReceiver :-

publicclassCallReceiverextendsBroadcastReceiver {

    privatestatic int lastState = TelephonyManager.CALL_STATE_IDLE;
    privatestaticDate callStartTime;
    privatestaticboolean isIncoming;
    privatestaticString savedNumber;
    publicstaticMyCallsAppDatabase myCallsAppDatabase;

    @OverridepublicvoidonReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
            savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
        } else {
            String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
            Stringnumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
            int state = 0;
            if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                state = TelephonyManager.CALL_STATE_IDLE;
            } elseif (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                state = TelephonyManager.CALL_STATE_OFFHOOK;
            } elseif (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                state = TelephonyManager.CALL_STATE_RINGING;
            }
            onCallStateChanged(context, state, number, intent);
        }
    }

    publicvoidonCallStateChanged(Context context, int state, Stringnumber, Intent intent) {
        if (lastState == state) {
            //No change, debounce extrasreturn;
        }
        switch (state) {
            caseTelephonyManager.CALL_STATE_RINGING:
                isIncoming = true;
                callStartTime = newDate();
                onIncomingCallStarted(context, number, callStartTime, intent);
                break;
            caseTelephonyManager.CALL_STATE_OFFHOOK:
                //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on themif (lastState != TelephonyManager.CALL_STATE_RINGING) {
                    isIncoming = false;
                    callStartTime = newDate();
                    onOutgoingCallStarted(context, number, callStartTime, intent);
                }
                break;
            caseTelephonyManager.CALL_STATE_IDLE:
                //Went to idle-  this is the end of a call.  What type depends on previous state(s)if (lastState == TelephonyManager.CALL_STATE_RINGING) {
                    //Ring but no pickup-  a missonMissedCall(context, number, callStartTime, intent);
                } elseif (isIncoming) {
                    onIncomingCallEnded(context, number, callStartTime, newDate(), intent);
                } else {
                    onOutgoingCallEnded(context, number, callStartTime, newDate(), intent);
                }
                break;
        }
        lastState = state;
        Intent intent1 = newIntent("CallApp");
        context.sendBroadcast(intent1);
    }

    protectedvoidonIncomingCallStarted(Context ctx, Stringnumber, Date start, Intent intent) {
//        Toast.makeText(ctx, "calling from " + number, Toast.LENGTH_SHORT).show();
    }

    protectedvoidonOutgoingCallStarted(Context ctx, Stringnumber, Date start, Intent intent) {
//        Toast.makeText(ctx, "calling to " + number, Toast.LENGTH_SHORT).show();
    }

    protectedvoidonIncomingCallEnded(Context ctx, Stringnumber, Date start, Date end, Intent intent) {
//        Toast.makeText(ctx, "calling from " + number + " ended ", Toast.LENGTH_SHORT).show();saveData(ctx, number, intent, "Incoming Call");
    }

    protectedvoidonOutgoingCallEnded(Context ctx, Stringnumber, Date start, Date end, Intent intent) {
//        Toast.makeText(ctx, "calling to " + number + " ended ", Toast.LENGTH_SHORT).show();saveData(ctx, number, intent, "Outgoing Call");
    }

    protectedvoidonMissedCall(Context ctx, Stringnumber, Date start, Intent intent) {
//        Toast.makeText(ctx, "missed call from " + number + " sim ", Toast.LENGTH_SHORT).show();saveData(ctx, number, intent, "Missed Call");
    }

    @SuppressLint("ServiceCast")
    protectedvoidsaveData(Context ctx, Stringnumber, Intent intent, String callType) {

        myCallsAppDatabase = Room.databaseBuilder(ctx, MyCallsAppDatabase.class, "calldb")
                .allowMainThreadQueries()
                .build();

        number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
        number = filterNumber(number);
        SimpleDateFormat dateFormat = newSimpleDateFormat("yyyy-MM-dd hh:mm:ss aaa");
        String dateString = dateFormat.format(newDate(System.currentTimeMillis()));
        CallLog callLog = newCallLog();
        callLog.setMobile(number);
        callLog.setCallType(callType);
        callLog.setTime(dateString);
        myCallsAppDatabase.myCallDao().addCallDetails(callLog);
    }
}

in Manifest.xml file :-

<receiverandroid:name=".broadcaestReceiver.CallReceiver"><intent-filter><actionandroid:name="android.intent.action.PHONE_STATE" /></intent-filter></receiver>

Solution 2:

Change code in Manifest file as below and setPriority to high. I thinks this menifest code needs when the app is in background.

<receiverandroid:name=".MyReceiver"><intent-filterandroid:priority="1000"><actionandroid:name="android.intent.action.PHONE_STATE" /><actionandroid:name="android.intent.action.NEW_OUTGOING_CALL" /></intent-filter></receiver>

This programatic code needs to wake ups the Reciever when app is foreground ie. when the the User is dealing with the actions of BroadcasteReciever from Activity. (The Reciever needs to registerReceiver() in onResume() && unregisterReceiver() in onDestroy() )

IntentFilterfilter=newIntentFilter();
 filter.addAction("android.intent.action.PHONE_STATE");
 filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
 filter.setPriority(1000);

 BroadcastReceiverreceiver=newBroadcastReceiver() {
    @OverridepublicvoidonReceive(Context context, Intent intent) {
            CallListenerService.this.onReceive(intent);
    }
};
registerReceiver(receiver, filter);

Solution 3:

Which android device are you using? I had also encountered such an error which broadcasts are received only when the app is running. Then I discovered that my device is in power saving mode which restricts broadcast and we can customize these settings for specific app in settings> Battery Management. My device is Honor 9 lite with android version Pie. If the problem still persists, try to make a toast as first line of onReceive() method in broadcast receiver. if you receive the toast, your app is receiving broadcasts but problem will be with in your code.

Try to run the same code in different devices. May be the problem would be with your device settings.

Post a Comment for "Listen To Calls Broadcast Receiver In Android Pie"