Skip to content Skip to sidebar Skip to footer

How To Detect Phone Call Broadcast Receiver In Android

I am building an application in android, which will perform an action when any phone call will come in my phone. I have tried this with broadcast receiver and phone state listener.

Solution 1:

Solution 2:

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

Its working!!

Solution 3:

Here is an example from a Chinese BBS.

publicclassPhoneStatReceiverextendsBroadcastReceiver{        

        privatestaticfinalStringTAG="PhoneStatReceiver"; 

        privatestaticbooleanincomingFlag=false;

        privatestaticStringincoming_number=null;



        @OverridepublicvoidonReceive(Context context, Intent intent) {

                //如果是拨打电话if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){                        

                        incomingFlag = false;

                        StringphoneNumber= intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);        

                        Log.i(TAG, "call OUT:"+phoneNumber);                        

                }else{                        

                        //如果是来电TelephonyManagertm= 

                            (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);                        



                        switch (tm.getCallState()) {

                        case TelephonyManager.CALL_STATE_RINGING:

                                incomingFlag = true;//标识当前是来电

                                incoming_number = intent.getStringExtra("incoming_number");

                                Log.i(TAG, "RINGING :"+ incoming_number);

                                break;

                        case TelephonyManager.CALL_STATE_OFFHOOK:                                

                                if(incomingFlag){

                                        Log.i(TAG, "incoming ACCEPT :"+ incoming_number);

                                }

                                break;



                        case TelephonyManager.CALL_STATE_IDLE:                                

                                if(incomingFlag){

                                        Log.i(TAG, "incoming IDLE");                                

                                }

                                break;

                        } 

                }

        }

}

Register it in your AndroidManifest.xml.

<receiverandroid:name=".filter.PhoneStatReceiver"><intent-filter><actionandroid:name="android.intent.action.PHONE_STATE"/><actionandroid:name="android.intent.action.NEW_OUTGOING_CALL" /></intent-filter></receiver><uses-permissionandroid:name="android.permission.READ_PHONE_STATE"></uses-permission><uses-permissionandroid:name="android.permission.PROCESS_OUTGOING_CALLS"></uses-permission>

Solution 4:

I have read here https://gist.github.com/ftvs/e61ccb039f511eb288ee

It works fine for me. Android version 5.0.

My task had consisted next.

My application must observer all calls events. And distinguish incoming, outgoing calls. Any time when the incoming call has finished it must create the new outgoing call. Phone number specified in settings number. This phone number is the number of gate controller. (https://www.pal-es.com/3g-eng) It is cheating for opening automatic gates for users, not in the whitelist. This application works into a standalone smartphone and is used decided for this task only.

And some features you can find here too.

For example:

  1. how update textView value from Runnable thread
  2. I make outgoing call not from BroadcastReceiver class, because it impossible. It need make from MainActivity. Havy fun))) Try it.

MainActivity.java

package com.example.root.test02;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    https://androidexample.com/Introduction_To_Broadcast_Receiver_Basics/index.php?view=article_discription&aid=60&aaid=85
    https://androidexample.com/Incomming_Phone_Call_Broadcast_Receiver__-_Android_Example/index.php?view=article_discription&aid=61
    https://stackoverflow.com/questions/5990590/how-to-detect-phone-call-broadcast-receiver-in-android
    https://stackoverflow.com/questions/1083527/how-to-block-calls-in-android
    https://stackoverflow.com/questions/5571249/how-do-i-retrieve-the-incoming-phone-calls-number-while-ringing-and-store-it-in
    https://gist.github.com/ftvs/e61ccb039f511eb288ee
*/publicclassMainActivityextendsAppCompatActivity {

    public TextView textView;
    publicStringMetallurgTelNumber="+79091112233"; // need redirect calls to this phone number@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PhonecallReceiverrv=newPhonecallReceiver();

        ThreadmyThread=newThread(myRunnable);
        myThread.start();

        textView = (TextView) findViewById(R.id.incoming_calls_log);
        textView.setText("Журнал входящих звонков:");

        TextViewversion= (TextView) findViewById(R.id.tvVersion);
        version.setText("v3.0");
    }

    publicvoidCallToMetallurgGates()
    {
        IntentcallIntent=newIntent(Intent.ACTION_CALL);
        callIntent.setData(Uri.parse("tel:" + MetallurgTelNumber));
        startActivity(callIntent);
    }


    RunnablemyRunnable=newRunnable() {
        @Overridepublicvoidrun()
        {
            while (true)
            {
                try
                {
                    Thread.sleep(50); // Waits for 1 second (1000 milliseconds)if (MyProperties.getInstance().NewIncomingCall)
                    {
                        CallToMetallurgGates();
                        MyProperties.getInstance().NewIncomingCall = false;
                        MyProperties.getInstance().CallId++;

                        Stringdbg_str= Integer.toString(MyProperties.getInstance().CallId) + " " + MyProperties.getInstance().PhoneNumber;

                        textView.post(newRunnable() {
                            publicvoidrun() {
                                SimpleDateFormatsdf=newSimpleDateFormat("dd.MM.yyyy HH:mm:ss");
                                StringcurrentDateandTime= sdf.format(newDate());
                                textView.append("\n" + currentDateandTime);
                                textView.append("\n(" + Integer.toString(MyProperties.getInstance().CallId) + "): " + MyProperties.getInstance().PhoneNumber);
                                textView.append("\nЗвоню на ворота: " + MetallurgTelNumber);
                            }
                        });


                        Thread.sleep(5000); // Waits for 1 second (1000 milliseconds)
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
    };
}

PhonecallReceiver.java

package com.example.root.test02;

import java.util.Date;

import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;


import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.util.Date;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;

import com.example.root.test02.MainActivity;



publicclassPhonecallReceiverextendsBroadcastReceiver {

        // как только происходит входящий звонокprotectedvoidonIncomingCallStarted(Context ctx, Stringnumber, Date start) {
        Log.d("onIncomingCallStarted",number);
    }

        // как только снимается (hook off) трубка и делается исходящийprotectedvoidonOutgoingCallStarted(Context ctx, Stringnumber, Date start) {
        Log.d("onOutgoingCallStarted",number);
    }

        // когда нажимается кнопка Завершить на входящем звонкеprotectedvoidonIncomingCallEnded(Context ctx, Stringnumber, Date start, Date end) {
        Log.d("onIncomingCallEnded",number);
        MyProperties.getInstance().NewIncomingCall = true;
        MyProperties.getInstance().PhoneNumber = number + " завершенный";
    }

        // когда нажимается кнопка Завершить на исходящем звонкеprotectedvoidonOutgoingCallEnded(Context ctx, Stringnumber, Date start, Date end) {
        Log.d("onOutgoingCallEnded",number);
    }

        // когда не сняли трубку при входящем звонке (пропуск звонка)protectedvoidonMissedCall(Context ctx, Stringnumber, Date start) {
        MyProperties.getInstance().NewIncomingCall = true;
        MyProperties.getInstance().PhoneNumber = number + " пропущенный";

    }

    //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 uppublicvoidonCallStateChanged(Context context, int state, Stringnumber) {
        if(lastState == state){
            //No change, debounce extrasreturn;
        }
        switch (state) {
            caseTelephonyManager.CALL_STATE_RINGING:
                isIncoming = true;
                callStartTime = newDate();
                savedNumber = number;
                onIncomingCallStarted(context, number, callStartTime);
                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, savedNumber, callStartTime);
                }
                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, savedNumber, callStartTime);
                }
                elseif(isIncoming){
                    onIncomingCallEnded(context, savedNumber, callStartTime, newDate());
                }
                else{
                    onOutgoingCallEnded(context, savedNumber, callStartTime, newDate());
                }
                break;
        }
        lastState = state;
    }

    privatestatic int lastState = TelephonyManager.CALL_STATE_IDLE;
    privatestaticDate callStartTime;
    privatestaticboolean isIncoming;
    privatestaticString savedNumber;  //because the passed incoming is only valid in ringingpublicvoidonReceive(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);
            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);
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.example.root.test02">

    **<uses-permissionandroid:name="android.permission.READ_PHONE_STATE" /><uses-permissionandroid:name="android.permission.PROCESS_OUTGOING_CALLS"/><uses-permissionandroid:name="android.permission.CALL_PHONE" />**

    <applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.AppCompat.Light"><activityandroid:name=".MainActivity"><intent-filter><actionandroid:name="android.intent.action.MAIN" /><categoryandroid:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

        **<receiverandroid:name="com.example.root.test02.PhonecallReceiver"><intent-filter><actionandroid:name="android.intent.action.PHONE_STATE" /></intent-filter></receiver>**
    </application></manifest>

MyProperties.java

package com.example.root.test02;

publicclassMyProperties {
    privatestatic MyProperties mInstance= null;

    publicbooleanNewIncomingCall=false;
    publicintCallId=0;
    publicStringPhoneNumber="";


    protectedMyProperties(){}

    publicstaticsynchronized MyProperties getInstance() {
        if(null == mInstance){
            mInstance = newMyProperties();
        }
        return mInstance;
    }
}

Solution 5:

Hopefully this will serve your purpose,

Please check this out.

<receiverandroid:name="ClassName"><intent-filter><actionandroid:name="android.intent.action.ANSWER">/action>
  </intent-filter></receiver>

Post a Comment for "How To Detect Phone Call Broadcast Receiver In Android"