Search code examples
javaandroidbroadcastreceivertelephonymanager

How to get the caller's number?


I am creating one application,what I am trying is whenever user cut or disconnect call,one alert dialog should appear with caller's number,I followed this tutorial

 public class MyCallReceiver extends BroadcastReceiver {



@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {

         // get the phone number 
        String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
        Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();

        Intent i = new Intent(context, Disp_Alert_dialog.class); 
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.putExtra("Number", incomingNumber);

        context.startActivity(i);
        // This code will execute when the phone has an incoming call



    } else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
            TelephonyManager.EXTRA_STATE_IDLE)
            || intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
                    TelephonyManager.EXTRA_STATE_OFFHOOK)) {
        // This code will execute when the call is disconnected
    //    Toast.makeText(context, "Detected call hangup event", Toast.LENGTH_LONG).show();

    }
}

Solution

  • Here's what you can do:

    To create a dialog box:

    new AlertDialog.Builder(this)
    .setTitle("This is the title")
    .setMessage("This is the message")
    .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) { 
            // when yes is clicked
        }
     })
    .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) { 
            // when no is clicked
        }
     })
    .setIcon(android.R.drawable.ic_dialog_alert)//pic for the icon
     .show();
    

    Manifest

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    
    <!--This part is inside the application-->
        <receiver android:name=".CallReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>
    

    Reusable call detector `

    package com.gabesechan.android.reusable.receivers;
    
    import java.util.Date;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.telephony.TelephonyManager;
    
    public abstract class PhonecallReceiver extends BroadcastReceiver {
    
        //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations
    
        private static int lastState = TelephonyManager.CALL_STATE_IDLE;
        private static Date callStartTime;
        private static boolean isIncoming;
        private static String savedNumber;  //because the passed incoming is only valid in ringing
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            //We listen to two intents.  The new outgoing call only tells us of an outgoing call.  We use it to get the number.
            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);
                String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                int state = 0;
                if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                    state = TelephonyManager.CALL_STATE_IDLE;
                }
                else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                    state = TelephonyManager.CALL_STATE_OFFHOOK;
                }
                else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
                    state = TelephonyManager.CALL_STATE_RINGING;
                }
    
    
                onCallStateChanged(context, state, number);
            }
        }
    
        //Derived classes should override these to respond to specific events of interest
        protected void onIncomingCallStarted(Context ctx, String number, Date start){}
        protected void onOutgoingCallStarted(Context ctx, String number, Date start){}
        protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){}
        protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end){}
        protected void onMissedCall(Context ctx, String number, Date start){}
    
        //Deals with actual events
    
        //Incoming call-  goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
        //Outgoing call-  goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
        public void onCallStateChanged(Context context, int state, String number) {
            if(lastState == state){
                //No change, debounce extras
                return;
            }
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    isIncoming = true;
                    callStartTime = new Date();
                    savedNumber = number;
                    onIncomingCallStarted(context, number, callStartTime);
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on them
                    if(lastState != TelephonyManager.CALL_STATE_RINGING){
                        isIncoming = false;
                        callStartTime = new Date();
                        onOutgoingCallStarted(context, savedNumber, callStartTime);                     
                    }
                    break;
                case TelephonyManager.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 miss
                        onMissedCall(context, savedNumber, callStartTime);
                    }
                    else if(isIncoming){
                        onIncomingCallEnded(context, savedNumber, callStartTime, new Date());                       
                    }
                    else{
                        onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());                                               
                    }
                    break;
            }
            lastState = state;
        }
    }
    

    `

    Functions

    public class CallReceiver extends PhonecallReceiver {
    
        @Override
        protected void onIncomingCallStarted(Context ctx, String number, Date start) {
        }
    
        @Override
        protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
        }
    
        @Override
        protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
        }
    
        @Override
        protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
        }
    
        @Override
        protected void onMissedCall(Context ctx, String number, Date start) {
        }
    
    }