Can an activity receive an unordered broadcast(incoming call) intent before system's default receiver?

后端 未结 2 1411
伪装坚强ぢ
伪装坚强ぢ 2020-12-05 16:59

Here is the scenario :

An activity is displayed(active). If a phone call comes, the activity should receive the intent (send the \"incoming call screen\" to the back

相关标签:
2条回答
  • 2020-12-05 17:04

    This is how I solved it :

    Manifest.xml

    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    ...
    <receiver android:name=".MyPhoneBroadcastReceiver">
    <intent-filter android:priority="99999">
        <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>
    
    <activity android:name=".LockScreenActivity" android:noHistory="true" android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.ANSWER" />
             <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>    
     </activity>
    

    MyPhoneBroadcastReceiver.java

    public void onReceive(final Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        ...
        if (extras != null) {
        String state = extras.getString(TelephonyManager.EXTRA_STATE);
    
         if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                 new Handler().postDelayed(new Runnable() {
              public void run() {
                  Intent intentPhoneCall = new Intent("android.intent.action.ANSWER");
                          intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
              context.startActivity(intentPhoneCall);
                      }
                 }, 100);
             }
        }
    }
    

    LockScreenActivity.java - A regular activity class with UI that shows up saying your screen is locked. It covers 100% area of your screen i.e. no navigation/status bar. Also the HOME/MENU keys have been disabled. This is how I achieved that : How can I detect user pressing HOME key in my activity?

    P.S. : The trick is not the main logic but a 100ms delay. Without it your custom(home) lock screen will be removed by the system default incoming call screen everytime you get a call on the phone!

    0 讨论(0)
  • 2020-12-05 17:04

    Ya sanjana is right that code works for me.. but instead of giving postdelay 100msec give more then 1.5 sec.. Bcoz to start incoming screen needs 800 to 1000msec.. I copied her code only but modified a bit.. Try this works fine...

    @Override
    public void onReceive(final Context context, Intent intent) {
    
        Bundle extras = intent.getExtras();
    
        if (extras != null) {
            String state = extras.getString(TelephonyManager.EXTRA_STATE);
            final String incomingNumber = extras.getString("incoming_number");
    
            Handler callActionHandler = new Handler();
    
            Runnable runRingingActivity = new Runnable() {
    
                @Override
                public void run() {
                    Intent intentPhoneCall = new Intent("android.intent.action.ANSWER");
                    intentPhoneCall.putExtra("INCOMING_NUM", incomingNumber);
                    intentPhoneCall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intentPhoneCall);
                }
            };
    
            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                callActionHandler.postDelayed(runRingingActivity, 2000);
    
            }
    
            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                callActionHandler.removeCallbacks(runRingingActivity);
                // setResultCode(Activity.RESULT_CANCELED);
            }
    
        }
    }
    

    Then use PhoneStateListener at receiver class side.. I used like this....

    /*********** My receiver class onCreate() contains ************/
    TelephonyManager telephony = (TelephonyManager)    
    getSystemService(getApplicationContext().TELEPHONY_SERVICE);
            telephony.listen(myListener, PhoneStateListener.LISTEN_CALL_STATE);
    
    class MyPhoneStateListener extends PhoneStateListener {
    
         Activity curActivity;
    
         public MyPhoneStateListener(Activity _curActivity){
             this.curActivity = _curActivity;
    
         }
    
            public void onCallStateChanged(int state, String incomingNumber) {
                switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    Log.i("TEST APP", "Cal End");                   
                    curActivity.finish();                   
                    break;
    
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.i("TEST APP", "Hello");                 
                    break;
    
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.i("TEST APP", "Calling...");
    
                    break;
                }
    
            }
        }
    
    0 讨论(0)
提交回复
热议问题