Android Question Answer an Incomming Call.

Jmu5667

Well-Known Member
Licensed User
Hi All

I know that there has been a lot of questions relating to this question. I have tried using AnswerCall library but alas it does not seem to work on all devices.

I have researched this topic an there seems to be away by using Intents;

B4X:
public void answerPhoneHeadsethook(Context context, Intent intent) {
  String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
  if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
  String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
  Log.d(TAG, "Incoming call from: " + number);
  Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
  buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
  try {
  context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
  Log.d(TAG, "ACTION_MEDIA_BUTTON broadcasted...");
  }
  catch (Exception e) {
  Log.d(TAG, "Catch block of ACTION_MEDIA_BUTTON broadcast !");
  }

  Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
  headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
  headSetUnPluggedintent.putExtra("state", 1); // 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
  headSetUnPluggedintent.putExtra("name", "Headset");
  // TODO: Should we require a permission?
  try {
  context.sendOrderedBroadcast(headSetUnPluggedintent, null);
  Log.d(TAG, "ACTION_HEADSET_PLUG broadcasted ...");
  }
  catch (Exception e) {
  // TODO Auto-generated catch block
  //e.printStackTrace();
  Log.d(TAG, "Catch block of ACTION_HEADSET_PLUG broadcast");
  Log.d(TAG, "Call Answered From Catch Block !!");
  }
  Log.d(TAG, "Answered incoming call from: " + number);
  }
  Log.d(TAG, "Call Answered using headsethook");
}

The above code snipit is from http://stackoverflow.com/questions/15481524/how-to-programatically-answer-end-a-call-in-android-4-1 and seems to show how to simulate a human would answering a call via their headset.

I have attempted to convert this to B4A but I an not a Java Expert and it does not work for me.

B4X:
Dim iB, iH As Intent
   Dim Broadcast As BroadCastReceiver

   Broadcast.Initialize("BR")

   iB.Initialize("android.intent.action.MEDIA_BUTTON","")
   iB.PutExtra("android.intent.extra.KEY_EVENT",1 & "," & KeyCodes.KEYCODE_HEADSETHOOK) ' ACTION_UP
   Log(iB.Action & " - " & iB.ExtrasToString)
   Broadcast.sendOrderedBroadcast(iB,"android.permission.CALL_PRIVILEGED")

   iH.Initialize("android.intent.action.HEADSET_PLUG","")
   iH.Flags = 1073741824  '  FLAG_RECEIVER_REGISTERED_ONLY
  iH.PutExtra("state",1)  '  0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
   iH.PutExtra("name","Headset")
   Log(iH.Action & " - " & iH.ExtrasToString)
   Broadcast.sendOrderedBroadcast(iH,Null)

Does anyone want to have a go at this and help. I am struggling with the putextra multiple values for the Key Events. There are a lot of these examples and if we all could learn how to translate them to b4a with the tools to hand it would benefit the wider community.

Regards

John.
 

Jmu5667

Well-Known Member
Licensed User
Thanks for the reply Erel, not too sure how to use the Javeobject to create the Keyevent object, any chance you could show me some code, any comments on my transations ?

Thanks

John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
I get the following on a compile,
Parsing code. Error
Error parsing program.
Error description: Unknown type: keyevent
Are you missing a library reference?
Occurred on line: 124
Dim ke As keyEvent

I have included the javaobject lib, am I missed another lib reference ?
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Hi Erel

I have implemented the following;

B4X:
Public Sub Answer_Call
  
   Dim ke As JavaObject
   Dim Broadcast As BroadCastReceiver
  
  
   Broadcast.Initialize("BR")
  
   ' // method 1
   Dim iB, iH As Intent
'   ke.InitializeNewInstance("android.view.KeyEvent", Array As Object(1, KeyCodes.KEYCODE_HEADSETHOOK))
'  
'   iH.Initialize("android.intent.action.HEADSET_PLUG","")
'   iH.Flags = 1073741824  '  FLAG_RECEIVER_REGISTERED_ONLY
'  iH.PutExtra("state",1)  '  0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
'   iH.PutExtra("name","Headset") 
'   Log(iH.Action & " - " & iH.ExtrasToString)
'   Broadcast.sendOrderedBroadcast(iH,Null)
'
'  
'   iB.Initialize("android.intent.action.MEDIA_BUTTON","")
'   iB.PutExtra("android.intent.extra.KEY_EVENT", ke)
'   Log(iB.Action & " - " & iB.ExtrasToString)
'   Broadcast.sendOrderedBroadcast(iB,"android.permission.CALL_PRIVILEGED")

    ' // method 2
   Dim i1,i2,i3,i4 As Intent
  
   ' // emulate headset plugged in
   i1.Initialize("android.intent.action.HEADSET_PLUG","")
   i1.Flags =  1073741824        ' Intent.FLAG_ACTIVITY_NO_HISTORY
   i1.PutExtra("state",1)      ' 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
   i1.PutExtra("microphone",1)   
   i1.PutExtra("name","Headset") 
   Broadcast.sendOrderedBroadcast(i1,"android.permission.CALL_PRIVILEGED")
   Log(i1.Action & " - " & i1.ExtrasToString)
  
'     Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG); 
'     localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 
'     localIntent1.putExtra("state", 1); 
'     localIntent1.putExtra("microphone", 1); 
'     localIntent1.putExtra("name", "Headset"); 
'     CallingActivity.this.sendOrderedBroadcast(localIntent1,"android.permission.CALL_PRIVILEGED"); 

   ' // emulate key down
   i2.Initialize("android.intent.action.MEDIA_BUTTON","")       
   ke.InitializeNewInstance("android.view.KeyEvent", Array As Object(0,  79))    
   i2.PutExtra("android.intent.extra.KEY_EVENT", ke)
   Broadcast.sendOrderedBroadcast(i2,"android.permission.CALL_PRIVILEGED")
   Log(i2.Action & " - " & i2.ExtrasToString)
      
'     Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON); 
'     KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_HEADSETHOOK);  0
'     localIntent2.putExtra("android.intent.extra.KEY_EVENT",localKeyEvent1); 
'     CallingActivity.this.sendOrderedBroadcast(localIntent2,"android.permission.CALL_PRIVILEGED"); 

   ' // emulate key up
   i3.Initialize("android.intent.action.MEDIA_BUTTON","")       
   ke.InitializeNewInstance("android.view.KeyEvent", Array As Object(1,  79))    
   i3.PutExtra("android.intent.extra.KEY_EVENT", ke)
   Broadcast.sendOrderedBroadcast(i2,"android.permission.CALL_PRIVILEGED")
   Log(i3.Action & " - " & i3.ExtrasToString)
      
      
'     Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON); 
'     KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,KeyEvent.KEYCODE_HEADSETHOOK); 
'     localIntent3.putExtra("android.intent.extra.KEY_EVENT",localKeyEvent2); 
'     CallingActivity.this.sendOrderedBroadcast(localIntent3,"android.permission.CALL_PRIVILEGED"); 

   ' // emulate headset unplugged
   i4.Initialize("android.intent.action.HEADSET_PLUG","")
   i4.Flags =  1073741824        ' Intent.FLAG_ACTIVITY_NO_HISTORY
   i4.PutExtra("state",0)      ' 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
   i4.PutExtra("microphone",1)   
   i4.PutExtra("name","Headset") 
   Broadcast.sendOrderedBroadcast(i4,"android.permission.CALL_PRIVILEGED")
   Log(i4.Action & " - " & i4.ExtrasToString)
        
'     Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG); 
'     localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); 
'     localIntent4.putExtra("state", 0); 
'     localIntent4.putExtra("microphone", 1); 
'     localIntent4.putExtra("name", "Headset"); 
'     CallingActivity.this.sendOrderedBroadcast(localIntent4,"android.permission.CALL_PRIVILEGED");

End Sub

I am also showing the Java code for this. At the moment it does not answer the call. I got the java from http://www.phonesdevelopers.com/1807741/

My feeling is that this code works but it could be the broadcastreceiver that is not doing the job. Is there any way of getting this tested ?

Regards

John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
I had a mistake in the broadcast receiver, Broadcast.sendOrderedBroadcast(i2.Action ,"android.permission.CALL_PRIVILEGED"), and when I run it I get;

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.HEADSET_PLUG from pid=31162, uid=10004

This is painful, I just want to answer a call. There are apps that do this already. I know you are busy, but is there a way around this...?

Regards

John. :(
 
Upvote 0

bsnqt

Active Member
Licensed User
Same to me, I had to give up after so many days trying with different codes... for same purpose.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Well Now, some good news (Android 4.2.2)

This works. It does not work on a HTC phone, at the moment but there is an app called Auto Answer Call https://play.google.com/store/apps/details?id=com.adt.autoanswer which works on some HTC phones.

Many thanks to Erels JavaObject which I use instead of the Broadcast Receiver's send ordered broadcast.


B4X:
Sub GetContext As JavaObject
  Return GetBA.GetField("context")
End Sub

Sub GetBA As JavaObject
  Dim jo As JavaObject
  Dim cls As String = Me
  cls = cls.SubString("class ".Length)
  jo.InitializeStatic(cls)
  Return jo.GetFieldJO("processBA")
End Sub

Public Sub answer_call
   
   Dim ke As JavaObject 
   Dim i1 As Intent
  
   Try

           
     i1.Initialize("android.intent.action.MEDIA_BUTTON","")        
     ke.InitializeNewInstance("android.view.KeyEvent", Array As Object(1,  KeyCodes.KEYCODE_HEADSETHOOK ))     
     i1.PutExtra("android.intent.extra.KEY_EVENT", ke)
          
     GetContext.RunMethod("sendOrderedBroadcast", Array As Object(i1,"android.permission.CALL_PRIVILEGED"))
    
   
   Catch
     ToastMessageShow(LastException.Message,True)
     Log("answer_call() " & LastException.Message)
   End Try


End Sub

I think if we work a bit harder we can get the other's to work with it.

Regards

John.
 
Upvote 0
Top