I am developing a broadcast receiver for incoming calls in Android and on getting incoming calls I want to inflate a pop up over the native incoming call screen.
I completed that code. But now the problem is that in the Android 4.1 (Jelly Bean) API level 17 when a phone rings, the PHONE_STATE
is coming as OFF HOOK
, and if I am calling an activity, it gets called, but the code under it doesn't get executed. I am listing the code:
My broadcast receiver
package com.example.popwindowonincomingcallscreen;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
public class IncomingBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("IncomingBroadcastReceiver: onReceive: ", "flag1");
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
Log.d("IncomingBroadcastReceiver: onReceive: ", state);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)
|| state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Log.d("Ringing", "Phone is ringing");
Intent i = new Intent(context, IncomingCallActivity.class);
i.putExtras(intent);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Wait.oneSec();
context.startActivity(i);
}
}
}
An the activity which I am calling:
import android.app.Activity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View.MeasureSpec;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
public class IncomingCallActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
try {
Log.d("IncomingCallActivity: onCreate: ", "flag2");
*/ After this line, the code is not executed in Android 4.1 (Jelly Bean) only/*
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
Log.d("IncomingCallActivity: onCreate: ", "flagy");
setContentView(R.layout.main);
Log.d("IncomingCallActivity: onCreate: ", "flagz");
String number = getIntent().getStringExtra(
TelephonyManager.EXTRA_INCOMING_NUMBER);
TextView text = (TextView) findViewById(R.id.text);
text.setText("Incoming call from " + number);
}
catch (Exception e) {
Log.d("Exception", e.toString());
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
After
try {
Log.d("IncomingCallActivity: onCreate: ", "flag2");
}
The code is not executing in Android 4.1 (Jelly Bean), but in other versions it is working.
I have tried almost all ways I can do. This code is displaying an translucent activity over the native call screen, and it doesn't block background controls, like picking up the phone. But I want it like true caller. I have attached an snapshot on how the true caller is displaying a window on the incoming call screen.
How can I achieve this functionality for an Android app?
This is how a true caller works:
My present output:
Update 1
After bounty also I am not getting the exact thing I am looking for, but I will get back to all; I am working upon it. Anyway, this code works for most Android phones. If anybody is going to use and catch the solution for it, please write here so that everybody can get the benefit.
Update 2
I tried to implement Toast in the broadcast receiver's onReceive method because toast is a native component of Android, but it is also not getting displayed in Android 4.1 (Jelly Bean).
My idea was to implement Toast in the broadcast receiver's onReceive method and afterwards changing its design according to our needs and tuning its duration of display. But one more problem is that findViewById doesn't work in the broadcast receiver, so I think we have to make a LinearLayout programmatically for customizing the toast.
try this
I think you shouldn't start activity to achieve the described result. You need a separate view having
LayoutParams.TYPE_SYSTEM_OVERLAY
set in its layout params.You can position this view wherever you want on the screen, or just cover the whole screen.
Here are few lines of code:
https://bitbucket.org/gyrussolutions/yaab/src/f01cc8aff690cae1b1107287cb17835b8a3c1643/src/biz/gyrus/yaab/LightMonitorService.java?at=default#cl-338 - the full source code, consider it a sample.
I'm trying something similar, adding an extra button to the incoming call screen.
The answer Sam Adams posted is working for me, although I'm calling the code from a PhoneStateListener. Apart from that, the only real difference to his code is I'm inflating a layout:
It is working on emulators as well as on a HTC One S (running Android 4.1.1).
Something you need to keep in mind is keeping a reference to the overlay view you are adding, and remove it again (call removeView() on windowmanager instance) when the phone goes back to idle (when the listener gets TelephonyManager.CALL_STATE_IDLE), otherwise your overlay will stay on screen.
Try the code before the
super.onCreate
method. I think after calling the super the code is skipped. Sometime this type of tricks worked for me.I just tested on the Android 4.2 (Jelly Bean) emulator, and it works perfect by blocking the entire incoming call screen just like truecaller:
In the manifest: