结果:
1.不提示发短信卡住,点击没有反映,我猜想,可能是因为我用的是小米手机吧。
2.接收短信报错,我猜想可能是我改了里面的方法吧(哪位大神了解,求指教)。
3.project -->options…--> users permitions。
3.1 Send SMS
3.2 Read Phone State权限:将其变成 true即可。
如果 read phone state为 false,程序将启动不了,一直黑屏(我没试,原作者是这么说的,你如果没事可以试一试,试过记得给我说一声哦)。
实例代码:
unit Unit1; interface uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
FMX.ScrollBox, FMX.Memo, FMX.Layouts,
Androidapi.JNI.Net,//需要引入
Androidapi.JNI.GraphicsContentViewText,//需要引入
Androidapi.JNI.JavaTypes,//需要引入
Androidapi.JNIBridge,//需要引入
Androidapi.Helpers,//需要引入
Androidapi.JNI.Telephony,//需要引入
Androidapi.JNI.Os,//需要引入
FMX.Platform,//需要引入
FMX.Helpers.Android,//需要引入
FMX.MediaLibrary.Actions,//需要引入
FMX.StdActns,//需要引入
FMX.PhoneDialer,//需要引入
FMX.Controls.Presentation;//需要引入 type
TForm1 = class(TForm)
Label1: TLabel;
Memo1: TMemo;
Layout1: TLayout;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
private
{ Private declarations }
public
TelephonyManager: JTelephonyManager;
// 打电话、打开地图显示某个坐标点 、发送电子邮件、播放音乐
procedure Call_URI(const AAction: JString; const AURI: string);
//实现打电话功能
procedure PhoneCall(phoneNumber: string);
//调用系统程序发短信
procedure SentSMSfromIntent(phoneNumber, SMSstring: string);
//直接没有任何提示的发送短信
procedure SentSMS(phoneNumber, SMSstring: string);
//获取Android手机SIM卡串号
procedure GetSN;
//接收短信
function FetchSms: string;
{ Public declarations }
end; var
Form1: TForm1; implementation
{$R *.fmx}
{$R *.NmXhdpiPh.fmx ANDROID} //打电话、打开地图显示某个坐标点 、发送电子邮件、播放音乐
procedure TForm1.Call_URI(const AAction: JString; const AURI: string);
var
uri: Jnet_Uri;
Intent: JIntent;
begin
uri := StrToJURI(AURI);
Intent := TJIntent.JavaClass.init(AAction, uri);
SharedActivityContext.startActivity(Intent);
/// /打开地图显示某个坐标点
// Call_URI(TJIntent.JavaClass.ACTION_VIEW, 'geo:38.899533,-77.036476');
end; //实现打电话功能
procedure TForm1.PhoneCall(phoneNumber: string);
var
phone: IFMXPhoneDialerService;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXPhoneDialerService, IInterface(phone)) then
begin
phone.Call(phoneNumber);
//监听电话状态请用 phone.OnCallStateChanged事件
end;
end; //调用系统程序发短信
procedure TForm1.SentSMSfromIntent(phoneNumber, SMSstring: string);
var
uri: Jnet_Uri;
Intent: JIntent;
begin
uri := StrToJURI('smsto:' + phoneNumber);
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_SENDTO, uri);
Intent.putExtra(StringToJString('sms_body'), StringToJString(SMSstring));
SharedActivityContext.startActivity(Intent);
end; //直接没有任何提示的发送短信
procedure TForm1.SentSMS(phoneNumber, SMSstring: string);
var
j: JSmsManager;
begin
j := tjsmsmanager.Create;
j.sendMultipartTextMessage(StringToJString(phoneNumber), nil, j.divideMessage(StringToJString(SMSstring)), nil, nil);
end; //获取Android手机SIM卡串号
procedure TForm1.GetSN;
var
TelephonyServiceNative: JObject;
begin
TelephonyServiceNative := SharedActivityContext.getSystemService
(TJContext.JavaClass.TELEPHONY_SERVICE);
if Assigned(TelephonyServiceNative) then
TelephonyManager := TJTelephonyManager.Wrap
((TelephonyServiceNative as ILocalObject).GetObjectID);
// TelephonyManager.getDeviceId 取 IMEI
// TelephonyManager.getLine1Number 取 MSISDN 手机号,大部分 SIM 卡中不会写入这个信息
// TelephonyManager.getSimSerialNumber 取 ICCID
// TelephonyManager.getSubscriberId 取 IMSI 运营商实际上是用这个查询的他那张对应电话号码的表
end; //接收短信
function TForm1.FetchSms: string;
var
cursor: JCursor;
uri: Jnet_Uri;
address, person, msgdatesent, protocol, msgread, msgstatus, msgtype,
msgreplypathpresent, Subject, body, servicecenter, locked: string;
msgunixtimestampms: int64;
addressidx, personidx, msgdateidx, msgdatesentidx, protocolidx, msgreadidx,
msgstatusidx, msgtypeidx, msgreplypathpresentidx, subjectidx, bodyidx,
servicecenteridx, lockedidx: integer;
begin
uri := StrToJURI('content://sms/inbox'); //收件箱
cursor := SharedActivity.getContentResolver.query(//uri, nil, nil, nil, nil);
// cursor := SharedActivity.
// managedQuery(
StrToJURI('content://sms/inbox'), //StrToJURI('content://sms/')所有短信, 含发件箱
nil,
StringToJString('1=1) group by (address'),//类似于 SQL 语句,注意,括号只有一半,原因中它已经有一对括号了
nil,
StringToJString('date asc')); //desc 降序
//以上执行的语句是:SELECT * FROM sms WHERE (type=1) AND (1=1) group by (address) order by date asc
addressidx := cursor.getColumnIndex(StringToJstring('address'));//电话
personidx := cursor.getColumnIndex(StringToJstring('person'));
msgdateidx := cursor.getColumnIndex(StringToJstring('date'));
msgdatesentidx := cursor.getColumnIndex(StringToJstring('date_sent'));
protocolidx := cursor.getColumnIndex(StringToJstring('protocol'));
msgreadidx := cursor.getColumnIndex(StringToJstring('read'));
msgstatusidx := cursor.getColumnIndex(StringToJstring('status'));
msgtypeidx := cursor.getColumnIndex(StringToJstring('type'));
msgreplypathpresentidx := cursor.getColumnIndex(StringToJstring('reply_path_present'));
subjectidx := cursor.getColumnIndex(StringToJstring('subject'));
bodyidx := cursor.getColumnIndex(StringToJstring('body'));
servicecenteridx := cursor.getColumnIndex(StringToJstring('service_center'));
lockedidx := cursor.getColumnIndex(StringToJstring('locked'));
// while (cursor.moveToNext) do//对所有短信的循环
// begin
cursor.moveToLast;//最后一条
address := JStringToString(cursor.getString(addressidx));
person := JStringToString(cursor.getString(personidx));
msgunixtimestampms := cursor.getLong(msgdateidx);
msgdatesent := JStringToString(cursor.getString(msgdatesentidx));
protocol := JStringToString(cursor.getString(protocolidx));
msgread := JStringToString(cursor.getString(msgreadidx));
msgstatus := JStringToString(cursor.getString(msgstatusidx));
msgtype := JStringToString(cursor.getString(msgtypeidx));
msgreplypathpresent := JStringToString(cursor.getString(msgreplypathpresentidx));
Subject := JStringToString(cursor.getString(subjectidx));
body := JStringToString(cursor.getString(bodyidx));
servicecenter := JStringToString(cursor.getString(servicecenteridx));
locked := JStringToString(cursor.getString(lockedidx));
Result := IntToStr(trunc(msgunixtimestampms / ))+#
+ '号码:' + address +#
+ 'person:' + person +#
+ 'msgdatesent:' + msgdatesent +#
+ 'protocol:' + protocol +#
+ 'msgread:' + msgread+#
+ 'msgstatus:' + msgstatus +#
+ 'msgtype:' + msgtype +#
+ 'msgreplypathpresent:' + msgreplypathpresent+#
+ 'Subject:' + Subject+#
+ 'servicecenter:' + servicecenter +#
+ 'locked:' + locked +#
+ '内容:' + body;
end; procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Text := '打电话、发短信和邮件,取得手机 IMEI!';
end; procedure TForm1.Button2Click(Sender: TObject);
begin
PhoneCall('');
//Call_URI(TJIntent.JavaClass.ACTION_CALL, 'tel:10086');//这个也可以
end; procedure TForm1.Button3Click(Sender: TObject);
begin
//直接没有任何提示的发送短信,尽量不用,这不道德。短信不限制长度,如超长,自动分条发送
SentSMS('', '直接没有任何提示的发送短信');
end; procedure TForm1.Button4Click(Sender: TObject);
begin
//调用系统程序发短信,短信不限制长度,如超长,自动分条发送
SentSMSfromIntent('', '调用系统程序发短信。');
end; procedure TForm1.Button5Click(Sender: TObject);
begin
//调用系统程序发送电子邮件
Call_URI(TJIntent.JavaClass.ACTION_SENDTO, 'mailto:513187410@qq.com');
end; procedure TForm1.Button6Click(Sender: TObject);
begin
GetSN; //先调用一下
Label1.Text := '本手机 IMEI:' + jstringtostring(TelephonyManager.getDeviceId); //取IMEI;
end; procedure TForm1.Button7Click(Sender: TObject);
begin
Memo1.Lines.Text := FetchSms;
end; end.
这个是测试用的,小伙伴们不要用哦。
var
cursor: JCursor;
uri: Jnet_Uri;
address,person,msgdatesent,protocol,msgread,msgstatus,msgtype,
msgreplypathpresent,subject,body,
servicecenter,locked:string;
msgunixtimestampms:int64;
addressidx,personidx,msgdateidx,msgdatesentidx,protocolidx,msgreadidx,
msgstatusidx,msgtypeidx,msgreplypathpresentidx,subjectidx,bodyidx,
servicecenteridx,lockedidx:integer;
begin
uri:=StrToJURI('content://sms/inbox');
cursor := SharedActivity.getContentResolver.query(uri, nil, nil,nil,nil);
addressidx:=cursor.getColumnIndex(StringToJstring('address'));
personidx:=cursor.getColumnIndex(StringToJstring('person'));
msgdateidx:=cursor.getColumnIndex(StringToJstring('date'));
msgdatesentidx:=cursor.getColumnIndex(StringToJstring('date_sent'));
protocolidx:=cursor.getColumnIndex(StringToJstring('protocol'));
msgreadidx:=cursor.getColumnIndex(StringToJstring('read'));
msgstatusidx:=cursor.getColumnIndex(StringToJstring('status'));
msgtypeidx:=cursor.getColumnIndex(StringToJstring('type'));
msgreplypathpresentidx:=cursor.getColumnIndex(StringToJstring('reply_path_present'));
subjectidx:=cursor.getColumnIndex(StringToJstring('subject'));
bodyidx:=cursor.getColumnIndex(StringToJstring('body'));
servicecenteridx:=cursor.getColumnIndex(StringToJstring('service_center'));
lockedidx:=cursor.getColumnIndex(StringToJstring('locked'));
while (cursor.moveToNext) do begin
address:=JStringToString(cursor.getString(addressidx));
person:=JStringToString(cursor.getString(personidx));
msgunixtimestampms:=cursor.getLong(msgdateidx);
msgdatesent:=JStringToString(cursor.getString(msgdatesentidx));
protocol:=JStringToString(cursor.getString(protocolidx));
msgread:=JStringToString(cursor.getString(msgreadidx));
msgstatus:=JStringToString(cursor.getString(msgstatusidx));
msgtype:=JStringToString(cursor.getString(msgtypeidx));
msgreplypathpresent:=JStringToString(cursor.getString(msgreplypathpresentidx));
subject:=JStringToString(cursor.getString(subjectidx));
body:=JStringToString(cursor.getString(bodyidx));
servicecenter:=JStringToString(cursor.getString(servicecenteridx));
locked:=JStringToString(cursor.getString(lockedidx));
Result:=IntToStr(trunc(msgunixtimestampms/))+' '+address+' '+body;
end;
end;
https://blog.csdn.net/davidtps/article/details/27321801