delphi xe 10 安卓 监听来电去电存在一些机型监听不到,寻求解决办法

DelphixpeFan 2018-02-10 11:34:44
按delphi xe 的帮助文档

uses
FMX.PhoneDialer;
type
TFormPhoneMain=class(TForm)
constructor Create(AOwner: TComponent); override;
procedure MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState);
private
PhoneDialerService: IFMXPhoneDialerService;

{Form}
constructor TFormPhoneMain.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(PhoneDialerService));
if Assigned(PhoneDialerService) then
PhoneDialerService.OnCallStateChanged:=MyOnCallStateChanged;
end;

procedure TFormPhoneMain.MyOnCallStateChanged(const ACallID: String; const ACallState: TCallState);
var
outText, s: String;
MyNotification: TNotification;
Begin
case ACallState of
TCallState.None:
outText:='无通话';
TCallState.Connected:
outText:='接通';
TCallState.Incoming:
outText:='来电';
TCallState.Dialing:
outText:='去电';
TCallState.Disconnected:
outText:='挂断';
end;
s:='';
with UniQuery6 do
begin
Close;
ParamByName('V').Value:=ACallID;
Open;
if RecordCount>0 then
s:=FieldByName('User_Name').AsString+' '+outText
else
s:='未知号码 '+outText;
end;
lblCallState.Text:='当前通话状态 '+s+': '+ACallID;
FormActivate(nil);
if (outText='来电')or(outText='去电') then
begin
Timer1.Enabled:=True;
// Create an instance of TNotification
MyNotification:=NotificationCenter1.CreateNotification;
try
MyNotification.Name:='来电显示';
// --- your code goes here ---
// Set the icon or notification number
MyNotification.Number:=18;
// Set the alert message
MyNotification.AlertBody:=lblCallState.Text;
// Note: You must send the notification to the notification center for the Icon Badge Number to be displayed.
NotificationCenter1.PresentNotification(MyNotification);
finally
MyNotification.DisposeOf;
end;
end
else
begin
Timer1.Enabled:=False;
NotificationCenter1.CancelNotification('来电显示');
BringAppToFront(TJIntent.JavaClass.ACTION_MAIN);
end;
End;


结果在一些手机上可以正常获取到来电,并把来电号码与自建的电话号本匹配,发出来电信息的通知;而大部分新的手机都监听不到;网上查询了一圈,的确有这样的事情发生,JAVA用新建一个监听来解决,但Delphi xe 目前资料太少,长时间没找到解决方法,有人有解决办法或者建议么?

参考网上一些相关的JAVA代码,感觉通过自建监听的方式,有可能能解决,分析了 Androidapi.JNI.Telephony 单元,发现其中的TJPhoneStateListener类应该能够实现需求,它的定义是这样的:
[JavaSignature('android/telephony/PhoneStateListener')]
JPhoneStateListener = interface(JObject)
['{50CE10E1-C584-4145-BC72-65BFA48BB281}']
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); cdecl; overload;
procedure onDataConnectionStateChanged(state: Integer; networkType: Integer); cdecl; overload;
procedure onMessageWaitingIndicatorChanged(mwi: Boolean); cdecl;
procedure onServiceStateChanged(serviceState: JServiceState); cdecl;
procedure onSignalStrengthChanged(asu: Integer); cdecl;//Deprecated
procedure onSignalStrengthsChanged(signalStrength: JSignalStrength); cdecl;
end;
TJPhoneStateListener = class(TJavaGenericImport<JPhoneStateListenerClass, JPhoneStateListener>) end;

现在问题来了,我该如何使用呢?
...全文
2027 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
光这个文件肯定不行,你看它uses了多少单元。你下载后把某个版本的SDK接口,比如android-26,复制出来,然后添加到项目的查找路径就可以使用了。
  • 打赏
  • 举报
回复
EMB没有完整翻译Android API,但是提供了一个工具java2op.exe,可以翻译Android API,另外也有人翻译了完整的各Android版本SDK接口文件:https://github.com/FMXExpress/android-object-pascal-wrapper/
ooolinux 2018-02-12
  • 打赏
  • 举报
回复
去英巴官网论坛问了吗?
DelphixpeFan 2018-02-12
  • 打赏
  • 举报
回复
唉,不能解决,TAndroidHelper.Activity.requestPermissions(LPermissions, 0);显式申请权限提示缺少requestPermissions这个过程,检查权限,显示没有找到Java类(PermissionChecker)。有高手能帮忙看下么?
DelphixpeFan 2018-02-12
  • 打赏
  • 举报
回复
https://github.com/FMXExpress/android-object-pascal-wrapper/blob/master/android-26/android.app.Activity.pas 我在他的文件里的确找到了给权限的相关内容 procedure requestPermissions(permissions : TJavaArray<JString>; requestCode : Integer) ; cdecl; procedure onRequestPermissionsResult(requestCode : Integer; permissions : TJavaArray<JString>; grantResults : TJavaArray<Integer>) ; cdecl; 我的问题是,我只下载这个PAS,并把这个PAS加载到工程文件里,可行么?还是要其他什么操作?
DelphixpeFan 2018-02-12
  • 打赏
  • 举报
回复
引用 7 楼 DelphiGuy 的回复:
EMB没有完整翻译Android API,但是提供了一个工具java2op.exe,可以翻译Android API,另外也有人翻译了完整的各Android版本SDK接口文件:https://github.com/FMXExpress/android-object-pascal-wrapper/
这样工程量就太大了,而且我印象有人发过文章,说翻译过来,几万条代码,还不是说立马就可以用的,查错会要老命.我做个小程序玩玩,还范不着这么大动干戈,但不管怎么说,还是要谢谢你的帮助.
ooolinux 2018-02-12
  • 打赏
  • 举报
回复
@早打大打打核战争 那实际编程要把.pas文件加入工程,编译生成.hpp和.lib后,再把.pas文件去掉,包含.hpp头文件后调用API?
  • 打赏
  • 举报
回复
不用,有.pas就行,Delphi编译器(CB自带)能自动生成给CB用的.hpp和.lib。
ooolinux 2018-02-12
  • 打赏
  • 举报
回复
@早打大打打核战争 如果用CB写安卓程序,Android API的Delphi接口文件还要再翻译为C++格式的吗?
DelphixpeFan 2018-02-11
  • 打赏
  • 举报
回复
uses Androidapi.Helpers, Androidapi.JNIBridge, Androidapi.JNI.JavaTypes; ... var LPermissions: TJavaObjectArray<JString>; begin LPermissions := TJavaObjectArray<JString>.Create(1); LPermissions.Items[0] := StringToJString('android.permission.READ_PHONE_STATE'); TAndroidHelper.Activity.requestPermissions(LPermissions, 0); end; 现在的问题是,因为Delphi中的Activity没有实现onRequestPermissionsResult,所以你不知道 用户是否真正授予了权限; 至少不是通过那种异步的方法。解决这个问题的方法可能是 稍后在某个时间点检查权限。问题是 在Delphi RTL中没有导入适当的Java类(PermissionChecker)。我只是碰巧自己做了这个导入,并创建了 下面的代码: type TAndroidPermissions = class(TObject) public const CAMERA = 'android.permission.CAMERA'; const RECORD_AUDIO = 'android.permission.RECORD_AUDIO'; const READ_CONTACTS = 'android.permission.READ_CONTACTS'; const READ_PHONE_STATE = 'android.permission.READ_PHONE_STATE'; public class function CheckPermission(const APermissionName: string): Boolean; static; end; implementation uses Androidapi.JNI.JavaTypes, Androidapi.JNI.GraphicsContentViewText, Androidapi.JNIBridge, Androidapi.Helpers; type JPermissionCheckerClass = interface(JObjectClass) ['{FC8D7A0B-078A-4DBB-B115-17E6F0E7CA18}'] {class} function _GetPERMISSION_DENIED: Integer; cdecl; {class} function _GetPERMISSION_DENIED_APP_OP: Integer; cdecl; {class} function _GetPERMISSION_GRANTED: Integer; cdecl; {class} function checkCallingOrSelfPermission(P1: JContext; P2: JString): Integer; cdecl; {class} function checkCallingPermission(P1: JContext; P2: JString; P3: JString): Integer; cdecl; {class} function checkPermission(P1: JContext; P2: JString; P3: Integer; P4: Integer; P5: JString): Integer; cdecl; {class} function checkSelfPermission(P1: JContext; P2: JString): Integer; cdecl; {class} property PERMISSION_DENIED: Integer read _GetPERMISSION_DENIED; {class} property PERMISSION_DENIED_APP_OP: Integer read _GetPERMISSION_DENIED_APP_OP; {class} property PERMISSION_GRANTED: Integer read _GetPERMISSION_GRANTED; end; [JavaSignature('android/support/v4/content/PermissionChecker')] JPermissionChecker = interface(JObject) ['{AF30C4BE-CF3B-4AE0-A274-D96FBC08728E}'] end; TJPermissionChecker = class(TJavaGenericImport<JPermissionCheckerClass, JPermissionChecker>) end; { TAndroidPermissions } class function TAndroidPermissions.CheckPermission(const APermissionName: string): Boolean; begin Result := TJPermissionChecker.JavaClass.checkSelfPermission(TAndroidHelper.Context, StringToJString(APermissionName)) = TJPermissionChecker.JavaClass.PERMISSION_GRANTED; end; 这可以这样调用: TAndroidPermissions.CheckPermission(TAndroidPermissions.READ_PHONE_STATE); 这可能是您现在的临时解决方案,但使用onRequestPermissionsResult会更可靠。 Brian Long最初的方法是“覆盖”一个原生的Activity方法,例如他在这里所做的: http : //blong.com/Articles/DelphiXE7NFC/NFC.htm 可能是一个潜在的解决方案,然而Embarcadero真的应该使它成为FMXNativeActivity的一部分,因为 随着时间的推移,这个问题会越来越频繁地出现。
DelphixpeFan 2018-02-11
  • 打赏
  • 举报
回复
引用 1 楼 DelphiGuy 的回复:
应该是权限管理的问题,见:https://newsgroups.embarcadero.com/thread.jspa?threadID=245771
谢谢,我试试这个帖子给出的解决办法,怀疑是安卓6.0版本权限给不到,需要显式给权限;另外,就是认为SDK版本太低了,要升级v4文件
lyhoo163 2018-02-11
  • 打赏
  • 举报
回复
Delphi xe 目前资料太少
  • 打赏
  • 举报
回复

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧