Jump to content
Ruslan

Make calls from app and get status

Recommended Posts

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

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

×