Ruslan 6 Posted December 29, 2023 Hi all and Happy Holidays! Can anyone guide me how to use Kastri or native FMX for making and receiving calls from application? Also I need a method to control the calling process, eg to terminate the call after some seconds, and to get statuses (logs) for those calls (answered, no answer, invalid number, or any type of calling results). I've started with PhoneDialer example that came with Delphi, and tried to use smth like following example but can't get statuses. procedure TPhoneDialerForm.FormCreate(Sender: TObject); begin {$IFDEF ANDROID} FCallPhonePermission := JStringToString(TJManifest_permission.JavaClass.CALL_PHONE); FReadPhoneStatePermission := JStringToString(TJManifest_permission.JavaClass.READ_PHONE_STATE); FReadCallLogPermission := JStringToString(TJManifest_permission.JavaClass.READ_CALL_LOG); FManageOwnCalls := JStringToString(TJManifest_permission.JavaClass.MANAGE_OWN_CALLS); FBindTelecomService := JStringToString(TJManifest_permission.JavaClass.BIND_TELECOM_CONNECTION_SERVICE); //FReadPrecisePhoneState := JStringToString(TJManifest_permission.JavaClass.READ_PRECISE_PHONE_STATE); {$ENDIF} { test whether the PhoneDialer services are supported } TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, FPhoneDialerService); PermissionsService.RequestPermissions([FCallPhonePermission,FReadPhoneStatePermission,FReadCallLogPermission,FManageOwnCalls,FBindTelecomService], procedure (const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray) begin if (Length(AGrantResults) = 5) and (AGrantResults[0] = TPermissionStatus.Granted) and (AGrantResults[1] = TPermissionStatus.Granted) and (AGrantResults[2] = TPermissionStatus.Granted) and (AGrantResults[3] = TPermissionStatus.Granted) and (AGrantResults[4] = TPermissionStatus.Granted) then begin ShowMessage('Permissions Activated!'); end; end ); FPhoneDialerService.OnCallStateChanged := CallStateChanged; end; procedure TPhoneDialerForm.CallStateChanged(const ACallID: string; const AState: TCallState); var Calls: TCalls; Call: TCall; begin case AState of TCallState.None: begin lbCalls.Items.Add(Format('%-16s %s', [ACallID, CallStateAsString(AState)])); end; TCallState.Connected: begin lbCalls.Items.Add(Format('%-16s %s', [ACallID, CallStateAsString(AState)])); end; TCallState.Incoming: begin Calls := FPhoneDialerService.GetCurrentCalls; try for Call in Calls do begin if Call.GetCallID = ACallID then begin lbCalls.Items.Add(Format('%-16s %s', [ACallID, CallStateAsString(AState)])); Exit; end; end; finally for Call in Calls do Call.Free; end; end; TCallState.Dialing: begin lbCalls.Items.Add(Format('%-16s %s', [ACallID, CallStateAsString(AState)])); end; TCallState.Disconnected: begin lbCalls.Items.Add(Format('%-16s %s', [ACallID, CallStateAsString(AState)])); end; end; end; function TPhoneDialerForm.CallStateAsString(AState: TCallState): String; begin case AState of TCallState.None: Result := 'None'; TCallState.Connected: Result := 'Connected'; TCallState.Incoming: Result := 'Incoming'; TCallState.Dialing: Result := 'Dialing'; TCallState.Disconnected: Result := 'Disconnected'; else Result := '<unknown>'; end; end; For the calling method I used these // Default method from example procedure TPhoneDialerForm.btnMakeCallClick(Sender: TObject); begin { test whether the PhoneDialer services are supported } if FPhoneDialerService <> nil then begin { if the Telephone Number is entered in the edit box then make the call, else display an error message } if edtTelephoneNumber.Text <> '' then begin PermissionsService.RequestPermissions([FCallPhonePermission], MakePhoneCallPermissionRequestResult, DisplayRationale) //FPhoneDialerService.Call(edtTelephoneNumber.Text); end else begin TDialogService.ShowMessage('Please type in a telephone number.'); edtTelephoneNumber.SetFocus; end; end else TDialogService.ShowMessage('PhoneDialer service not supported'); end; procedure TPhoneDialerForm.MakePhoneCallPermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray); begin // 1 permission involved: CALL_PHONE if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then FPhoneDialerService.Call(edtTelephoneNumber.Text) else TDialogService.ShowMessage('Cannot make a phone call because the required permission has not been granted'); end; // The other method for making calls procedure TPhoneDialerForm.MakeCall(const PhoneNumber: string); var Intent: JIntent; Uri: Jnet_Uri; begin Intent := TJIntent.Create; Intent.setAction(TJIntent.JavaClass.ACTION_CALL); Uri := TJnet_Uri.JavaClass.parse(StringToJString('tel:' + PhoneNumber)); Intent.setData(Uri); if TAndroidHelper.Activity.getPackageManager.queryIntentActivities(Intent, 0).size > 0 then TAndroidHelper.Activity.startActivity(Intent) else ShowMessage('No app to handle the call intent.'); end; Share this post Link to post