繁体   English   中英

Delphi Firemonkey (Android) - 检测发送短信失败

[英]Delphi Firemonkey (Android) - Detecting Failed Sending SMS

当我的应用程序使用 Android5 时,我可以通过检查 content://sms/sent 和 content://sms/failed 来监控短信是否已发送或失败。 除了通过我的应用程序,我还可以直接从手机的 SMS 应用程序查看消息及其状态。

既然旧的 Android5 智能手机已经死了,我正在升级到基于 Android8 (Oreo) 的更新的智能手机。 但是,我面临检测已发送短信状态的问题。

首先......我无法再使用手机的默认短信应用程序“看到”短信。 第二...即使我一一滚动所有消息,我也无法使用我的应用程序找到短信。

这是我用来发送短信的代码:

smsManager := TJSmsManager.JavaClass.getDefault;
smsTo      := StringToJString(targetstr);
smsarray   := smsmanager.divideMessage(stringtojstring(bodystr));
smsManager.sendmultiparttextMessage(smsTo, nil,smsarray, nil, nil);

虽然这是我用来滚动浏览所有消息的代码:

uri := StrToJURI('content://sms');
smscursor := TAndroidHelper.Activity.getContentResolver.query(uri, nil, nil,nil,nil);
id_id := smscursor.getColumnIndex(StringToJstring('_id'));
idaddress := smscursor.getColumnIndex(StringToJstring('address'));
idbody := smscursor.getColumnIndex(StringToJstring('body'));
idstatus := smscursor.getColumnIndex(StringToJstring('status'));
idthread_id := smscursor.getColumnIndex(StringToJstring('thread_id'));
idtype := smscursor.getColumnIndex(StringToJstring('type'));
smscursor.moveToFirst;

** 使用重复直到循环读取每条短信,直到“islast”为真 **

但是无论短信是否成功发送,我都无法找到已发送的短信。

我需要做这个检测,因为我所在地区的信号强度非常低,大约 20% 的短信失败,我的应用程序应该重新发送预期的消息。

PS:我也尝试从 content://sms/sent 和 content://sms/failed 中搜索短信但无济于事。

无论如何,我的问题是:

  1. 如何使发送的短信显示在手机的默认短信应用程序中?
  2. 如何正确判断发送短信是否成功?

我在某处读到上面的方法是使用 API 并且有一种方法可以使用手机的短信应用程序代替...但我不知道该怎么做。

谢谢你。

为了可能处于类似情况的其他人的利益,需要:

(A) 无需使用手机内置短信默认应用程序,即可直接从应用程序发送短信

(B) 短信长度可以超过默认的 160 个字符限制(使用 sendmultiparttextMessage)

(C) 能够知道短信是否被处理(基于onReceive的ResultCode)

已知限制:

  • 在多卡手机下,短信通过默认卡发送
  • 如果发送给多个电话收件人,则无法知道哪些失败(如果有)。 所以我建议一次发送 1 条短信给 1 个收件人

PS:在 Delphi Community Edition 10.4.2 和 Android Oreo 8.0 和 8.1 下测试

我做了什么:

  1. 从此链接的第二个答案中为 BroadcastReceiver 创建并保存一个单元(我称之为 BCast.pas) How read JPendingIntent in Delphi?

  2. 在您的 main.pas(假设它另存为 main.pas)中,添加以下内容:

  • 添加到项目在步骤 1 中创建的单元(在我的情况下是 bcast.pas)

  • 在使用子句中添加 BCAST

  • 为 TBroadCastReceiver 添加变量(即 fbroadcast : Tbroadcastreceiver;)

  • 在我的例子中做一个 OnReceiveBroadcast 程序:

     private { Private declarations } procedure OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer);
  • 然后在实现中,为 OnReceiveBroadcast 创建代码:

     procedure Tmain.OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer); begin // ... put in the codes here for the result of the last sms send. // // ... use the the value of AResultcode to do the checking // // ... AResultcode=1 means ok, other number means possible error // end;
  • 初始化 fbroadcast 如下:(我把它们放在我主要的 onshow 下):

     fbroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast); fbroadcast.addactions([StringToJString('xxx')]);

    其中 xxx 是用于匹配意图操作的任何字符串

  1. 在sendms中添加一个过程:

     procedure tmain.SendSMSAPI(target,messagestr:string); var smsManager: JSmsManager; // Androidapi.JNI.Telephony // smsTo : JString; // Androidapi.JNI.JavaTypes // PIntent : JPendingIntent; // Androidapi.JNI.App // smsarray : jarraylist; APIntent : JArraylist; intent : JIntent; begin Intent := TJIntent.Create; Intent.setAction(StringToJString('xxx')); PIntent := TJPendingIntent.JavaClass.getBroadcast(TAndroidHelper.Context, 0, Intent, 0); APIntent := Tjarraylist.create; APIntent.add(PIntent); smsManager:= TJSmsManager.JavaClass.getDefault; smsTo := StringToJString(target); // Androidapi.Helpers // smsarray := smsmanager.divideMessage(stringtojstring(messagestr)); smsManager.sendmultiparttextMessage(smsTo, nil,smsarray, APIntent, nil); end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM