Jump to content
Maher Tannous

Call from sim 2

Recommended Posts

hello
please i need help
i want to call a number from sim2 card

I want to request USSD code from sim2 slot without change any thing in android settings
any help to do that in delphi fmx android

some one send me this

Intent intent = new Intent(Intent.ACTION_CALL);
intent.putExtra("com.android.phone.extra.slot", 1); //For sim 2
intent.putExtra("simSlot", 1); //For sim 2
intent.setData(Uri.parse("tel:" + "**********"));

I tried this without success
I replaced "com.android.phone.extra.slot" with TJIntent.JavaClass.EXTRA_PHONE_NUMBER
but I can't find any thing to replace with "simSlot" ????

 

My code :

 

uses
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Net,

var
mobilenumber : string;
Intent : JIntent;
Begin
mobilenumber:='*155#';
Intent := TJIntent.Create;
Intent.setAction(TJIntent.JavaClass.ACTION_CALL); Intent.putExtra(TJIntent.JavaClass.EXTRA_PHONE_NUMBER, 1);
Intent.putExtra(TJIntent.JavaClass.EXTRA_INDEX, 1);
Intent.setData(TJnet_Uri.JavaClass.parse
(StringtoJString(mobilenumber)));
TAndroidHelper.Context.startActivity(Intent);
End;

Share this post


Link to post

Your code does not match the Java equivalent that has been sent to you. This is the equivalent:

uses
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net, Androidapi.Helpers;

procedure TForm1.Button1Click(Sender: TObject);
var
  MobileNumber: string;
  Intent: JIntent;
begin
  MobileNumber := '*155#';
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
  Intent.putExtra(StringToJString('com.android.phone.extra.slot'), 1);
  Intent.putExtra(StringToJString('simSlot'), 1);
  Intent.setData(TJnet_Uri.JavaClass.parse(StringtoJString('tel:' + MobileNumber)));
  TAndroidHelper.Context.startActivity(Intent);
end;

I don't have a dual SIM device to test this.

 

21 minutes ago, Maher Tannous said:

I replaced "com.android.phone.extra.slot" with TJIntent.JavaClass.EXTRA_PHONE_NUMBER

Those are not equivalent. TJIntent.JavaClass.EXTRA_PHONE_NUMBER is "android.intent.extra.PHONE_NUMBER", not "com.android.phone.extra.slot"

  • Like 1

Share this post


Link to post
34 minutes ago, Dave Nottage said:

Your code does not match the Java equivalent that has been sent to you. This is the equivalent:


uses
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.Net, Androidapi.Helpers;

procedure TForm1.Button1Click(Sender: TObject);
var
  MobileNumber: string;
  Intent: JIntent;
begin
  MobileNumber := '*155#';
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
  Intent.putExtra(StringToJString('com.android.phone.extra.slot'), 1);
  Intent.putExtra(StringToJString('simSlot'), 1);
  Intent.setData(TJnet_Uri.JavaClass.parse(StringtoJString('tel:' + MobileNumber)));
  TAndroidHelper.Context.startActivity(Intent);
end;

I don't have a dual SIM device to test this.

 

Those are not equivalent. TJIntent.JavaClass.EXTRA_PHONE_NUMBER is "android.intent.extra.PHONE_NUMBER", not "com.android.phone.extra.slot"

sorry for that but it does not work

your code is asking me to choose between sim card and if I choose sim 2

it calling the number *155

it does not run ussd code for *155#

it removes # and call *155

may be some one can test the code and tell me what happining

Thanks

Share this post


Link to post
Guest

@Maher Tannous In my case it didn't ask to select between sims, and for the # it should be replaced with %23 so phone number should be:

Quote

MobileNumber := '*155%23';

 

Share this post


Link to post
Guest

Dave's code automatically made a call directly using SIM 2, the phone did not ask me to choose a sim.

Share this post


Link to post
Guest

My 4.4.2 Android is configured to ask me on each call i make to choose a sim to be used, with that code it i didn't even ask me.

Share this post


Link to post

my android version is 9

samsung j7 pro

and I configured to ask me on each call i make to choose a sim to be used

and it always show me dialog to choose sim to call from

maybe the problem in android version

8.jpg

Share this post


Link to post
Guest

May be it is a system feature,bug, changes , security thing ....

, i suggest consulting with Google on that matter, you might find some answers, 

 

Good luck.

Share this post


Link to post
Guest

@Maher Tannous Try this code as it solved similar behaviour like yours on Android 6, and i think this is the right way to format phone numbers with #

procedure CallByPhoneNumber(const PhoneNumber: string; SIMindex: Integer);
var
  Intent: JIntent;
begin
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
    //Intent.putExtra(StringToJString('com.android.phone.force.slot'), true);
    //Intent.putExtra(StringToJString('Cdma_Supp'), True);

  Intent.putExtra(StringToJString('extra_asus_dial_use_dualsim'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.extra.slot'), SIMindex);
  Intent.putExtra(StringToJString('slot'), SIMindex);
  Intent.putExtra(StringToJString('simslot'), SIMindex);
  Intent.putExtra(StringToJString('sim_slot'), SIMindex);
  Intent.putExtra(StringToJString('subscription'), SIMindex);
  Intent.putExtra(StringToJString('Subscription'), SIMindex);
  Intent.putExtra(StringToJString('phone'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.DialingMode'), SIMindex);
  Intent.putExtra(StringToJString('simSlot'), SIMindex);
  Intent.putExtra(StringToJString('slot_id'), SIMindex);
  Intent.putExtra(StringToJString('simId'), SIMindex);
  Intent.putExtra(StringToJString('simnum'), SIMindex);
  Intent.putExtra(StringToJString('phone_type'), SIMindex);
  Intent.putExtra(StringToJString('slotId'), SIMindex);
  Intent.putExtra(StringToJString('slotIdx'), SIMindex);

  Intent.setData(TJnet_Uri.JavaClass.parse(StringToJString('tel:' +
    JStringToString(TJnet_Uri.JavaClass.encode(StringToJString(PhoneNumber))))));
  TAndroidHelper.Context.startActivity(Intent);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CallByPhoneNumber('*111#', 0);   // 0 for SIM1
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  CallByPhoneNumber('*111#', 1);   // 1 for SIM2
end;

 

Share this post


Link to post

This to call TelecomManager

 

var
  telService: JObject;

 

  telService := TAndroidHelper.Activity.getSystemService
    (TJContext.JavaClass.TELECOM_SERVICE);

 

But the problem is how to call : getCallCapablePhoneAccounts

 

Share this post


Link to post
3 hours ago, Maher Tannous said:

But the problem is how to call : getCallCapablePhoneAccounts

There's an import for TelecomManager, here:

 

https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.TelecomManager.pas

 

Be aware that Java2Pas (which was used for the import) sometimes puts instance methods where the class methods are, so they should be removed from there in the import.

 

getCallCapablePhoneAccounts is an instance method that returns a JList, containing instances of JPhoneAccountHandle, so one way to access them is to do this:

 

var
  LService: JObject;
  LAccounts: JList;
  LPhoneAccountHandle: JPhoneAccountHandle;
  I: Integer;
begin
  Result := False;
  LService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELECOM_SERVICE);
  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService)).getCallCapablePhoneAccounts;
  for I := 0 to LAccounts.size - 1 do
  begin
    LPhoneAccountHandle := TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID(LAccounts.get(I)));
    // Do whatever with the LPhoneAccountHandle here
  end;
end;

An import for PhoneAccountHandle is here:

 

https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.PhoneAccountHandle.pas

 

Note that getCallCapablePhoneAccounts was introduced in API level 23.

Share this post


Link to post
Guest

@Dave Nottage Thank you .

 

This raise a question about raised exception and i know you are the right person to ask 

Quote

Invoke error: method not found

raised on   LService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELECOM_SERVICE);

The question is : Is there right way to handle this ? 

i mean my phone API level is 19 and TELECOM_SERVICE is not there, should i use try..except or there is a method to check class existence without raising an exception ?

Share this post


Link to post
12 hours ago, Kas Ob. said:

The question is : Is there right way to handle this ? 

This is one way:

if TOSVersion.Check(21) then
begin
  // Do the TELECOM_SERVICE stuff
end;

TELECOM_SERVICE was introduced in API level 21. Another way is:

if TJBuild_VERSION.JavaClass.SDK_INT >= 21 then
begin
  // Do the TELECOM_SERVICE stuff
end;

 

Share this post


Link to post
On 12/28/2019 at 3:15 AM, Dave Nottage said:

There's an import for TelecomManager, here:

 

https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.TelecomManager.pas

 

Be aware that Java2Pas (which was used for the import) sometimes puts instance methods where the class methods are, so they should be removed from there in the import.

 

getCallCapablePhoneAccounts is an instance method that returns a JList, containing instances of JPhoneAccountHandle, so one way to access them is to do this:

 


var
  LService: JObject;
  LAccounts: JList;
  LPhoneAccountHandle: JPhoneAccountHandle;
  I: Integer;
begin
  Result := False;
  LService := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELECOM_SERVICE);
  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService)).getCallCapablePhoneAccounts;
  for I := 0 to LAccounts.size - 1 do
  begin
    LPhoneAccountHandle := TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID(LAccounts.get(I)));
    // Do whatever with the LPhoneAccountHandle here
  end;
end;

An import for PhoneAccountHandle is here:

  

https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-28/android.telecom.PhoneAccountHandle.pas

 

Note that getCallCapablePhoneAccounts was introduced in API level 23.

Thank you

but

I have to put all files from this page

https://github.com/FMXExpress/android-object-pascal-wrapper/tree/master/android-28

in my project folder !!!

Share this post


Link to post
3 hours ago, Dave Nottage said:

I've created a more compatible (with the other Delphi units) import for the Telecom classes, here:

 

https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.Telecom.pas

 

Which should at least make it a bit easier

 

Thank you

 

procedure CallByPhoneNumber(const PhoneNumber: string; SIMindex: Integer);
var
  Intent: JIntent;
  LService: JObject;
  LAccounts: JList;
  LPhoneAccountHandle: JPhoneAccountHandle;
  I: Integer;
begin
  LService := TAndroidHelper.Context.getSystemService
    (TJContext.JavaClass.TELECOM_SERVICE);
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.setData(TJnet_Uri.JavaClass.parse(StringToJString('tel:' +
    JStringToString(TJnet_Uri.JavaClass.encode(StringToJString
    (PhoneNumber))))));
  Intent.putExtra(StringToJString('com.android.phone.force.slot'), true);
  Intent.putExtra(StringToJString('Cdma_Supp'), true);
  Intent.putExtra(StringToJString('extra_asus_dial_use_dualsim'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.extra.slot'), SIMindex);
  Intent.putExtra(StringToJString('slot'), SIMindex);
  Intent.putExtra(StringToJString('simslot'), SIMindex);
  Intent.putExtra(StringToJString('sim_slot'), SIMindex);
  Intent.putExtra(StringToJString('subscription'), SIMindex);
  Intent.putExtra(StringToJString('Subscription'), SIMindex);
  Intent.putExtra(StringToJString('phone'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.DialingMode'), SIMindex);
  Intent.putExtra(StringToJString('simSlot'), SIMindex);
  Intent.putExtra(StringToJString('slot_id'), SIMindex);
  Intent.putExtra(StringToJString('simId'), SIMindex);
  Intent.putExtra(StringToJString('simnum'), SIMindex);
  Intent.putExtra(StringToJString('phone_type'), SIMindex);
  Intent.putExtra(StringToJString('slotId'), SIMindex);
  Intent.putExtra(StringToJString('slotIdx'), SIMindex);
  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService))
    .getCallCapablePhoneAccounts;
  for I := 0 to LAccounts.size - 1 do
  begin
    LPhoneAccountHandle := TJPhoneAccountHandle.Wrap
      (TAndroidHelper.JObjectToID(LAccounts.get(I)));
    if (LAccounts <> null) AND (LAccounts.size() > 0) then
    Begin
      Intent.putExtra('Android.telecom.extra.PHONE_ACCOUNT_HANDLE',
        LAccounts.get(0));
    End
    else if (LAccounts <> null) AND (LAccounts.size() > 1) then
    Begin
      Intent.putExtra('Android.telecom.extra.PHONE_ACCOUNT_HANDLE',
        LAccounts.get(1));
    End;
  end;
  TAndroidHelper.Context.startActivity(Intent);

End;

 

I got an error here ( LAccounts.get(0) )

it returns an TJObject

but Intent.putExtra reqired a Byte

Share this post


Link to post
7 hours ago, Maher Tannous said:

I got an error here ( LAccounts.get(0) )

That part should be more like this:

  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService)).getCallCapablePhoneAccounts;
  if LAccounts <> nil then
  begin
    for I := 0 to 1 do
    begin
      if LAccounts.size > I then
      begin
        LPhoneAccountHandle := TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID(LAccounts.get(I)));
        Intent.putExtra(StringToJString('android.telecom.extra.PHONE_ACCOUNT_HANDLE'), LPhoneAccountHandle);
      end;
    end;
  end;

 

Share this post


Link to post
22 hours ago, Dave Nottage said:

That part should be more like this:


  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService)).getCallCapablePhoneAccounts;
  if LAccounts <> nil then
  begin
    for I := 0 to 1 do
    begin
      if LAccounts.size > I then
      begin
        LPhoneAccountHandle := TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID(LAccounts.get(I)));
        Intent.putExtra(StringToJString('android.telecom.extra.PHONE_ACCOUNT_HANDLE'), LPhoneAccountHandle);
      end;
    end;
  end;

 

Intent.putExtra(StringToJString('android.telecom.extra.PHONE_ACCOUNT_HANDLE'), LPhoneAccountHandle);

 

does not accept

LPhoneAccountHandle

 

I must use JString or integer value

Share this post


Link to post
17 hours ago, Dave Nottage said:

Actually putExtra takes a number of different types, including JParcelable. I've modified the Telecom import unit:

 

https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.Telecom.pas

 

So if you update that, it should now accept LAccountHandle

 

Thank you very much

this is my working code

 

1- Use this unit https://github.com/DelphiWorlds/KastriFree/blob/master/API/DW.Androidapi.JNI.Telecom.pas

2-

procedure CallByPhoneNumber(const PhoneNumber: string; SIMindex: Integer);
var
  Intent: JIntent;
  LService: JObject;
  LAccounts: JList;
begin
  LService := TAndroidHelper.Context.getSystemService
    (TJContext.JavaClass.TELECOM_SERVICE);
  Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_CALL);
  Intent.setFlags(TJIntent.JavaClass.FLAG_ACTIVITY_NEW_TASK);
  Intent.setData(TJnet_Uri.JavaClass.parse(StringToJString('tel:' +
    JStringToString(TJnet_Uri.JavaClass.encode(StringToJString
    (PhoneNumber))))));
  Intent.putExtra(StringToJString('com.android.phone.force.slot'), true);
  Intent.putExtra(StringToJString('Cdma_Supp'), true);
  Intent.putExtra(StringToJString('extra_asus_dial_use_dualsim'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.extra.slot'), SIMindex);
  Intent.putExtra(StringToJString('slot'), SIMindex);
  Intent.putExtra(StringToJString('simslot'), SIMindex);
  Intent.putExtra(StringToJString('sim_slot'), SIMindex);
  Intent.putExtra(StringToJString('subscription'), SIMindex);
  Intent.putExtra(StringToJString('Subscription'), SIMindex);
  Intent.putExtra(StringToJString('phone'), SIMindex);
  Intent.putExtra(StringToJString('com.android.phone.DialingMode'), SIMindex);
  Intent.putExtra(StringToJString('simSlot'), SIMindex);
  Intent.putExtra(StringToJString('slot_id'), SIMindex);
  Intent.putExtra(StringToJString('simId'), SIMindex);
  Intent.putExtra(StringToJString('simnum'), SIMindex);
  Intent.putExtra(StringToJString('phone_type'), SIMindex);
  Intent.putExtra(StringToJString('slotId'), SIMindex);
  Intent.putExtra(StringToJString('slotIdx'), SIMindex);
  Intent.putExtra(StringToJString('simSlotName'), SIMindex);
  LAccounts := TJTelecomManager.Wrap(TAndroidHelper.JObjectToID(LService))
    .getCallCapablePhoneAccounts;
  if LAccounts <> nil then
    Intent.putExtra
      (StringToJString('android.telecom.extra.PHONE_ACCOUNT_HANDLE'),
      TJPhoneAccountHandle.Wrap(TAndroidHelper.JObjectToID
      (LAccounts.get(SIMindex))));
  TAndroidHelper.Context.startActivity(Intent);
end;

3-

CallByPhoneNumber(mobilenumber, 0);

or

CallByPhoneNumber(mobilenumber, 1);

Edited by Maher Tannous
  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×