Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Android Gelen Çağrı Durumunu Yakalamak
#1
Merhabalar,
Zamanında üstadın https://www.delphican.com/showthread.php?tid=63 burada anlattığını 32 bit çalışan eski android telefonlarda denedim, gayet güzel arayan numarayı yakalayabiliyorum.  Fakat yeni 9-10-11 sürümlü telefonlarda maalesef aşağıdaki kod satırına girmiyor bile. Bununla ilgili bir çalışma yapanınız olduysa yardımcı olursa sevinirim. Yabancı forumlarda da aradım. Aynı sorunu yaşayanlar olmuş fakat çözümü bulamadım. Teşekkürler.
Cevapla
#2
Merhabalar,
Bu süre zarfında Embarcadero' ya ticket açtım. Ve dönüşleri şu şekilde oldu, sonrasında örnek bir kod ile beni çözüme ulaştırdılar.

Android işletim sistemine bağlı, işletim sisteminin bunu nasıl idare ettiği konusunda büyük bir değişiklik oldu. FMX telefon durum dinleyicisinin doğrudan nasıl kullanılacağına dair küçük bilgiler ekledim, bunun eski Android 31 öncesi API'yi kullandığını unutmayın.

Ben çağrı alındığında gelen numarayı sql' e aktardım ve tüm android sürümlerinde gelen çağrıyı yakalayabiliyorum Smile

unit Unit3;

interface

uses
 System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
 System.Permissions,FMX.Platform,FMX.Controls.Presentation,FMX.DialogService,
 FMX.Helpers.Android,
 Androidapi.JNI.Telephony,Androidapi.JNIBridge,Androidapi.JNI.Os, Androidapi.JNI.JavaTypes,
 Androidapi.Helpers, Androidapi.JNI.GraphicsContentViewText, FMX.VirtualKeyboard,
 FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
 FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
 FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef,
 FireDAC.Stan.ExprFuncs, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf,
 FireDAC.DApt, FireDAC.Phys.SQLiteWrapper.Stat, FireDAC.FMXUI.Wait, DBAccess,
 Uni, UniProvider, SQLServerUniProvider, Data.DB, MemDS, FireDAC.Comp.UI,
 FireDAC.Comp.DataSet, FireDAC.Comp.Client, FMX.Edit;


type
   TPhoneStateListener = class(TJavaLocal,  Androidapi.JNI.Telephony.JICustomPhoneStateListener)
   public
   procedure onCallForwardingIndicatorChanged(cfi: Boolean); cdecl;
   procedure onCallStateChanged(state: Integer; incomingNumber: JString); cdecl;
   procedure onCellInfoChanged(cellInfo: JList); cdecl;
   procedure onCellLocationChanged(location: Androidapi.JNI.Telephony.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: Androidapi.JNI.Telephony.JServiceState); cdecl;
   procedure onSignalStrengthChanged(asu: Integer); cdecl;
   procedure onSignalStrengthsChanged(signalStrength: Androidapi.JNI.Telephony.JSignalStrength); cdecl;
 end;


 TForm3 = class(TForm)
   Label1: TLabel;
   CornerButton1: TCornerButton;
   Label2: TLabel;
   FDConnection1: TFDConnection;
   FQAYAR: TFDQuery;
   FQAYARHOST: TWideMemoField;
   FQAYARPORT: TWideMemoField;
   FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
   FDGUIxWaitCursor1: TFDGUIxWaitCursor;
   FQGELENCAGRILAR: TUniQuery;
   FQGELENCAGRILARID: TIntegerField;
   FQGELENCAGRILARTELEFON: TWideStringField;
   FQGELENCAGRILARTARIH: TDateTimeField;
   FQGELENCAGRILARDURUM: TIntegerField;
   SQLServerUniProvider1: TSQLServerUniProvider;
   UniConnection1: TUniConnection;
   host: TEdit;
   port: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure CornerButton1Click(Sender: TObject);
   procedure FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
     Shift: TShiftState);
   procedure FDConnection1BeforeConnect(Sender: TObject);
   procedure FormShow(Sender: TObject);
 private
   { Private declarations }
    FPhoneReadCallLog, FCallPhonePermission, FPhoneStatePermission: string;
    FPhoneStateListener      : TPhoneStateListener;
    FPre31TelephonyManager   : Androidapi.JNI.Telephony.JTelephonyManager;


    procedure DisplayRationale(Sender: TObject; const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc);
    procedure MakePhoneCallPermissionRequestResult(Sender: TObject; const APermissions: TClassicStringDynArray; const AGrantResults: TClassicPermissionStatusDynArray);
    procedure RunListen;
    procedure StartListenForIncoming;
 public
   { Public declarations }
 end;

var
 Form3: TForm3;

implementation

{$R *.fmx}


procedure TForm3.StartListenForIncoming;
var
 LTelephonyServiceNative: JObject;
begin
 if Assigned(TAndroidHelper.Context) then
 begin
   LTelephonyServiceNative := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.TELEPHONY_SERVICE);
   if Assigned(LTelephonyServiceNative) then
       FPre31TelephonyManager := Androidapi.JNI.Telephony.TJTelephonyManager.Wrap(LTelephonyServiceNative);
     FPhoneStateListener := TPhoneStateListener.Create;
     CallInUIThread(RunListen);
 end;
end;


procedure TForm3.RunListen;
begin
 if Assigned(FPre31TelephonyManager) then
     FPre31TelephonyManager.listen(TJCustomPhoneStateListener.JavaClass.init(FPhoneStateListener),
               TJPhoneStateListener.JavaClass.LISTEN_CALL_STATE );
end;

procedure TForm3.DisplayRationale(Sender: TObject;
 const APermissions: TClassicStringDynArray; const APostRationaleProc: TProc);
begin
  TDialogService.ShowMessage('The app needs to be able to listening for ringing',
   procedure(const AResult: TModalResult)
   begin
     APostRationaleProc;
   end)
end;

procedure TForm3.FDConnection1BeforeConnect(Sender: TObject);
begin
FDConnection1.Params.Values['Database'] := GetHomePath + PathDelim + 'baglanti.db';
end;

procedure TForm3.FormCreate(Sender: TObject);
begin
//this might only be needed on pre-31 Android
FCallPhonePermission := JStringToString(TJManifest_permission.JavaClass.CALL_PHONE);
FPhoneStatePermission := JStringToString(TJManifest_permission.JavaClass.READ_PHONE_STATE);
FPhoneReadCallLog := JStringToString(TJManifest_permission.JavaClass.READ_CALL_LOG);

Label2.Text := 'Android API: '+TJBuild_VERSION.JavaClass.SDK_INT.ToString;
end;

procedure TForm3.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
 Shift: TShiftState);
Var
 keyboard: IFMXVirtualKeyboardService;
begin
 if (Key = vkHardwareBack) then
 Begin

   keyboard := TPlatformServices.Current.GetPlatformService(IFMXVirtualKeyboardService) as IFMXVirtualKeyboardService;

   if  TVirtualKeyboardState.Visible in keyboard.VirtualKeyBoardState then   Exit;

   SharedActivity.moveTaskToBack(True);

   Key := 0;

 End;
end;
procedure TForm3.FormShow(Sender: TObject);
begin
 FDConnection1.Connected:=false;
 FDConnection1.Connected:=true;

 FQAYAR.Close;
 FQAYAR.Open;

 host.Text:=FQAYARHOST.Value;
 port.Text:=FQAYARPORT.Value;
end;

procedure TForm3.CornerButton1Click(Sender: TObject);
begin
  PermissionsService.RequestPermissions([FCallPhonePermission, FPhoneStatePermission,FPhoneReadCallLog], MakePhoneCallPermissionRequestResult, DisplayRationale);
 FDConnection1.Connected:=false;
 FDConnection1.Connected:=true;

 FQAYAR.Close;
 FQAYAR.Open;

 FQAYAR.Edit;
 FQAYARHOST.Text:=host.Text;
 FQAYARPORT.Text:=port.Text;
 FQAYAR.Post;

 UniConnection1.Server:=host.Text;
 UniConnection1.Port:=StrToInt(port.Text);
 try
 UniConnection1.Connected:=false;
 UniConnection1.Connected:=true;
 ShowMessage('BİLGİSAYAR İLE BAĞLANTI KURULDU');
 except on E: Exception do
 ShowMessage('BİLGİSAYAR İLE BAĞLANTI KURULAMADI');
 end;
end;

procedure TForm3.MakePhoneCallPermissionRequestResult(Sender: TObject;
 const APermissions: TClassicStringDynArray;
 const AGrantResults: TClassicPermissionStatusDynArray);
var
 PermissionGranted : boolean;
begin
PermissionGranted := ((Length(AGrantResults) = 3) and
(AGrantResults[0] = TPermissionStatus.Granted) and
(AGrantResults[1] = TPermissionStatus.Granted) and
(AGrantResults[2] = TPermissionStatus.Granted)
);

if PermissionGranted  then
   StartListenForIncoming
else
  TDialogService.ShowMessage('Cannot listen for ringing because the required permission has not been granted');
end;



{ TPhoneStateListener }

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

procedure TPhoneStateListener.onCallStateChanged(state: Integer;
 incomingNumber: JString);
begin
if state = TJTelephonyManager.JavaClass.CALL_STATE_RINGING then
begin
  Form3.Label1.Text := copy(JStringToString(incomingNumber),3,12) ;
  Form3.FQGELENCAGRILAR.Active:=true;
  Form3.FQGELENCAGRILAR.Insert;
  Form3.FQGELENCAGRILARTELEFON.Text:=Form3.label1.Text;
  Form3.FQGELENCAGRILARTARIH.AsDateTime:=now;
  Form3.FQGELENCAGRILARDURUM.Value:=0;
  Form3.FQGELENCAGRILAR.Post;
end;

end;

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

procedure TPhoneStateListener.onCellLocationChanged(location: Androidapi.JNI.Telephony.JCellLocation);
begin
//Not needed
end;

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

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

procedure TPhoneStateListener.onDataConnectionStateChanged(state,
 networkType: Integer);
begin
//Not needed
end;

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

procedure TPhoneStateListener.onServiceStateChanged(
 serviceState: Androidapi.JNI.Telephony.JServiceState);
begin
//Not needed
end;

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

procedure TPhoneStateListener.onSignalStrengthsChanged(
 signalStrength: Androidapi.JNI.Telephony.JSignalStrength);
begin
//Not needed
end;

end.
Cevapla
#3
9dan sonra kapadılar o apiyi, normalde daha çağrı telefona düşmeden çağrıyı numarayı yakalayabiliyorduk. hatta görüşmeyi bile kaydedebiliyorduk. artık varsayılan telefon arama uygulaması yapmadan bu erişime sahip olamıyorsun

Şimdi çağrı geldiğinde, kilt ekranı açılana kadar numarayı yakalayamıyorsun. kısıtlaya kısıtlaya IOS'a çevirdiler androidi iyice.
WWW
Cevapla
#4
Evet haklısınız. Bende Embarcadero' ya ticket açtıktan sonra kesin çözüm sandığım cevabı yukarıda paylaşmıştım. Fakat sonradan fark ettim ki %100 tüm cihazlarda çalışmıyor. Bu işin Delphi' de çözümü yok sanırım.
Cevapla
#5
(03-11-2022, Saat: 11:28)yhackup Adlı Kullanıcıdan Alıntı: 9dan sonra kapadılar o apiyi, normalde daha çağrı telefona düşmeden çağrıyı numarayı yakalayabiliyorduk. hatta görüşmeyi bile kaydedebiliyorduk. artık varsayılan telefon arama uygulaması yapmadan bu erişime sahip olamıyorsun

Şimdi çağrı geldiğinde, kilt ekranı açılana kadar numarayı yakalayamıyorsun. kısıtlaya kısıtlaya IOS'a çevirdiler androidi iyice.

Uygulamanızı varsayılan çağrı uygulaması dışında varsayılan çağrı filtresi uygulaması (Örnek:Hiya, Truecaller) olarak ayarlamayı deneyin. Çağrıları kilit ekranını açmadan da yakalayabileceğinizi tahmin ediyorum.
Cevapla
#6
(05-11-2022, Saat: 16:57)emrahozten Adlı Kullanıcıdan Alıntı: Evet haklısınız. Bende Embarcadero' ya ticket açtıktan sonra kesin çözüm sandığım cevabı yukarıda paylaşmıştım. Fakat sonradan fark ettim ki %100 tüm cihazlarda çalışmıyor. Bu işin Delphi' de çözümü yok sanırım.

Sorunun Delphi ile bir ilgisi yok. 
Embarcedoru'nun size sunmuş olduğu çözüm önerisine bakarsanız; (TAndroidHelper sınıfını inceleyin) Android Java native kodlarını implement ederek kullanıyor.
Yani hangi geliştirme ortamında test ederseniz edin aynı sonuca ulaşırsınız.
Begin : = end / 2;
Cevapla
#7
(05-11-2022, Saat: 18:32)engerex Adlı Kullanıcıdan Alıntı:
(03-11-2022, Saat: 11:28)yhackup Adlı Kullanıcıdan Alıntı: 9dan sonra kapadılar o apiyi, normalde daha çağrı telefona düşmeden çağrıyı numarayı yakalayabiliyorduk. hatta görüşmeyi bile kaydedebiliyorduk. artık varsayılan telefon arama uygulaması yapmadan bu erişime sahip olamıyorsun

Şimdi çağrı geldiğinde, kilt ekranı açılana kadar numarayı yakalayamıyorsun. kısıtlaya kısıtlaya IOS'a çevirdiler androidi iyice.

Uygulamanızı varsayılan çağrı uygulaması dışında varsayılan çağrı filtresi uygulaması (Örnek:Hiya, Truecaller) olarak ayarlamayı deneyin. Çağrıları kilit ekranını açmadan da yakalayabileceğinizi tahmin ediyorum.

Belki ama bıraktım zaten o projeyi, bir arkadaş ile ortaktık sonra yasal olarak yasaklandı bu tür uygulamalar (kim arıyor gibi) bizde bıraktık.
WWW
Cevapla
#8
(07-11-2022, Saat: 16:07)yhackup Adlı Kullanıcıdan Alıntı:
(05-11-2022, Saat: 18:32)engerex Adlı Kullanıcıdan Alıntı: Uygulamanızı varsayılan çağrı uygulaması dışında varsayılan çağrı filtresi uygulaması (Örnek:Hiya, Truecaller) olarak ayarlamayı deneyin. Çağrıları kilit ekranını açmadan da yakalayabileceğinizi tahmin ediyorum.

Belki ama bıraktım zaten o projeyi, bir arkadaş ile ortaktık sonra yasal olarak yasaklandı bu tür uygulamalar (kim arıyor gibi) bizde bıraktık.

Bir ara mahkeme kararı ile engel geldi ancak tam olarak yasak olduğunu sanmıyorum. Hiya, Tuecaller halen indirilip kullanılabiliyor. Hatta Hiya Samsung cihazlarda dahili (kurulu değil sisteme dahili) geliyor ve performansı da gayet iyi.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Android Uygulama İkonu ARM 2 400 11-11-2025, Saat: 12:15
Son Yorum: ARM
  Android SDK kajmerantime 1 385 28-10-2025, Saat: 14:53
Son Yorum: cinarbil
  Android El Terminali Barkod Okuyucu Verisi tuna 0 334 17-10-2025, Saat: 01:07
Son Yorum: tuna
  Android işlem öneriliyor uyarısı! Coban 9 1.863 07-08-2025, Saat: 12:07
Son Yorum: RAD Coder
  FMX Android Adaptive Icons kullanabilir miyiz? egeven 1 2.157 30-06-2025, Saat: 21:46
Son Yorum: emozgun



Konuyu Okuyanlar: 1 Ziyaretçi