Search code examples
androidbroadcastreceiverandroid-notificationsalertphone-call

Android: Presenting a notification during a call?


I have a broadcast receiver that listens to incoming calls. And I want to tweak the incoming call screen. Right now I can present toasts and add notifications to the notification bar (BTW the user can't pull it down because the screen is locked, before accepting the call, which kinda sucks). I tried to show an alert but it crashed - is it not allowed? Is there a way for the code in the broadcast receiver to do other things, like change the avatar of the caller or give it a name (even if it doesn't exist in the contacts). Let's just say my broadcast receiver intercepts a call - can it add the phone number and a custom avatar to the contacts, so that they will immediately be presented in the call screen?

What do you think?


Edit

I have tested vendor's code, and it worked, but it is not safe to change the UI from a background thread, so I tried to tweak his code a bit to make it thread safe but the toast doesn't appear for some reason. What do you think?

private Handler handler = new Handler();

    private void showToast() { 
        Thread thread = new Thread(null, doBackgroundThreadProcessing, "Background");
        thread.start();
    }

    private Runnable doBackgroundThreadProcessing = new Runnable() { 
        public void run() {
            backgroundThreadProcessing();
        } 
    };

    private void backgroundThreadProcessing() {
        handler.post(new Runnable() {
            public void run() { 
                int count = 0;
                try{
                    while (count < 10) {
                        toast.show();
                        Thread.sleep(1850);
                        count++;

                    }
                }
                catch(Exception e){

                    Log.e("LongToast", "", e);
                }
            } 
        });
    }

Solution

  • You need a BroadcastReceiver like that:

    public class IncomingBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
            MyLog.d("IncomingBroadcastReceiver: onReceive: ");
    
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            MyLog.d("IncomingBroadcastReceiver: onReceive: " + state);
            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING))
            {
                Intent i = new Intent(context, IncomingCallActivity.class);
                i.putExtras(intent);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
                context.startActivity(i);
            }
    
        }
    
    }
    

    And register it in the manifest to <action android:name="android.intent.action.PHONE_STATE"></action>.

    Then create an Activity like that:

    public class IncomingCallActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            MyLog.d("IncomingCallActivity: onCreate: ");
    
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
    
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    
            setContentView(R.layout.main);
    
            String number = getIntent().getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            TextView text = (TextView)findViewById(R.id.text);
            text.setText("Incoming call from " + number);
        }
    }
    

    which has this layout:

    <?xml version="1.0" encoding="utf-8"?>
    
    <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal"
        android:text="text"
        android:windowBackground="@android:color/transparent" 
        android:windowIsTranslucent="true" 
        android:windowAnimationStyle="@android:style/Animation.Translucent"></TextView>
    

    This will produce a translucent dialog-like activity on top of the incoming call screen, that allows the user to answer the call (doesn't interfere with touch events).