当我的应用程序使用Android5时,我可以通过检查内容://SMS/sent和内容://SMS/failed来监控短信是否发送或失败。除了通过我的app,我还可以直接从手机的短信应用中看到消息及其状态。
既然老款优秀的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;
**使用repeat until循环读取每条短信,直到"为真**
但是无论短信发送成功与否,我都找不到已发送的短信。
我需要做这个检测,因为我所在地区的信号强度非常低,大约20%的时间短信失败,我的应用程序应该重新发送预期的消息。
PS:我也试着从content://SMS/sent和content://SMS/中搜索SMS,但没有成功。
无论如何,我的问题是:- 如何使发送的短信显示在手机的默认短信应用程序?
- 如何正确判断发送短信是否成功?
我在某个地方读到,上面的方法是使用API,有一种方法来使用手机的短信应用程序代替…但是我不知道如何去做。
谢谢。
为了其他可能有类似情况的人的利益,需要:
(A)能够直接从应用程序发送短信,而不使用手机内置的短信默认应用程序
(B)短信长度可以超过默认的160个字符限制(使用sendmultipartextmessage)
(C)能够知道SMS是否正在处理(基于onReceive from PendingIntent的aResultCode)
众所周知的局限:
- 多sim卡下,短信通过默认sim卡发送
- 如果发送到多个电话收件人,没有办法知道哪一个失败,如果有的话。所以我建议一次发1条短信给1个收件人
- 不检测收件人是否收到短信,因为DeliveryIntent为nil
PS:在Delphi Community Edition 10.4.2和Android Oreo 8.0和8.1下测试
我做了什么:
-
创建并保存BroadcastReceiver的单位(我称之为BCast.pas)从这个链接的第二个答案如何阅读JPendingIntent在Delphi?
-
在你的主目录中。Pas(假设保存为main.pas),添加以下内容:
-
ADD TO PROJECT在步骤1中创建的单元(在我的例子中是bcast.pas)
- 添加广播地址使用条款
-
为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如下:(我把它们放在我的主要的昂秀):
fbroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast); fbroadcast.addactions([StringToJString('xxx')]);
, xxx是任何字符串,将使用匹配操作意图的
-
为sendsms添加一个过程:
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;