uses
SysUtils,
FMX.Helpers.Android,
Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Net,
Androidapi.JNI.JavaTypes,
Androidapi.JNI.Telephony;
function 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);
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/1000))+' '+address+' '+body;
end;
end;
Thanks, this code was really helpful for me.
ReplyDeleteNow I'm trying to understand how to get an event triggered
when a sms arrives so that I don't have to check the sms
inbox continously by means of a timer.
Any ideas about that?
/Ole
In the Android SDK, that is supported using services. I have not heard, that it is possible to implement that with Delphi XE5, we will probably have to wait for Delphi XE6 to do that. XE5 is Embarcadero's first venture into Android land, and while it makes GUI app development significantly easier, it does not support everything.
ReplyDeleteLard, is it possible to access the contact directory of android phone with XE5 ?
ReplyDeleteI'd also like to know if there's any way to get the contacts from XE5 android app?
ReplyDeleteI'm trying to make a sms/mms backup app, along with contact names.
So, to add one more questions: this code reads smses. Can you please provide sample for reading mms-es as well? (with attachments or without them, text-only would also be a way...)
THANKS! :)
+, why cursor.getString(msgdatesentidx)); always returns 0, either for sent or received messages?
ReplyDeleteIf you want to get the correct delivery and sent dates in your query, you need to use "date2" instead of sent_date -> for inbox!
ReplyDeleteHowever, for outbox, for which you keep the exact same code as above, only change the path from /sms/inbox to /sms/sent you must use "report_date" instead of "sent_date".
So, this little modification, and you'll have all the data you need :)
There's also SO topic on this one:
http://stackoverflow.com/questions/21104999/sms-messages-date-sent-on-android-with-delphi-xe5-always-returns-0
How can I use the result of this function? Can I put the 'fetchsms' in one timer?
ReplyDeleteLike this:
begin
memo1.lines.add(fetchsms);
end;
If not, show me the way please.
Hi, Lars,
ReplyDeleteand thanks for this very useful code !!
However when i call this function with this little bit of code, i get only the very first sms on the android device.
procedure TForm1.Button2Click(Sender: TObject);
begin
Memo1.Text := FetchSms;
end;
Can you tell me how to get to the other end of the table containing the sms's and maybe how to select a sender phone number.
I suspect that this latter one is done with the line
getContentResolver.query(uri, nil, nil,nil,nil); , but i dont quite get it.
If you could help me with theese 2 problems i would be grateful.
Thanks in advance,
Christian
How do I delete a sms after I read it
ReplyDeleteThanks, this code was really helpful for me.
ReplyDeletewant to fetch a specific number messages ??
ReplyDeleteThanks nice post !!SMS plugins are one of the best ways to send SMS directly from the browser. SMS plugins help you to create a buzz in the market and making your marketing much easier than other traditional means of communication.
ReplyDelete