In Android, sending SMS messages (Short Message Service) is a common feature that allows an app to send text messages to other phone numbers. This functionality can be useful in applications related to communication, authentication (like OTP verification), or notifications.
Android provides a straightforward API to send SMS messages, but there are certain permissions and practices to consider when implementing SMS functionality.
To send SMS messages in Android, you need to declare the appropriate permissions in your AndroidManifest.xml file. There are two main permissions you might need, depending on the specific functionality:
<uses-permission android:name="android.permission.SEND_SMS"/>
This permission allows your app to send SMS messages.
If your app needs to read incoming SMS messages (e.g., for OTP verification), you'll need the following permission:
<uses-permission android:name="android.permission.READ_SMS"/>
This permission is typically requested when interacting with SMS directly, such as reading messages for automatic verification.
SmsManagerThe primary way to send SMS messages programmatically in Android is through the SmsManager class. This class provides methods to send SMS messages both to individual phone numbers and in bulk.
Here’s how you can use SmsManager to send an SMS message.
import android.telephony.SmsManager;
public void sendSMS(String phoneNumber, String message) {
// Get an instance of SmsManager
SmsManager smsManager = SmsManager.getDefault();
// Send the SMS
smsManager.sendTextMessage(phoneNumber, null, message, null, null);
}
sendTextMessage(String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent): This method sends a text message to a specified phone number.
null for standard messages).PendingIntent to be triggered when the message is sent. If null, it won't trigger any action.PendingIntent to be triggered when the message is delivered. If null, it won't trigger any action.In this example, the message is sent without tracking the status of the message (i.e., no PendingIntent is provided).
PendingIntent (Optional)You can also monitor the status of the SMS by passing a PendingIntent for both the sent and delivery statuses. This is useful if you want to handle the SMS sending result (whether it was successful or failed).
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsManager;
public void sendSMSWithStatus(Context context, String phoneNumber, String message) {
// Create PendingIntents for SMS sent and delivery status
Intent sentIntent = new Intent("SMS_SENT");
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0, sentIntent, 0);
Intent deliveryIntent = new Intent("SMS_DELIVERED");
PendingIntent deliveryPI = PendingIntent.getBroadcast(context, 0, deliveryIntent, 0);
// Get the default SmsManager
SmsManager smsManager = SmsManager.getDefault();
// Send the SMS with PendingIntent for sent and delivery status
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveryPI);
}
PendingIntent: This is used to perform some action when the message is sent or delivered.
You can listen for these intents in your BroadcastReceiver to handle the sent and delivery events.
To handle these intents, you need to register a BroadcastReceiver to listen for the SMS sent and delivered events.
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Check if the intent is for SMS sent or delivery status
String action = intent.getAction();
if ("SMS_SENT".equals(action)) {
int resultCode = getResultCode();
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(context, "SMS Sent Successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "SMS Failed to Send", Toast.LENGTH_SHORT).show();
}
} else if ("SMS_DELIVERED".equals(action)) {
int resultCode = getResultCode();
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(context, "SMS Delivered", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "SMS Not Delivered", Toast.LENGTH_SHORT).show();
}
}
}
}
You need to register this receiver in your AndroidManifest.xml:
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="SMS_SENT"/>
<action android:name="SMS_DELIVERED"/>
</intent-filter>
</receiver>
Starting with Android 6.0 (API level 23), Android apps need to request permissions at runtime for certain sensitive operations, such as sending SMS. This means you need to check whether the app has the necessary permissions before attempting to send an SMS.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted, request permission
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.SEND_SMS}, REQUEST_SEND_SMS);
} else {
// Permission already granted, send SMS
sendSMS(phoneNumber, message);
}
You also need to handle the result of the permission request in your onRequestPermissionsResult() method:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_SEND_SMS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, send SMS
sendSMS(phoneNumber, message);
} else {
// Permission denied
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
Another method to send SMS is by using an Intent. However, this method is deprecated in newer Android versions because it involves leaving the app to use a built-in messaging app, and it's not as flexible as SmsManager.
Example:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("smsto:" + phoneNumber)); // Set recipient phone number
intent.putExtra("sms_body", message); // Set message body
startActivity(intent); // Opens the default messaging app
Sending SMS messages in Android is simple and straightforward using the SmsManager class. For basic SMS functionality, you can send messages directly, while using PendingIntent allows you to track the sending and delivery status. Additionally, remember to handle runtime permissions for sending SMS on Android 6.0 and higher devices.
If you want to offer a better user experience, consider using SMS Intent only for opening the default SMS app, and use SmsManager for background SMS sending when you need more control over the process.
Always ensure that the app handles permissions carefully and provide feedback on the SMS sending process for a smooth user experience.
Open this section to load past papers