Reputation: 362
I would appreciate some help in finding a working code for reading sms messages, on android kitkat. I am aware that the app has to be a default sms app with relevant permissions. I really don't want to annoy the user with any popup dialog requesting that the user manually selects the default sms app. I would like my app to perform as the default sms until its task is completed then return the setting to the original default sms that the user or factory has set, before using my app.
Currently, I am NOT able to display any sms messages and can't see why. I am, however, seeing my app listed among the default sms apps on the testing device.
Here is the code that I am using:
function TForm1.Process_SMS: string;
var
cursor: JCursor;
uri: Jnet_Uri;
address, person, msgdatesent, protocol, msgread, msgstatus, msgtype,
msgreplypathpresent, subject, body,
smsid, servicecenter, locked: string;
msgunixtimestampms: int64;
id_smsid, 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);
id_smsid := cursor.getColumnIndex(StringToJstring('_id'));
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
smsid := JStringToString(cursor.getString(id_smsid));
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));
Listbox1.Items.Add(subject);
// I plan on deleting messages here
//SharedActivity.getContentResolver.delete(uri, StringToJString('_ID=' + smsid), nil);
Result := IntToStr(trunc(msgunixtimestampms/1000)) + ' ' + address + ' ' + body;
end;
end;
This how I call it:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
label1.text := Process_SMS;
end;
Here is the xml file I am using:
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.embarcadero.ezt"
android:versionCode="19"
android:versionName="1.0.0"
android:installLocation="preferExternal">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="11" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BROADCAST_SMS" />
<uses-permission android:name="android.permission.BROADCAST_WAP_PUSH" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CALL_PRIVILEGED" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-feature android:glEsVersion="0x00020000" android:required="True"/>
<application android:persistent="False"
android:restoreAnyVersion="False"
android:label="ezt"
android:debuggable="True"
android:largeHeap="False"
android:icon="@drawable/ic_launcher"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true">
<!-- Our activity is a subclass of the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="ezt"
android:configChanges="orientation|keyboard|keyboardHidden"
android:launchMode="singleTask">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="ezt" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" />
<!-- BroadcastReceiver that listens for incoming SMS messages -->
<receiver android:name=".SmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_DELIVER" />
</intent-filter>
</receiver>
<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver android:name=".MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<!-- Activity that allows the user to send new SMS/MMS messages -->
<activity android:name=".ComposeSmsActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>
<!-- Service that delivers messages from the phone "quick response" -->
<service android:name=".HeadlessSmsSendService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->
On my testing device I have selected my app as the default sms app and under personal->security->app permissions, I have set it to "always allow" my app for READ SMS. The interface for my app is simply a Listbox and two speed buttons.
Please and thanks for your help. I am lost...
Upvotes: 0
Views: 2128
Reputation: 362
I sent two text messages from another phone, today, to my test device, and I had two previous text messages before. This means there is a total of 4 messages in there(test device). When I run my app now, I see the last 2 text messages. I don't know why, I only see the last 2. I am just glad that I see something, because now development can continue. I have now disabled "app permissions". I have also NOT set my app as the default sms either. It's strange that it's working even with this configuration. Anyways, thanks to everyone who checked in to view this question.
Upvotes: 2