My app sends SMS via SmsManager.sendMultipartTextMessage and then notifies the server about the status of SMS sending.
Everything works fine, but there is a problem with Yota operator. SMS is not delivered to phones with MTS operator. Employees of the Yota operator claim that MTS operator blocks receiving messages from Yota.
This is not our problem, but the Android system says that such SMS successfully delivered. We cannot redeliver such SMS from another phone because our system thinks that they have already been successfully delivered.
If app tries to send such SMS, the system first signals about successful SMS sending and then about successful SMS delivery. Sounds good, but in fact the SMS is not delivered. This is not an isolated case. Tested on different devices. Also tried to send SMS to different phones with MTS operator.
I tried to send the same SMS through a standard "Messages" application and noticed the following:
SMS, sent from my application, are displayed differently in a standard "Messages" application on different devices. For example, ZTE BLADE L110 (API 22) shows an error sending a message and Xiaomi Redmi 3S (API 23) does not. But on both smartphones when I try to send such SMS via the standard application is shown error sending message (ZTE before this shows Toast "SMS successfully sent").
Who can help? Can there be another way to check if the SMS is delivered or not? How does the standard "Messages" application register the fact of SMS sending error while the system generates intents with signals that the message was successfully sent and delivered?
Here is my code:
Sending SMS job:
public class SendSMSJob extends SimpleJobService {
public static final String EXTRA_SMS_LIST_JSON = "sms_list";
public static final String TAG = "send_sms_job";
private static final String ACTION_SENT = "ru.sp2all.smsgate.SMS_SENT";
private static final String ACTION_DELIVERED = "ru.sp2all.smsgate.SMS_DELIVERED";
private int startId;
#Override
public void onCreate() {
super.onCreate();
MyLog.i(getLogTag(), "onCreate()");
}
#Override
public int onRunJob(JobParameters parameters) {
try {
this.startId = startId;
String json = parameters.getExtras().getString(EXTRA_SMS_LIST_JSON);
Gson gson = new Gson();
SMSDataList smsDataList = gson.fromJson(json, SMSDataList.class);
MyLog.d(getLogTag(), "Sending " + String.valueOf(smsDataList.items.length) + " messages");
boolean complete = true;
boolean needRetry = true;
for (SMSData sms: smsDataList.items) {
Integer subscriptionId = SimsHelper.getSimSubscriptionIdForIndex(getApplicationContext(), sms.simIndex);
SmsManager smsManager = null;
if (subscriptionId != null) {
smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
} else {
smsManager = SmsManager.getDefault();
}
ArrayList<String> parts = smsManager.divideMessage(sms.message);
MyLog.i(getLogTag(), "parts.size=" + parts.size());
insertSmsToDB(sms, parts);
ArrayList<PendingIntent> deliveryIntents = new ArrayList<>(parts.size());
ArrayList<PendingIntent> sentIntents = new ArrayList<>(parts.size());
try {
for (int part = 0; part < parts.size(); part++) {
Intent sentIntent = new Intent(ACTION_SENT);
sentIntent.putExtra("id", sms.smsId + "_" + Integer.toString(part));
sentIntent.putExtra("sms_id", sms.smsId);
sentIntent.putExtra("parts", Integer.toString(parts.size()));
sentIntent.putExtra("part", Integer.toString(part));
sentIntent.putExtra("phone", sms.phone);
sentIntent.putExtra("msg", sms.message);
PendingIntent sentPI = PendingIntent.getBroadcast(this,
Integer.parseInt(sms.smsId) * 100 + part,
sentIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
sentIntents.add(sentPI);
Intent deliveredIntent = new Intent(ACTION_DELIVERED);
deliveredIntent.putExtra("id", sms.smsId + "_" + Integer.toString(part));
deliveredIntent.putExtra("sms_id", sms.smsId);
deliveredIntent.putExtra("parts", Integer.toString(parts.size()));
deliveredIntent.putExtra("part", Integer.toString(part));
deliveredIntent.putExtra("phone", sms.phone);
deliveredIntent.putExtra("msg", sms.message);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this,
Integer.parseInt(sms.smsId) * 100 + part,
deliveredIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
deliveryIntents.add(deliveredPI);
}
MyLog.i(getLogTag(), "Sending to " + sms.phone);
smsManager.sendMultipartTextMessage(sms.phone, null, parts,
sentIntents, deliveryIntents);
} catch (Exception e) {
ErrorReporter.exception(this, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
complete = true;
}
}
if (complete) {
return RESULT_SUCCESS;
} else if (needRetry) {
return RESULT_FAIL_RETRY;
} else {
return RESULT_FAIL_NORETRY;
}
} catch (Exception e) {
ErrorReporter.exception(this, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
return RESULT_FAIL_RETRY;
}
}
private String getLogTag() {
return getClass().getSimpleName();
}
}
Registered in AndroidManifest Broadcast receivers for SMS status handling:
<receiver android:name=".SMSSentReceiver">
<intent-filter>
<action android:name="ru.sp2all.smsgate.SMS_SENT" />
</intent-filter>
</receiver>
<receiver android:name=".SMSDeliveredReceiver">
<intent-filter>
<action android:name="ru.sp2all.smsgate.SMS_DELIVERED" />
</intent-filter>
</receiver>
SMS sent BroadcastReceiver:
public class SMSSentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String sms_id = intent.getStringExtra("sms_id");
int part = Integer.parseInt(intent.getStringExtra("part"));
MyLog.d(getLogTag(), "br_sent " + sms_id);
int status = 0;
int code = getResultCode();
switch (code) {
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
status = 400;
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
status = 401;
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
status = 402;
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
status = 403;
break;
case Activity.RESULT_OK:
updateDBWithNewSentPartsCount();
status = 202; // 202 is SMS sent Server status
break;
default:
status = 404; break;
}
if (status == 202) {
int sent = getSentPartsFromDB();
int parts = getAllPartsFromDB();
MyLog.d(getLogTag(), "DB sent:" + sms_id + " - : sent:" + sent + " parts: " + parts);
if (sent >= parts) {
MyLog.d(getLogTag(), "DB sent all parts");
Network.sendSMSStatus(context, sms_id, status);
}
} else {
Network.sendSMSStatus(context, sms_id, status);
}
} catch (Exception e) {
ErrorReporter.exception(context, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
}
}
private String getLogTag() {
return getClass().getSimpleName();
}
}
SMS delivered Broadcast Receiver:
public class SMSDeliveredReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String sms_id = intent.getStringExtra("sms_id");
int part = Integer.parseInt(intent.getStringExtra("part"));
MyLog.d(getLogTag(), "br_delivered " + sms_id);
int resultCode = getResultCode();
switch (resultCode) {
case Activity.RESULT_OK:
updateDBWithNewDeliveredPartsCount();
int delivered = getDeliveredPartsFromDB();
int parts = getAllPartsFromDB();
MyLog.i(getLogTag(), "DB delivered: " + sms_id + ", " + delivered + " parts of " + parts);
if (delivered >= parts) {
MyLog.i(getLogTag(), "DB delivered all parts");
Network.sendSMSStatus(context, sms_id, 200); // 200 is SMS delivered Server status
}
break;
case Activity.RESULT_CANCELED:
MyLog.w(getLogTag(), "DB delivered: CANCELLED " + sms_id);
Network.sendSMSStatus(context, sms_id, 405);
break;
default:
MyLog.w(getLogTag(), "DB delivered: unknown code " + resultCode);
Network.sendSMSStatus(context, sms_id, resultCode);
}
} catch (Exception e) {
ErrorReporter.exception(context, getLogTag(), e, new ErrorReporter.ReporterHandler(e));
}
}
private String getLogTag() {
return getClass().getSimpleName();
}
}
Log from device when I try to send SMS and SMS not delivered actually:
SendSMSJob: onCreate()
SendSMSJob: Sending 1 messages
SendSMSJob: parts.size=1
SendSMSJob: Sending to +7988*******
SMSSentReceiver: br_sent 704402
SMSSentReceiver: DB sent:704402 - : sent:1 parts: 1
SMSSentReceiver: DB sent all parts
Network: sendSMSStatus status: 202
Network: get: https://{SERVER_NAME}/result.php?status=202&smsId=704402
Network: got: {"status":200}
SMSDeliveredReceiver: br_delivered 704402
SMSDeliveredReceiver: DB delivered: 704402, 1 parts of 1
SMSDeliveredReceiver: DB delivered all parts
Network: sendSMSStatus status: 200
Network: get: https://{SERVER_NAME}/result.php?status=200&smsId=704402
Network: got: {"status":200}
Text of SMS for test: gate4
SMS is not an acknowledged protocol. You can't know if it has been delivered from the sending end. The sender can only know when the message is sent. The send is reporting correctly, as the data is being sent, but it is being blocked at the other end.
If you need acknowledged SMS you can reply from the receiver, but this will involve developing you own acknowledging protocol.
I'd just poll a web service from the device. Data is a LOT cheaper than SMS messages anyway.
Good luck.
Related
In my project, I want to send all receiving messages to an email address. I successfully did that when the app is open. but when the app is closed, I can't send themail.
how to detect the message is received when the app is closed.
I used the worker for the email sending.
Also, I want to get the message data to the worker class to send the email.
Worker Class
public class MessageSenderWorker extends Worker {
#NonNull
#Override
public Result doWork() {
try {
new Thread(new Runnable() {
#Override
public void run() {
GMailSender sender = new GMailSender("emailaddredd",
"password");
try {
sender.sendMail("datafrom mesaage", "datafrom mesaage",
"emailaddress", "emailaddress");
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
return Result.SUCCESS;
} catch (Exception e) {
return Result.FAILURE;
}
}
}
My Broadcast Reciever
public class MessageReceiver extends BroadcastReceiver {
private static MessageListener mListener;
#Override
public void onReceive(Context context, Intent intent) {
Bundle data = intent.getExtras();
Object[] pdus = (Object[]) data.get("pdus");
for(int i=0; i<pdus.length; i++){
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String message = "Sender : " + smsMessage.getDisplayOriginatingAddress()
+ "Email From: " + smsMessage.getEmailFrom()
+ "Emal Body: " + smsMessage.getEmailBody()
+ "Display message body: " + smsMessage.getDisplayMessageBody()
+ "Time in millisecond: " + smsMessage.getTimestampMillis()
+ "Message: " + smsMessage.getMessageBody();
mListener.messageReceived(message);
NotificationWorker notificationWorker = new NotificationWorker();
PeriodicWorkRequest.Builder dataCheckBuilder = new PeriodicWorkRequest.Builder(notificationWorker.getClass(), 1, TimeUnit.MINUTES).setConstraints(networkConstraints());
PeriodicWorkRequest dataCheckWork = dataCheckBuilder.build();
WorkManager.getInstance().enqueue(dataCheckWork);
}
}
If user turn screen OFF then you must use AlarmManager only (based on my practise) no more than 1 time in 30 minutes. For example you can use custom Broadcast Reciever and call it by AlarmManager. Custom Broadcast Reciever set new Alarm etc. Also you have to create Boot Broadcast Reciever to start Alarm.
To "wake up" a device, because of Doze Mode and app stand-by, the only reliable (and battery-friendly) is to use a high priority Firebase Cloud Message (FCM).
Your app can then handle this message retrieving the email you sent. An option there is that, when you receive the FCM, you enqueue a worker that will then download the message/email.
Everything else will be impacted by Doze Mode and other battery optimization systems in Android. Also, using an FCM is the most battery friendly solution for these cases.
Workers already run on a background thread - you shouldn't create your own inside them. They're also for synchronous work - meaning by the time you return a result, your work should have been completed. Take out all the "new Thread" code and put the contents of the Thread directly in the Worker. You'll also want to read this: https://developer.android.com/topic/libraries/architecture/workmanager/advanced/threading
sorry for my bad english.
I sending push notification from my codeigniter web to android app, I have 3 devices to test it.
My first device, it works well for me.
And then in my second and third device my android didn't receive any message.
I tried to send notification from my firebase console, then I choose target is user segment with my package name. All of my devices receive the message.
Then I tried to send notification using topic, which is my topic is global. Only my first device receives the message.
Here's my code :
public static final String TOPIC_GLOBAL = "global";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public static final String PUSH_NOTIFICATION = "pushNotification";
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
// txtMessage.setText(message);
}
}
};
private void displayFirebaseRegId() {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
String regId = pref.getString("regId", null);
Log.e(TAG, "Firebase reg id: " + regId);
if (!TextUtils.isEmpty(regId))
{
//Toast.makeText(getApplicationContext(),regId,Toast.LENGTH_LONG).show();
}
// Toast.makeText(getApplicationContext(), regId, Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(),"Firebase Reg Id is not received yet!)",Toast.LENGTH_LONG).show();
}
I am sending SMS through my application using a very common way that is explained in pretty much all tutorials. I use sendMultipartTextMessage with "sent Intents" and "delivery Intents", then a Broadcast receiver listen for the results and print things.
But, everytime I try to send a SMS, even with something like 10 characters, I always get a "Generic failure".
My default SMS app is working perfectly and I can send/receive SMS/MMS without any troubles so it can't be a network issue. I don't want my app to become my new default SMS app, I just want it to be able to send a short SMS sometimes.
I tried a lot of things but everything has failed.
What is that issue and what can I do to get rid of it ?
Utils :
public static void sendSMS(Context context, String destination) {
final String srcPhoneNumber = PreferenceManager.getDefaultSharedPreferences(context).getString(OptionsFragment.SMS_SRC_PHONE_NUMBER, null);
final String message = PreferenceManager.getDefaultSharedPreferences(context).getString(OptionsFragment.SMS_MESSAGE, null);
if (message == null || message.isEmpty() || destination == null || destination.isEmpty()) {
Console.log('e', "tag", "sms sending failure");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("sms");
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra("sms", context.getString(R.string.empty_message));
MyApplication.getInstance().sendBroadcast(broadcastIntent);
return ;
}
final List<String> phoneNumbers = getPhoneNumbers();
removeEmptyElement(phoneNumbers);
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(message);
ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
PendingIntent sentPI = PendingIntent.getBroadcast(MyApplication.getInstance(), 0, new Intent("sms"), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(MyApplication.getInstance(), 0, new Intent("sms"), 0);
for (String part : parts) {
sentIntents.add(sentPI);
deliveryIntents.add(deliveredPI);
}
SmsManager.getDefault().sendMultipartTextMessage(destination, srcPhoneNumber, parts, sentIntents, deliveryIntents);
}
Receiver :
#Override
public void onReceive(Context context, Intent intent) {
String s = intent.getAction();
if (s.equals("sms")) {
String message = intent.getStringExtra("sms");
if (message != null) {
if (message.equals("OK")) {
AlertDialog.Builder builder = new AlertDialog.Builder(HomeFragment.this.getActivity());
builder.setMessage(context.getString(R.string.sms_send_success))
.setCancelable(true)
.setTitle("Success");
builder.create().show();
} else {
Utils.makeErrorDialog(HomeFragment.this.getActivity(), message);
}
}
else {
switch (getResultCode())
{
case Activity.RESULT_OK:
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Utils.makeErrorDialog(HomeFragment.this.getActivity(),context.getString(R.string.send_error) + "Generic failure");
progressDialog.dismiss();
return;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Utils.makeErrorDialog(HomeFragment.this.getActivity(),context.getString(R.string.send_error) + "No service");
progressDialog.dismiss();
return;
case SmsManager.RESULT_ERROR_NULL_PDU:
Utils.makeErrorDialog(HomeFragment.this.getActivity(),context.getString(R.string.send_error) + "Null PDU");
progressDialog.dismiss();
return;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Utils.makeErrorDialog(HomeFragment.this.getActivity(),context.getString(R.string.send_error) + "Radio off");
progressDialog.dismiss();
return;
}
...
The second parameter in the SmsManager#sendMultipartTextMessage() method (as well as the sendTextMessage() and sendDataMessage() methods) is for the number of your service center, not the sender's number. A service center is the part of your network that handles the storage, routing, and delivery of SMS messages, so passing an invalid number would result in the generic failure status you're getting. You simply need to pass null for this.
We're using the SMSManager on Android to send a text message to someone else from the device.
We've had reports of a user not receiving an SMS that we thought was delivered based on the fact that the sentIntent got called with Activity.RESULT_OK - but that seems to happen when the local SMS service simply queues the message for delivery and not necessarily when it is truly sent.
So I thought we should make use of the deliveryIntent.
The problem here is that I always get the sentIntent callback, but never the deliveryIntent one.
Any ideas?
Code is below, thanks.
// The intent action to be unique so that we can have multiple
// concurrent pending intents.
// http://developer.android.com/reference/android/app/PendingIntent.html
String intentAction = TAG + "-" + callbackId; // callbackId is unique
Intent intent = new Intent(intentAction);
intent.putExtra("phoneNumber", phoneNumber);
intent.putExtra("callbackId", callbackId);
intent.putExtra("message", message);
PendingIntent sentPI = PendingIntent.getBroadcast(
cordova.getActivity(), 0, intent, 0);
cordova.getActivity().registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context ctx, Intent intent) {
String sentToPhoneNumber = intent.getStringExtra("phoneNumber");
String callbackId = intent.getStringExtra("callbackId");
String message = intent.getStringExtra("message");
int resultCode = getResultCode();
int status = -1;
String details = "";
logger.log(Level.INFO, TAG + " SENT intent!! to: " +
sentToPhoneNumber + ", resultCode: " + resultCode);
switch (resultCode) {
case Activity.RESULT_OK:
status = 0;
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
details = "No service";
case SmsManager.RESULT_ERROR_NULL_PDU:
details = "Null PDU";
case SmsManager.RESULT_ERROR_RADIO_OFF:
details = "Radio off";
status = 1;
break;
}
JSONObject obj = new JSONObject();
try {
obj.put("status", status);
obj.put("details", details);
obj.put("phone_number", sentToPhoneNumber);
obj.put("message", message);
} catch (JSONException e) {
throw new RuntimeException(e);
}
sendAsyncResultStatus(callbackId, obj);
ctx.unregisterReceiver(this);
}
}, new IntentFilter(intentAction));
// The intent action to be unique so that we can have multiple
// concurrent pending intents.
// http://developer.android.com/reference/android/app/PendingIntent.html
String deliveryIntentAction = TAG + "-Delivery-" + callbackId;
Intent deliveryIntent = new Intent(deliveryIntentAction);
deliveryIntent.putExtra("phoneNumber", phoneNumber);
deliveryIntent.putExtra("callbackId", callbackId);
deliveryIntent.putExtra("message", message);
PendingIntent deliveryPI = PendingIntent.getBroadcast(
cordova.getActivity(), 0, deliveryIntent, 0);
cordova.getActivity().registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context ctx, Intent intent) {
logger.log(Level.INFO, TAG + " DELIVERY intent YOYO!!");
String sentToPhoneNumber = intent.getStringExtra("phoneNumber");
String callbackId = intent.getStringExtra("callbackId");
String message = intent.getStringExtra("message");
String pdu = intent.getStringExtra("pdu");
logger.log(Level.INFO, TAG + " DELIVERY intent!! to: " +
sentToPhoneNumber + ", pdu: " + pdu);
JSONObject obj = new JSONObject();
try {
obj.put("pdu", pdu);
obj.put("phone_number", sentToPhoneNumber);
obj.put("message", message);
} catch (JSONException e) {
throw new RuntimeException(e);
}
sendAsyncResultStatus(callbackId, obj);
ctx.unregisterReceiver(this);
}
}, new IntentFilter(deliveryIntentAction));
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, deliveryPI);
DeliveryIntent is dependent on DeliveryReports provided by some carriers.
Some Carriers do provide DeliveryReports and some don't. There are three categories in terms of carriers support of DliveryReports...
Provider does not provide DeliveryReport at all.
Provider always give a fake DeliveryReport (you will get an OK report even for invalid numbers)
Provider does provide the delivery report.
The Complication doesn't stop here... If your provider (sending provider) does support delivery reports, you will get the delivery reports mostly when you are sending messages to subscribers of the same carrier. But when you send the message outside this carrier you may or may not get the delivery report. In most cases you won't.
This can be caused by a verity of reasons e.g.
Destination provider doesn't support delivery reports
Some of the intermediate SMS gateway(s) do not support delivery reports
DeliveryReports of Destination carrier or some intermediate gateways are not compatible with those of Originating Carriers.
Delivery Reports in such case are not a guaranteed information in my knowledge so far.
I could imagine that delivery intents depend on the reception of Return Receipts. The network provider needs to send these in order to make your program work.
You can do this by opening the "settings menu", browse to "SMS settings" and tick the box "Return receipt".
I'm rather new to Android.
Im trying to send SMS from Android application.
When using the SMS Intent the SMS window opens and the user needs to approve the SMS and send it.
Is there a way to automatically send the SMS without the user confirming it?
Thanks,
Lior
You can use this method to send an sms. If the sms is greater than 160 character then sendMultipartTextMessage is used.
private void sendSms(String phonenumber,String message, boolean isBinary)
{
SmsManager manager = SmsManager.getDefault();
PendingIntent piSend = PendingIntent.getBroadcast(this, 0, new Intent(SMS_SENT), 0);
PendingIntent piDelivered = PendingIntent.getBroadcast(this, 0, new Intent(SMS_DELIVERED), 0);
if(isBinary)
{
byte[] data = new byte[message.length()];
for(int index=0; index<message.length() && index < MAX_SMS_MESSAGE_LENGTH; ++index)
{
data[index] = (byte)message.charAt(index);
}
manager.sendDataMessage(phonenumber, null, (short) SMS_PORT, data,piSend, piDelivered);
}
else
{
int length = message.length();
if(length > MAX_SMS_MESSAGE_LENGTH)
{
ArrayList<String> messagelist = manager.divideMessage(message);
manager.sendMultipartTextMessage(phonenumber, null, messagelist, null, null);
}
else
{
manager.sendTextMessage(phonenumber, null, message, piSend, piDelivered);
}
}
}
Update
piSend and piDelivered are Pending Intent They can trigger a broadcast when the method finish sending an SMS
Here is sample code for broadcast receiver
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = null;
switch (getResultCode()) {
case Activity.RESULT_OK:
message = "Message sent!";
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
message = "Error. Message not sent.";
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
message = "Error: No service.";
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
message = "Error: Null PDU.";
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
message = "Error: Radio off.";
break;
}
AppMsg.makeText(SendMessagesWindow.this, message,
AppMsg.STYLE_CONFIRM).setLayoutGravity(Gravity.BOTTOM)
.show();
}
};
and you can register it using below line in your Activity
registerReceiver(receiver, new IntentFilter(SMS_SENT)); // SMS_SENT is a constant
Also don't forget to unregister broadcast in onDestroy
#Override
protected void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}
If your application has in the AndroidManifest.xml the following permission
<uses-permission android:name="android.permission.SEND_SMS"/>
you can send as many SMS as you want with
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage(...);
and that is all.
Yes, you can send SMS using the SmsManager. Please keep in mind that your application will need the SEND_SMS permission for this to work.
Yes, you can send sms without making user interaction...But it works, when user wants to send sms only to a single number.
try {
SmsManager.getDefault().sendTextMessage(RecipientNumber, null,
"Hello SMS!", null, null);
} catch (Exception e) {
AlertDialog.Builder alertDialogBuilder = new
AlertDialog.Builder(this);
AlertDialog dialog = alertDialogBuilder.create();
dialog.setMessage(e.getMessage());
dialog.show();
}
Also, add manifest permission....
<uses-permission android:name="android.permission.SEND_SMS"/>