Send long SMS messages sequentially with delay - android

I have a situation where I want to send a long message (around 600 characters) to approximately 10 people. The problem message of 600 characters means 4 SMS so the final count comes to 40 messages.
I would usually do something like this for long messages:
String phoneNo = etPhoneNo.getText().toString();
String msg = etMsg.getText().toString();
try {
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> msgArray = smsManager.divideMessage(msg);
smsManager.sendMultipartTextMessage(phoneNo, null, msgArray, 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();
}
The problem is of course if I trigger this 10 times, I will send 40 messages at the same time. I don't want that as there is limitation on sms messages. On KitKat it's 30 messages in 30 minutes.
How can I accomplish to send next message 30-40 seconds after previous message was successfully sent? My goal is to receive some confirmation that message is sent and then start sending another message.

You possibly need a AlarmManager to send message every few second (in case your app is in background). If your app is always in foreground, you can use thread and timertask.
If you want to make sure that sms is sent successfully, you may refer to this post:
Java android, how to know if a sms is successfully sent?

All you need is Threading technique. Make a thread that sleep with given delay.
Aproach
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// put code to execute send SMS here
try {
// and make delay 5 second
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// execute thread
thread.start();

Related

How can i make SmsManager API not show sent message and received message at same time

I am writing an app that sends the user of the app a text message when such user performs a certain action with the app. Now, i am using the SmsManager API to achieve this. Only problem is that sent message and received message is showing at the same time in messages. How do i fix this. Also, i want to change the name of the sender of the message to the app name.
public void sendSMSEntering() {
String phone = "08187016641";
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null, "Welcome to the ICAN 2019 conference" , null, null);
Toast.makeText(getApplicationContext(), "SMS sent.", Toast.LENGTH_LONG).show();
}
public void sendSMSExiting() {
String phone = "08187016641";
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null, "Goodbye. We hope you enjoyed the conference" , null, null);
Toast.makeText(getApplicationContext(), "SMS sent.", Toast.LENGTH_LONG).show();
}
My button from xml onClickListener
sendMeAMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickcount++;
if (clickcount % 2 == 0) {
sendSMSEntering();
} else {
sendSMSExiting();
}
}
});
Screenshot
As can be observed in the image above, the message the app sent and the message received by me are both there. I only want the message received to be displayed in messages. Also you will observe that the sender of the message is my phone number (String phone = "08187016641"). 'phone' is used as both the recipients phone number and the sender of the message. Perhaps smsManager.sendTextMessage(phone, null, "Goodbye. We hope you enjoyed the conference" , null, null); is not good enough to achieved this and needs to be changed to something else. I need suggestions
After so much research I found out that the SMSManager API is whack. There are so many good SMS API's out there that you can integrate with your app. You can then use a GET or POST as appropriate to request SMS messages. These SMS API's give you the option of using a custom Sender name and other powerful options to customize incoming text messages. Some of these SMS API's include Nexmo SMS API, Ozeki SMS API and so many others. The good thing is, they have a comprehensive documentation. Infact, integrating these SMS API's into your app takes just a few lines of code.

Sending 50+ messages causing issues lead to generic failure

I am developing an application in which i need to send 100+ of messages. After going through few threads i came to know there is limitation on sending messages like 100 messages can be send in an hour. To do so i divide my recipient list into chunks and place delay of 5 seconds between each chunk and 3 seconds delay in every message. The delay between chunks increase after every chunk and when it gets to 100 seconds it will reset to 5 seconds. After that it worked OK for 50 messages but when i raise recipient list it causing issues some messages didn't go at first place and shown as error messages in native.
Is there any standard way to achieve this i may need to send 100+ messages , how can i send multiple messages without any failure at once. If i need to place delay what should be the appropriate delay between chunks or messages.
Thanks in advance.
private final int MAX_SMS_IN_ONE_TIME = 10;
private final int DELAY_BETWEEN_CHUNKS = 5000;
public void sendMessage(arguments){
// Send long messages in chunk of 20 messages and put gap of increasing 5 seconds till 50 seconds and then reset.
final Iterator iterator = messageChunks.iterator();
new Thread(new Runnable() {
#Override
public void run(){
int interval =1;
while (iterator.hasNext()) {
for (final Contact contact :
(List<Contact>) iterator.next()) {
sendSMS(body, contact.getmMobileNumbers().get(0));
App.trackEvent("Message", "Sent", "Messages from our sms app");
}
}
try {
Log.i("chunk", "chunk # " + interval + " delay is " + DELAY_BETWEEN_CHUNKS);
Thread.sleep(DELAY_BETWEEN_CHUNKS * interval);
interval++;
if (interval == 10) {
interval = 1;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
public void sendSMS(final String message, final String phoneNo) {
try {
String SENT = "com.ebryx.smscustommessagegeneration"+""+System.currentTimeMillis()+""+((int)this.getmMessageId());
Intent intentMessageASendStatus = new Intent(SENT);
final PendingIntent pi = PendingIntent.getBroadcast(App.getContext(), ((int)this.getmMessageId()),
intentMessageASendStatus, PendingIntent.FLAG_CANCEL_CURRENT);
final ArrayList<PendingIntent> sentPI = new ArrayList<PendingIntent>(){{add(pi);}};
App.getContext().registerReceiver(new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Log.i("tag","sent successfully ");
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Log.i("tag","Generic Failure");
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Log.i("tag","No service failure");
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Log.i("tag","Airplane mode failure");
break;
}
}
}, new IntentFilter(SENT));
final SmsManager smsManager = SmsManager.getDefault();
final ArrayList<String> parts = smsManager.divideMessage(message);
new Timer().schedule(new TimerTask() {
#Override
public void run() {
smsManager.sendMultipartTextMessage(phoneNo, null, parts, sentPI, null);
}}, 3000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
There appears to be no official documentation for SMS send limits, from what I could find and the following site either.
Unfortunately there appears to be no public documentation from
Google’s Android development team on the issue.
This is from May 17, 2017
The only figures on sms limits I've been able to find are from Commonsware's site:
SMS Sending Limitations
Apps running on Android 1.x and 2.x devices are limited to sending 100 SMS messages an hour, before the
user starts getting prompted with each SMS message request to confirm
that they do indeed wish to send it.
Apps running on Android 4.x devices, the limits are now 30 SMS
messages in 30 minutes .../...
There appears to be no way around increasing that limit without rooting the phone. Where you need to change the following settings. The following will allow 1000 SMS to be sent per 180000ms == 30 minutes.
SMS_OUTGOING_CHECK_MAX_COUNT 1000
SMS_OUTGOING_CHECK_INTERVAL_MS 1800000
The usual (frustrating) Android issues with varying performance across devices also applies. One phone may perform at a different level to another.
This company has determined the maximum SMS capacities for some handsets with their product. SMS sending limits with FrontlineSync and Android. They also advise that rooting the phone may be needed to increase limits.
Related resources:
Check android package SMS limit?
is there a limit to the number of numbers to send an SMS?
Android Java: How To Send SMS & Receive SMS & Get SMS Messages dated 30 August, 2017.

How to send mutiple text messages from an android app?

Sorry if this question is already asked or seems stupid but i am stuck . I am writing an android application in which app sends different messages to different people the first one successfully send but there is a problem with the second one it doesn't show me error but it doesn't send the second message here is a portion of my code
public void sendSMSMessenger(){
Log.i("Send SMS", "");
try {
// SmsManager smsManager = SmsManager.getDefault();
SmsManager.getDefault().sendTextMessage(Emergencyphonenumber, null, "There is an emergency with your "+PatientRelationship+" "+Patientname+" please open the link to find the location "+"https://www.google.com/maps/place/"+latitude+","+longitude, null, null);
Toast.makeText(this, "Message Sent (Relative)", Toast.LENGTH_SHORT).show();
SmsManager.getDefault().sendTextMessage(Doctorphonenumber, null, "There is an emergency with your patient named "+Patientname+" please open the link to find the location "+"https://www.google.com/maps/place/"+latitude+","+longitude, null, null);
Toast.makeText(this, "Message Sent (Doctor)", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "Message Sending failed", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Thank you....
You can not send messages simultaneously. In a way its hard for network to process all the messages collectively. Wait a little. Increase the time.

How to prevent Outgoing SMS from getting stored in KitKat?

I am creating an application that will send/receive messages to/from a certain gateway number. I don't want the messages that are sent to this particular number to be stored in the inbox of my device.
The code I am using to send the SMS is:
protected void sendMessage(String strMessage) {
try {
SmsManager smsMan = SmsManager.getDefault();
smsMan.sendTextMessage(gatewayNumber, null, strMessage, null, null);
Toast.makeText(getApplicationContext(),
"SMS was sent successfully!",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"SMS was not sent, please contact developer!",
Toast.LENGTH_LONG).show();
}
}
I have managed to tackle the problem of storing incoming messages by using the abortBroadcast(); function. (I realize this doesn't work above KitKat, and I'm fine with it).
But the messages that are sent from the application are being stored in the inbox too (only on KitKat), and that bothers me. Any solutions?

Losing data with RealTimeSocket

I'm porting a game to use Google Play Game Services with multiplayer support. I'm using RealTimeSocket instead of realtime message because the game already has socket support.
To get the socket I call GamesClient.getRealTimeSocketForParticipant, and then I could get input and output streams as use it as a usual socket.
My problem is that if a device receives data before the call to getRealTimeSocketForParticipant, I will not be able to read this data. For instance:
Device A calls getRealTimeSocketForParticipant.
Device A sends "Hello".
Device B calls getRealTimeSocketForParticipant.
Device B receives nothing.
Device A sends "World".
Device B receives "World".
I have modified one of the example projects (ButtonClicker) and replicated the problem here. I have modified the code to use realtime socket, and modified the startGame method to this:
String mReceivedData = "";
byte mNextByteToSend = 0;
void startGame(boolean multiplayer)
{
mMultiplayer = multiplayer;
updateScoreDisplay();
switchToScreen(R.id.screen_game);
findViewById(R.id.button_click_me).setVisibility(View.VISIBLE);
GamesClient client = getGamesClient();
String myid = mActiveRoom.getParticipantId(client.getCurrentPlayerId());
ArrayList<String> ids = mActiveRoom.getParticipantIds();
String remoteId = null;
for(int i=0; i<ids.size(); i++)
{
String test = ids.get(i);
if( !test.equals(myid) )
{
remoteId = test;
break;
}
}
//One of devices should sleep in 5 seconds before start
if( myid.compareTo(remoteId) > 0 )
{
try
{
//The device that sleeps will loose the first bytes.
Log.d(TAG, "Sleeping in 5 seconds...");
Thread.sleep(5*1000);
}
catch(Exception e)
{
}
}
else
{
Log.d(TAG, "No sleep, getting socket now.");
}
try
{
final RealTimeSocket rts = client.getRealTimeSocketForParticipant(mRoomId, remoteId);
final InputStream inStream = rts.getInputStream();
final OutputStream outStream = rts.getOutputStream();
final TextView textView =((TextView) findViewById(R.id.score0));
//Thread.sleep(5*1000); Having a sleep here instead minimizes the risk to get the problem.
final Handler h = new Handler();
h.postDelayed(new Runnable()
{
#Override
public void run()
{
try
{
int byteToRead = inStream.available();
for(int i=0; i<byteToRead; i++)
{
mReceivedData += " " + inStream.read();
}
if( byteToRead > 0 )
{
Log.d(TAG, "Received data: " + mReceivedData);
textView.setText(mReceivedData);
}
Log.d(TAG, "Sending: " + mNextByteToSend);
outStream.write(mNextByteToSend);
mNextByteToSend++;
h.postDelayed(this, 1000);
}
catch(Exception e)
{
}
}
}, 1000);
}
catch(Exception e)
{
Log.e(TAG, "Some error: " + e.getMessage(), e);
}
}
The code ensures that one of the two devices sleeps 5 seconds before the call to getRealTimeSocketForParticipant. For the device that doesn't sleep the output will be something like:
No sleep, getting socket now.
Sending: 0
Sending: 1
Sending: 2
Sending: 3
Sending: 4
Received data: 0
Sending: 5
Received data: 0 1
Sending: 6
Received data: 0 1 2
That's expected, no data lost. But for the other device I get this:
Sleeping in 5 seconds...
Received data: 4
Sending: 0
Received data: 4 5
Sending: 1
Received data: 4 5 6
Sending: 2
Received data: 4 5 6 7
Sending: 3
The first bytes are lost. Is there anyway to avoid this?
If i'm understanding the API correctly, the messages exchanged through a real time socket are unrealiable, so you can't always have assurance that all players received all messages you sent. I couldn't find info about the network protocol used by RealTimeSocket, but I suspect it's UDP.
If that's really the case, I'm afraid there's little you can do short of implementing some sort of handshake yourself. Choose one device (ex.: the one with the lowest ID) to be the "synchronizer", and have it create a set with every other device. Send a message ("SYN") such as "where are you? x y z" (not literally, of course) every second, until the others respond "I'm here! (y)" ("ACK"). Remove from the set the devices that sent a response, until the set is empty. At this point, send everyone a "game's starting!" and go on.
Note that any of these messages can be lost: if the "ACK" is lost, next time the "SYN" is sent the device should answer again. If the "game's starting" message is lost, tough luck, the device will keep waiting until it receives a different message, at such point it should consider itself free to start (though delayed).
One last note: even if the underlying protocol is TCP, it's still not 100% reliable, no protocol is. See this question for more info, if you don't know this fact already.

Categories

Resources