Pop-up window on the external screen of Android incoming calls, for example, an application for Android-caller

Update - May 09, 2013 * I tried to inject Toast into the onReceive broadcast receiver because the toast is a native component of Android, but it also does not appear in Android 4.1 (Jelly Bean).

My idea was to inject Toast into the onReceive broadcast receiver, and then change its design to suit our needs and adjust its display duration. But another problem is that findViewById does not work in the broadcast receiver, so I think we should make LinearLayout a programmatic way to set up the toast. *

Update . After generosity, I also do not receive what I seek, but I will return to all; I'm working on it. Anyway, this code works for most Android phones. If someone is going to use and catch a solution for this, write here so that everyone can benefit. Thanks for all your answers.

I am developing a broadcast receiver for incoming calls on Android and when incoming calls arrive that I want to inflate a pop-up window on my own incoming call screen.

I have completed this code. But now the problem is that in Android 4.1 (Jelly Bean) level API 17 , when the phone rings, PHONE_STATE approaches as an OFF HOOK , and if I call an action, it is called, but the code below it does not execute. 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); } } } 

I perform the actions that I invoke:

 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 does not run in Android 4.1 (Jelly Bean), but in other versions it works.

I tried almost everything I can. This code displays a translucent activity on the own calls screen, and it does not block background controls, for example, picks up the phone. But I want him to be a true caller. I attached a snapshot of how the true caller displays a window on the incoming call screen.

How can I achieve this functionality for an Android app?

Here's how the true caller works:

Enter image description here

My current output is:

Enter image description here

+45
android android-layout android-widget broadcastreceiver android-broadcast
Mar 28 '13 at 14:06
source share
10 answers

I’m not sure that your GUI will always be on top of the standard one, because the system broadcast receiver and your receiver are trying to display its GUI on top of the screen. We are not sure which one is called first, but one difficult task is to make your graphical interface on top of the screen when the phone rings, call your activity after 1-2 seconds for this handler.

 new Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Intent intent = new Intent(context, AcceptReject.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } }, 2000); 

I hope this can help you.

+25
Apr 20 '13 at 5:32
source share
— -

Try executing the code before the super.onCreate method. I think that after calling the super code is skipped. This trick once worked for me.

+9
Apr 18 '13 at 10:14
source share

I just tested the Android 4.2 emulator (Jelly Bean) , and it works great, blocking the entire screen of incoming calls, like truecaller:

 public void onReceive(Context context, Intent intent) { WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); params.height = LayoutParams.MATCH_PARENT; params.width = LayoutParams.MATCH_PARENT; params.format = PixelFormat.TRANSLUCENT; params.gravity = Gravity.TOP; LinearLayout ly = new LinearLayout(context); ly.setBackgroundColor(Color.RED); ly.setOrientation(LinearLayout.VERTICAL); wm.addView(ly, params); } 

In the manifest:

 <receiver android:name="" android:enabled="true" > <intent-filter android:priority="-1"> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver> 
+9
May 18 '13 at 6:38
source share

I'm trying something like this by adding an extra button to the incoming call screen.

The answer written by Sam Adams works for me, although I am calling the code from PhoneStateListener. In addition, the only real difference from its code is to inflate the layout:

 overlay = (RelativeLayout) inflater.inflate(R.layout.overlay, null); wm.addView(overlay, params); 

It works with both emulators and HTC One S (it runs Android 4.1.1).

Something you need to remember is to keep the link to the displayed overlay view that you add and delete it again (call removeView () on the windowmanager instance) when the phone returns to standby (when the listener receives TelephonyManager.CALL_STATE_IDLE) otherwise your overlay will remain on the screen.

  WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if(overlay!=null) { wm.removeView(overlay); overlay = null; } 
+6
Aug 2 '13 at 4:04 on
source share

I think you should not start activity in order to achieve the described result. You need to have a separate view containing LayoutParams.TYPE_SYSTEM_OVERLAY in its layout options.

You can position this view wherever you want on the screen, or simply close the entire screen.

Here are a few lines of code:

  _av = new ActivatorView(this); _avLayoutParams = new WindowManager.LayoutParams(0, 0, 0, 0, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.OPAQUE); _avLayoutParams.screenBrightness = _fScreenBrightness = 20f; WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.addView(_av, _avLayoutParams); 

https://bitbucket.org/gyrussolutions/yaab/src/f01cc8aff690cae1b1107287cb17835b8a3c1643/src/biz/gyrus/yaab/LightMonitorService.java?at=default#cl-338 - full source code, consider it as a sample.

+5
Apr 20 '13 at 7:01
source share

I am also working on this (maybe I'm wrong to understand you here). What you want to achieve is to show this activity in Android 4.2 (Jelly Bean). I just put a delay to display activity. I used PhoneStateListener in different classes. I can display the new activity on the caller’s screen. Here is my complete code:

Enter image description here

File MyBroadcastReceiver.java

 public class MyBroadcastReceiver extends BroadcastReceiver { static CustomPhoneStateListener phoneStateListener; Context context; Intent intent; @Override public void onReceive(Context context, Intent intent) { this.context = context; this.intent = intent; // TODO Auto-generated method stub TelephonyManager telephonyManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE); phoneStateListener = new CustomPhoneStateListener(context); telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } } 

File CustomPhoneStateListener.java

 public class CustomPhoneStateListener extends PhoneStateListener { // private static final String TAG = "PhoneStateChanged"; Context context; // Context to make Toast if required private AudioManager amanager; Intent i1; public CustomPhoneStateListener(Context context) { super(); this.context = context; i1 = new Intent(context, YourActivity.class); i1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); i1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); } @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { case TelephonyManager.CALL_STATE_IDLE: Toast.makeText(context, "Phone state Idle", Toast.LENGTH_LONG) .show(); break; case TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText(context, "Phone state Off hook", Toast.LENGTH_LONG) .show(); break; case TelephonyManager.CALL_STATE_RINGING: try { Thread.sleep(3000); context.startActivity(i1); } catch (Exception e) { e.getLocalizedMessage(); } default: break; } } 

and YourActivity will remain as you created ... Note. I am facing some problems also in this code, which they are here.

  • When a closed call is closed (missed or rejected), activity is not closed.
  • I can’t click “Activity” (I want to add one button for my application)
  • It only works for the first time. When I make a call a second time, my application stops (I think this is because the action does not close when the call is rejected).

(Help accepted for these problems. Thanks. May help someone)

UPDATE

HERE A LINE A SMALL DEMO HOW TO ACHIEVE IT.

  • When a closed call is closed (missed or rejected), activity is not closed. - SOLVED
  • I can’t click on Activity (I want to add one button for my application) - SOLVED
  • It only works for the first time. When I make a call a second time, my application stops (I think this is because the action does not close when the call is dismissed) - SOLVED
+5
Jun 15 '13 at 7:22
source share

My method:

  • use the receiver to receive phone call events
  • use the service to make an overlay

     ps:wmParams.type = WindowManager.LayoutParams.TYPE_PHONE; 
0
Oct 28 '13 at
source share

We also faced a similar problem that the overlay was not displayed on the device with contact lock. The solution that worked for us is below:

 mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); mParams = new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_SYSTEM_ERROR, LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); 

It was LayoutParams.TYPE_SYSTEM_ERROR that mattered.

0
Oct. 14 '15 at 22:47
source share
 new Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Intent i = new Intent(context, CallingIncoming.class); i.putExtras(intent); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK /*| Intent.FLAG_ACTIVITY_CLEAR_TASK*/); context.startActivity(i); } }, 450);//It will help you to delay your screen and after it your screen will be top of default app screen 
0
Jun 26 '16 at 6:51
source share

Use a simple broadcast receiver and put this code in the broadcast receiver:

 public void onReceive(final Context context, final Intent intent) { Log.v(LOG_TAG, "Receieved notification about network status"); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); params.height = WindowManager.LayoutParams.MATCH_PARENT; params.width = WindowManager.LayoutParams.MATCH_PARENT; params.format = PixelFormat.TRANSLUCENT; params.gravity = Gravity.TOP; LinearLayout ly = new LinearLayout(context); ly.setBackgroundColor(Color.RED); ly.setOrientation(LinearLayout.VERTICAL); wm.addView(ly, params); } 
0
Jul 15 '16 at 11:17
source share



All Articles