I wrote a simple class that extends BroadcastReceiver to handle an incoming call and get the caller's number. Now I want to display that number in a popup window or something similar. I've tried to display an alert dialog or open an activity but my app crashed. Then I read that it's not a good idea to start dialog from a BroadcastReceiver class. I need you to advice me how to correctly display the caller's number on the screen when there's an incoming call. This is my Broadcast Receiver class:
package com.example.nrsearch;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallReceiver extends BroadcastReceiver {
public CallReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CallReceiverBroadcast", "onReceive() is called. ");
TelephonyManager teleMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener psl = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.i("CallReceiverBroadcast", "onCallStateChanged() is called. ");
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.i("CallReceiverBroadcast", "Incoming call caught. Caller's number is " + incomingNumber + ".");
}
}
};
teleMgr.listen(psl, PhoneStateListener.LISTEN_CALL_STATE);
teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
}
}
If you want to show a dialog from inside your onReceive of the BroadcastReceiver, you have to start a transparent activity with an alert dialog and NEVER called setContentView(). The activity will have an transparent view and only the alert dialog will show..
Your Broadcast Receiver onReceive
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CallReceiverBroadcast", "onReceive() is called. ");
TelephonyManager teleMgr =(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener psl = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.i("CallReceiverBroadcast", "onCallStateChanged() is called. ");
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Log.i("CallReceiverBroadcast", "Incoming call caught. Caller's number is " +incomingNumber + ".");
//start activity which has dialog
Intent i=new Intent(context,DialogActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
};
teleMgr.listen(psl, PhoneStateListener.LISTEN_CALL_STATE);
teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
}
And your DiaLogActivity
public class DialogActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//dont call setcontent view
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?").setCancelable(
false).setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
}).setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
I created a IncomingCallService
service that extends from BroadcastReceiver
to handle an incoming call and get the caller's number. Now I displayed that Incoming caller number in a popup window like TrueCaller. Its working fine me. Hope it should helpful for you. Please try and let me know. Thanks
CallReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
public class CallReceiver extends BroadcastReceiver {
static String IncomingNumber;
@Override
public void onReceive(final Context context, Intent intent) {
TelephonyManager teleMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener psl = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
IncomingNumber = incomingNumber;
Log.i("CallReceiverBroadcast", "Incoming call caught. Caller's number is " + incomingNumber + ".");
Intent i = new Intent(context, IncomingCallService.class);
context.startService(i);
case TelephonyManager.CALL_STATE_IDLE:
Log.i("CallReceiverBroadcast", "CALL_STATE_IDLE");
IncomingCallService.clearView(context);
// Call Disconnected
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.i("CallReceiverBroadcast", "CALL_STATE_OFFHOOK");
IncomingCallService.clearView(context);
// Call Answer Mode
break;
}
}
};
teleMgr.listen(psl, PhoneStateListener.LISTEN_CALL_STATE);
teleMgr.listen(psl, PhoneStateListener.LISTEN_NONE);
}
}
IncomingCallService.java:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
public class IncomingCallService extends Service {
static View view = null;
static WindowManager wm;
static LayoutInflater inflater;
static WindowManager.LayoutParams params;
private static TextView txtIncomingnumber;
static boolean processingAction = false;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onCreate();
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, 350,
WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.TOP;
params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.activity_main,null);
wm.addView(view, params);
txtIncomingnumber = (TextView)view.findViewById(R.id.txtIncomingnumber);
txtIncomingnumber.setText("You have Incoming Call from " + CallReceiver.IncomingNumber);
return START_STICKY;
}
public static void clearView(Context context) {
wm = (WindowManager) context.getSystemService(WINDOW_SERVICE);
if(view != null) {
if(view.isEnabled()){
wm.removeView(view);
view = null;
}
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:background="#0090FF"
android:padding="10dp"
android:keepScreenOn="true" >
<TextView
android:id="@+id/txtIncomingnumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="Incoming Call Number"
android:textColor="#fff" />
</RelativeLayout>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stackoverflow"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" ></uses-permission>
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".CallReceiver" >
<intent-filter android:priority="99999">
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<activity
android:name="com.stackoverflow.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".IncomingCallService">
</service>
</application>
</manifest>