Sending Text Messages Programmatically in Android

Sending SMS programmatically without opening message app

You can send messages from your application through this:

public void sendSMS(String phoneNo, String msg) {
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, msg, null, null);
Toast.makeText(getApplicationContext(), "Message Sent",
Toast.LENGTH_LONG).show();
} catch (Exception ex) {
Toast.makeText(getApplicationContext(),ex.getMessage().toString(),
Toast.LENGTH_LONG).show();
ex.printStackTrace();
}
}

Also, you need to give SEND_SMS permission in AndroidManifest.xml to send a message

<uses-permission android:name="android.permission.SEND_SMS" />

Programmatically send text message on Android

The concept of "outbox" depends on the SMS application. You cannot programatically add SMS's to outboxes of SMS applications on the device (there could be more than one). If you want the SMS to be shown in the users default SMS application then use the intent ACTION_SEND to send the SMS

Code for doing it with an intent

Uri uri = Uri.parse("smsto:xxxxxxx");   
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
it.putExtra("sms_body", "THE SMS BODY");
startActivity(intent);

In short, If you want to send it programatically using SMSManager It would not show in the outbox. Use intents for that.

Sending text messages programmatically in android

You actually need to send the next sms after the previous one is sent, for this you need to check the status of the sms sent, please see this tutorial, it says:

If you need to monitor the status of the SMS message sending process, you can actually use two PendingIntent objects together with two BroadcastReceiver objects, like this:

 //---sends an SMS message to another device---
private void sendSMS(String phoneNumber, String message)
{
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";

PendingIntent sentPI = PendingIntent.getBroadcast(this, 0,
new Intent(SENT), 0);

PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
new Intent(DELIVERED), 0);

//---when the SMS has been sent---
registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));

//---when the SMS has been delivered---
registerReceiver(new BroadcastReceiver(){
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS delivered",
Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(DELIVERED));

SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
}

Android Send SMS programmatically

The code worked for me like this thanks to Mike M -

private void sendSMS(String number, String msg)
{
SmsManager sm = SmsManager.getDefault();
ArrayList<String> parts = sm.divideMessage(msg);

Intent iSent = new Intent(ACTION_SMS_SENT);
PendingIntent piSent = PendingIntent.getBroadcast(this, 0, iSent, 0);
Intent iDel = new Intent(ACTION_SMS_DELIVERED);
PendingIntent piDel = PendingIntent.getBroadcast(this, 0, iDel, 0);

if (parts.size() == 1)
{
msg = parts.get(0);
sm.sendTextMessage(number, null, msg, piSent, piDel);
}
else
{
ArrayList<PendingIntent> sentPis = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> delPis = new ArrayList<PendingIntent>();

int ct = parts.size();
for (int i = 0; i < ct; i++)
{
sentPis.add(i, piSent);
delPis.add(i, piDel);
}

sm.sendMultipartTextMessage(number, null, parts, sentPis, delPis);
stopSelf();
}
}

public class SmsReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();

if (action.equals(ACTION_SMS_SENT))
{
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
else if (action.equals(ACTION_SMS_DELIVERED))
{
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS delivered",
Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered",
Toast.LENGTH_SHORT).show();
break;
}
}
}
}

Programmatically sent SMS not showing in Messages app

First, there are hundreds, if not thousands, of SMS clients. None have to show SMS messages sent by other apps. They can do that, but they do not have to do that.

Second, it is possible that on some devices, the device manufacturer chose to not have SmsManager add its messages to the system-supplied ContentProvider that many (most?) SMS clients use.

IOW, while many times an SmsManager-sent message will appear in an SMS client, do not assume that this will happen 100% of the time.

Sending SMS programmatically to multiple people getting Generic Error

IHMO you are not using the right approach. I'm using a different one and it is working. I try to explain:

You should keep a counter for all pending intents because if the sms you are sending has two parts you will receive two RESULT_OK (or RESULT_ERROR_*) and only when you receive the results for all parts you should proceed sending the next sms. I don't like the idea of blocking the thread... maybe this is the reason you are getting strange errors.

I refactored your code with my approach:

private int mMessageSentParts;
private int mMessageSentTotalParts;
private int mMessageSentCount;

private void startSendMessages(){

registerBroadCastReceivers();

mMessageSentCount = 0;
sendSMS(array[mMessageSentCount].toString(), message);
}

private void sendNextMessage(){
if(thereAreSmsToSend()){
sendSMS(array[mMessageSentCount].toString(), message);
}else{
Toast.makeText(getBaseContext(), "All SMS have been sent",
Toast.LENGTH_SHORT).show();
}
}

private boolean thereAreSmsToSend(){
return mMessageSentCount < array.length;
}

private void sendSMS(final String phoneNumber, String message) {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";

SmsManager sms = SmsManager.getDefault();
ArrayList<String> parts = sms.divideMessage(message);
mMessageSentTotalParts = parts.size();

Log.i("Message Count", "Message Count: " + mMessageSentTotalParts);

ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();

PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);

for (int j = 0; j < mMessageSentTotalParts; j++) {
sentIntents.add(sentPI);
deliveryIntents.add(deliveredPI);
}

mMessageSentParts = 0;
sms.sendMultipartTextMessage(phoneNumber, null, parts, sentIntents, deliveryIntents);
}

private void registerBroadCastReceivers(){

registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:

mMessageSentParts++;
if ( mMessageSentParts == mMessageSentTotalParts ) {
mMessageSentCount++;
sendNextMessage();
}

Toast.makeText(getBaseContext(), "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(getBaseContext(), "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(getBaseContext(), "No service",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(getBaseContext(), "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(getBaseContext(), "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));

registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {

case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS delivered",
Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(DELIVERED));

}


Related Topics



Leave a reply



Submit