Delphi Android READ_PHONE_STATE not triggering Code Answer

Hello Developer, Hope you guys are doing great. Today at Tutorial Guruji Official website, we are sharing the answer of Delphi Android READ_PHONE_STATE not triggering without wasting too much if your time.

The question is published on by Tutorial Guruji team.

I manage to get runtime permission for READ_PHONE_STATE but app doesn’t react to phone state changes at all. I have also in manifest file READ_PHONE_STATE enabled.

Have tried with 3 Android phones but all fail to track state changes.

With iOS i manage to get READ_PHONE_STATE working with same code as i have tried with Android, but in iOS Apple has deprecated showing caller phone number.

    uses
      System.Permissions;

    {$R *.fmx}


    constructor TForm1.Create(AOwner: TComponent);
    const
      PermissionAccessReadPhoneState = 'android.permission.READ_PHONE_STATE';
      PermissionAccessMakeCall = 'android.permission.CALL_PHONE';
    begin
      inherited Create(AOwner);

      TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService));

      PermissionsService.RequestPermissions([PermissionAccessMakeCall, PermissionAccessReadPhoneState],
        procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TpermissionStatus>)
        begin
          if (Length(AgrantResults) = 2) and (AgrantResults[0] = TPermissionStatus.Granted) and (AgrantResults[1] = TPermissionStatus.Granted) then
            begin
              ShowMessage('READ_PHONE_STATE + CALL_PHONE Activated!');
            end;
        end);

if Assigned(PhoneDialerService) then
    begin
      PhoneDialerService.OnCallStateChanged := MyOnCallStateChanged;
    end;
end;

    procedure TForm1.MyOnCallStateChanged(const ACallID: String;
      const ACallState: TCallState);
    var
      outText: String;
    begin
      case ACallState of
        TCallState.None:          outText := 'No calls';
        TCallState.Connected:     outText := 'Connected';
        TCallState.Incoming:      outText := 'Incoming Call';
        TCallState.Dialing:       outText := 'Dialing';
        TCallState.Disconnected:  outText := 'Disconnected';
      end;

      lblCallState.Text := outText;

    end;

Answer

uses
  Androidapi.JNI.Telephony;

type
  TPhoneStateListener = class;
  TfrmTabbed = class(TForm)
    HeaderToolBar: TToolBar;
    ToolBarLabel: TLabel;
    TabControl1: TTabControl;
    ...

  private
    { Private declarations }
    PhoneStateListener: TPhoneStateListener;
    ...

  end;

  TPhoneStateListener = class(TJavaLocal, JICustomPhoneStateListener)
  private
    [weak]
    FParent : TfrmTabbed;
  public
    constructor Create(AParent : TfrmTabbed);
    procedure onCallForwardingIndicatorChanged(cfi: Boolean); cdecl;
    procedure onCallStateChanged(state: Integer; incomingNumber: JString); cdecl;
    procedure onCellInfoChanged(cellInfo: JList); cdecl;
    procedure onCellLocationChanged(location: JCellLocation); cdecl;
    procedure onDataActivity(direction: Integer); cdecl;
    procedure onDataConnectionStateChanged(state: Integer); overload; cdecl;
    procedure onDataConnectionStateChanged(state: Integer; networkType: Integer); overload; cdecl;
    procedure onMessageWaitingIndicatorChanged(mwi: Boolean); cdecl;
    procedure onServiceStateChanged(serviceState: JServiceState); cdecl;
    procedure onSignalStrengthChanged(asu: Integer); cdecl;
    procedure onSignalStrengthsChanged(signalStrength: JSignalStrength); cdecl;
  end;

procedure TfrmTabbed.FormShow(Sender: TObject);
var
  obj: JObject;
begin
  if PhoneStateListener = nil then
      PhoneStateListener := TPhoneStateListener.Create(Self);
    obj := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
    if obj = nil then
      raise Exception.Create('Telephony service not supported');
    CallinUIThread(procedure
    var
      TelephonyManager: JTelephonyManager;
      PSL: JCustomPhoneStateListener;
    begin
      TelephonyManager := TJTelephonyManager.Wrap(obj);
      PSL := TJCustomPhoneStateListener.JavaClass.init(PhoneStateListener);
      TelephonyManager.listen(PSL,
        TJPhoneStateListener.JavaClass.LISTEN_CALL_STATE
      );
    end
    );

{ TPhoneStateListener }

constructor TPhoneStateListener.Create(AParent: TfrmTabbed);
begin
  inherited Create;
  FParent := AParent;
end;

procedure TPhoneStateListener.onCallForwardingIndicatorChanged(cfi: Boolean);
begin
end;

procedure TPhoneStateListener.onCallStateChanged(state: Integer;
  incomingNumber: JString);
begin
  if state = TJTelephonyManager.JavaClass.CALL_STATE_IDLE then
  begin
  end
  else if state = TJTelephonyManager.JavaClass.CALL_STATE_OFFHOOK then
  begin
  end
  else if state = TJTelephonyManager.JavaClass.CALL_STATE_RINGING then
  begin
  end;
end;

procedure TPhoneStateListener.onCellInfoChanged(cellInfo: JList);
begin
end;

procedure TPhoneStateListener.onCellLocationChanged(location: JCellLocation);
begin
end;

procedure TPhoneStateListener.onDataActivity(direction: Integer);
begin
end;

procedure TPhoneStateListener.onDataConnectionStateChanged(state: Integer);
begin
end;

procedure TPhoneStateListener.onDataConnectionStateChanged(state: Integer; networkType: Integer);
begin
end;

procedure TPhoneStateListener.onMessageWaitingIndicatorChanged(mwi: Boolean);
begin
end;

procedure TPhoneStateListener.onServiceStateChanged(serviceState: JServiceState);
begin
end;

procedure TPhoneStateListener.onSignalStrengthChanged(asu: Integer);
begin
end;

procedure TPhoneStateListener.onSignalStrengthsChanged(signalStrength: JSignalStrength);
begin
end;
We are here to answer your question about Delphi Android READ_PHONE_STATE not triggering - If you find the proper solution, please don't forgot to share this with your team members.

Related Posts

Tutorial Guruji