I wish to achieve a SMS loopback, i.e. to send and receive SMS from the same application. In order to do so, I have created a class that extends BroadcastReciever, implemented the onReceive() method, and declared the relevant permissions.
I verified the implementation by sending a SMS using telnet.
I want to automate the telnet process, i.e. having the application test itself by sending the SMS. In order to do so, I invoke the following method in the main activity, but the BroadcastReceiver is never called:
private final void sendSMS() {
final TelephonyManager telMgr = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
final int len = telMgr.getLine1Number().length();
final String phoneNum = telMgr.getLine1Number().substring(len - 4, len);
final String msg = "msg";
SmsManager.getDefault().sendTextMessage(phoneNum, null, msg, null, null);
}
Any clue what is wrong...?
UPDATE: Note that the code above is intended for the emulator.
Not sure if I understand you question right, but are you trying send an SMS from the emulator to itself? As far as I know, that is not possible. Just load up another emulator, and send messages between them.
Since telnet commands work, your BroadcastReceiver is probably correctly implemented, but you should probably attach the code for it anyways... Its hard to troubleshoot code you can't see :)
Related
My application basically backup the SMS and MMS to cloud server. I used below URI to retrieve data from database.
SMS- Uri uri = Uri.parse("content://sms/");
MMS-Uri uri = Uri.parse("content://mms/");
Few days back while testing my app i noticed some messages(SMS & MMS) are missing while retrieving from SQLite. After doing some research i found that those are RCS (Rich Communication Services) messages. Now my challenge is to read RCS messages(SMS & MMS).
Is there any way to read RCS (Rich Communication Services) messages in Android?
What URI i need to use for read RCS (Rich Communication Services) messages?
Thanks in advance.
EDIT: It seems like the API won’t make it after all. Work is still happening to it apparently: https://android-review.googlesource.com/q/RCS+(status:open+OR+status:merged). But it won’t be for third-party developers.
According to this (https://9to5google.com/2019/02/22/android-q-rcs-api-delay/), now there will be no developer-accessible API for RCS messages until Android R at the earliest.
There isn’t a way (short of some vendor-specific API) at the moment, but support for programatically interfacing with RCS is underway if the code commits are any indication of the direction Android is going… https://android-review.googlesource.com/c/platform/frameworks/base/+/849669
The relevant classes are still being implemented, but it looks like you’ll be relying on these (tentatively):
RcsParticipant
RcsThread
Rcs1To1Thread (extends RcsThread)
RcsGroupThread (extends RcsThread)
RcsMessage
RcsIncomingMessage (extends RcsMessage)
RcsOutgoingMessage (extends RcsMessage)
RcsPart
RcsFileTransferPart (extends RcsPart)
RcsLocationPart (extends RcsPart)
RcsMultiMediaPart (extends RcsPart)
RcsTextPart (extends RcsPart)
This code is telling:
class RcsThreadQueryHelper {
static final String ASCENDING = "ASCENDING";
static final String DESCENDING = "DESCENDING";
static final String THREAD_ID = "_id";
static final Uri THREADS_URI = Uri.parse("content://rcs/thread");
static final Uri PARTICIPANTS_URI = Uri.parse("content://rcs/participant");
static final String[] THREAD_PROJECTION = new String[]{THREAD_ID};
static String buildWhereClause(RcsThreadQueryParameters queryParameters) {
// TODO - implement
return null;
}
}
Currently I am trying to modify an incoming SMS before it is saved to the Inbox.
As the system is Android 4.4.4, a simple interception with a high priority broadcast receiver is not possible. That is also the reason why I'm modifying the Android Source (AOSP) and not building an App.
So far I have managed to identify a promising class: InboundSmsHandler. Within the inner class SmsBroadcastReceiver the method onReceive is triggered when a SMS has arrived and later on sends an "SMS_RECEIVED" intend. So basically this method seems to be at a good spot.
The problem is that I can not modify the SMS that is delivered with the intend of onReceive.
I have already tried to modify it with PDU:
byte[] pdu = createFakePDU("15555215556", "modified body");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");
(This approach did not work, the SMS App has shown the original message)
Tried to modify the body of a SmsMessage directly:
(I have added a method to SmsMessage to be able to modify the body)
SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
int pduCount = msgs.length;
for(int i=0; i<pduCount; i++)
{
msgs[i].modifyBody("test");
}
(This approach did not work, the SMS App has shown the original message)
And finally added a new SMS to the database:
....
contentResolver.insert( Uri.parse( SMS_URI ), values );
....
(The problem with that approach is that the original SMS still arrives and therefore not only one modified SMS but one original SMS and one modified arrive. The original SMS must be deleted, but I don't know how.)
Does anyone know how I can modify a SMS before it arrives at the Inbox?
Best regards
mint
AFAIK, on 4.4.4 there is nothing that can prevent your app to receive SMS by registering your BroadcastReceiver, setting the right permissions and the right intent filter. That is:
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
and
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
(if I correctly remember them)
Then inside your BroadcastReceiver you call abortBroadcast(), modify the SMS as needed, and finally store it manually with
getContentResolver().insert(Uri.parse("content://sms/sent"), values);
Thanks for all the answers, I have found a spot in InboundSmsHandler where it is possible to modify the PDU before the broadcast is sent: the method proccessMessagePart. Before the command "intent.putExtra("pdus", pdus);" is executed, the pdus array and therefore the message body can be modified.
I'm developing an app that needs to send some sms and at the same time, make a phone call. The principal problem is if I put the code with normal intents that works but make that phone call and it finish intermediately because the phone starts to send the sms.
My question is:
How can I do the two things at the same time? I've just thought about sending the sms in background but I don't know how to.
Java always make the phone call first, also if the code is not in that order.
I resolved this using two services. The first one make the call and the second send the messages. My problem was that i'm using the same button in order to start both so did it in that way. Thanks
`Intent callIntent = new Intent(Intent.ACTION_CALL);`
`callIntent.setData(Uri.parse("tel:" + phoneToCall));`
`callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);`
`this.getApplicationContext().startActivity(callIntent);`
`Timer timerSMS = new Timer();`
`TimerTask tSMS = new TimerTask() {`
`#Override`
`public void run() {`
`SmsManager sms = SmsManager.getDefault();`
`for (int i = 0; i = 10)`
`sms.sendTextMessage(phoneToSMS[i], null, "Hello World", null, null);'
`}`
`}`
`};`
`timerSMS.schedule(tSMS, 1);`
It starts after 1 ms. So we can say that it works almost at the same time.
I am making a call from my Android Application and it lists a set of apps that is capable of placing calls and user can select one to place calls. But what I want to know, Is there a way to redirect the call to a specific 3rd party VOIP App (like Cisco Jabber) instead of listing all apps** capable of placing calls. I have tried using
register for ACTION_NEW_OUT_GOING_CALLS using a broadcast receiver to interrupt the outgoing calls but I dont know how to redirect the call following is the code of broadcast receiver.
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.d("Test", ""+phoneNumber);
TelephonyManager telephoneManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class<?> c = telephoneManager.getClass();
Class className = Class.forName(c.getName());
Log.d("Test", c.getSimpleName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
List<ResolveInfo> callAppList = context.getPackageManager().queryIntentActivities(intent, 0);
Log.d("Test", ""+callAppList.size());
if(callAppList.size() > 0)
Log.d("Test", callAppList.get(0).activityInfo.targetActivity);
}
I can think of a couple of solutions.
Does the 3rd party provide APIs ? You could integrate with that (like the skype API)
If the 3rd party software has an activity that can accept your call, then you can forward the control to that activity by providing an appropriate intent.
I'm not aware that the telephony manager can capture data about VOIP calls. I believe its responsibility is specific to calls on the phone itself. I've not worked with the telephony manager before, so I would not know.
I am working on a simple app for the HTC EVO that blinks the alternate notification LED when a new text message is received. I have this part working great via a Broadcast Receiver but I need some way to turn the LED off when the user has read the message(s) using their default SMS app. I'm not sure if it is best to do this in the receiver or in a background service. I found this, which might be what I am looking for, but I have no idea on how to use it as I could not find any instructions or tutorials.
Alright, I have worked out the following code which I think will meet my needs.
private int getUnreadSMSCount()
{
int count = 0;
Uri smsURI = Uri.parse("content://sms");
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(smsURI, null, "read=0", null, null);
if (cursor != null)
{
try
{
count = cursor.getCount();
}
finally
{
cursor.close();
}
}
return count;
}
Unfortunately I do not believe there is a way to do this.
When your BroadcastReceiver receives the Intent it is a copy of the Intent, same with the default SMS app. So you each have copies of the message independent of eachother.
You can set your own copy of the message to read, but you will be unable to see its status in the default SMS app. Also, the default app does not send out a broadcast that the message has been read, all that data is kept locally.
The only way you would be able to implement this would be to write a full replacement of the Messaging app.
Sorry, I hope this helps, let me know if you have any other questions.