I want to send message to multiple numbers. I tried to use SMS manager. But it's not working.
I am doing it onPostExecute method of an AsyncTask. But I want to create a service and send messages from that service because user can close the application before messages sending gets complete so it should be working in background.
I have created a arraylist of numbers. Now this I want to send to service and send message to each number.
My attempt:
#Override
public void doPostExecute(JSONArray response) throws JSONException {
ArrayList<String> numbers = new ArrayList<>();
for (int i = 0; i < response.length(); i++) {
JSONObject subObject1 = response.getJSONObject(i);
String status = subObject1.getString("status");
if (status.equals("1")) {
JSONObject invitation = subObject1.getJSONObject("invitation");
String number = invitation.getString("invitee_no");
numbers.add(number);
} else {
}
}
try {
SmsManager sms = SmsManager.getDefault();
PendingIntent sentPI;
String SENT = "SMS_SENT";
sentPI = PendingIntent.getBroadcast(InviteContactsActivity.this, 0,new Intent(SENT), 0);
sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
sms.sendTextMessage("8655864341", null, "Hi,add me to your unique contact list.",sentPI, null);
} catch (Exception e) {
e.printStackTrace();
}
}
I have added permission for send sms in manifest.
<uses-permission android:name="android.permission.SEND_SMS"/>
How can I do this? Can anyone help please? Thank you..
EDIT:
I tried to write service like below:
public class MessageService extends Service {
ArrayList<String> numbers = new ArrayList<>();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
numbers = intent.getStringArrayListExtra("numbers");
for(int i=0;i<numbers.size();i++) {
sendMsg(numbers.get(i));
}
return super.onStartCommand(intent, flags, startId);
}
public void sendMsg(final String num){
String SENT = "SMS_SENT";
final SmsManager sms = SmsManager.getDefault();
final PendingIntent sentPI = PendingIntent.getBroadcast(MessageService.this, 0,new Intent(SENT), 0);
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
sms.sendTextMessage("8655864341", null, "Hi MyApp SMS", sentPI, null);
}
}, 2000);
}
#Override
public IBinder onBind(Intent intent)
{
// numbers = intent.getStringArrayListExtra("numbers");
return null;
}
}
And calling it from an activity:
Intent serviceIntent = new Intent(this,MessageService.class);
serviceIntent.putStringArrayListExtra("numbers",numbers);
startService(serviceIntent);
Added service in manifest:
<uses-permission android:name="android.permission.SEND_SMS" />
<receiver android:name=".SmsSentReceiver"/> <receiver android:name=".SmsDeliveredReceiver"/>
<service android:name=".helper.MessageService"></service>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".Activities.MainActivity" />
But as I do debug and check service is not getting called.
What's going wrong?
EDIT :
Tried this way with broadcast receiver :
public class MessageService extends Service {
ArrayList<String> numbers = new ArrayList<>();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
numbers = intent.getStringArrayListExtra("numbers");
for (String number:numbers) {
sendSMS("8655864341","Hello");
}
// sendMsg(numbers.get(i));
return super.onStartCommand(intent, flags, startId);
}
public void sendMsg(final String num){
String SENT = "SMS_SENT";
final SmsManager sms = SmsManager.getDefault();
final PendingIntent sentPI = PendingIntent.getBroadcast(MessageService.this, 0,new Intent(SENT), 0);
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
sms.sendTextMessage("7303668514", null, "Hi MyApp SMS", sentPI, null);
}
}, 2000);
}
#Override
public IBinder onBind(Intent intent)
{
// numbers = intent.getStringArrayListExtra("numbers");
return null;
}
private void sendSMS (String phoneNumber, String message){
ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>();
PendingIntent sentPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
new Intent(getApplicationContext(), SmsSentReceiver.class), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
new Intent(getApplicationContext(), SmsDeliveredReceiver.class), 0);
try {
SmsManager sms = SmsManager.getDefault();
ArrayList<String> mSMSMessage = sms.divideMessage(message);
for (int i = 0; i < mSMSMessage.size(); i++) {
sentPendingIntents.add(i, sentPI);
deliveredPendingIntents.add(i, deliveredPI);
}
sms.sendMultipartTextMessage(phoneNumber, null, mSMSMessage,
sentPendingIntents, deliveredPendingIntents);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), "SMS sending failed...", Toast.LENGTH_SHORT).show();
}
}
public class SmsDeliveredReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(context, "SMS delivered", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(context, "SMS not delivered", Toast.LENGTH_SHORT).show();
break;
}
}
}
public class SmsSentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(context, "SMS Sent", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(context, "SMS generic failure", Toast.LENGTH_SHORT)
.show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(context, "SMS no service", Toast.LENGTH_SHORT)
.show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(context, "SMS null PDU", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(context, "SMS radio off", Toast.LENGTH_SHORT).show();
break;
}
}
}
Getting this exception:
java.lang.RuntimeException: Unable to instantiate receiver com.example.siddhi.contactsapp.helper.MessageService$SmsSentReceiver: java.lang.InstantiationException: class com.example.siddhi.contactsapp.helper.MessageService$SmsSentReceiver has no zero argument constructor
Not getting message..
You can do something like this :
Use a for loop for your Numbers list and inside that Use a handler to maintain some time gap between each sent message, say 2 seconds and send the message.
OR
You can define a Broadcast Receiver inside your Service which will check for the Message Delivery Report and if Delivered then send another Message.
First Link
Second Link
Hope it Helps :)
Edit :
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ArrayList<String> numberlist=new ArrayList<String>();
for(int i=0;i<numberlist.size();i++) {
sendMsg(numberlist.get(i));
}
return super.onStartCommand(intent, flags, startId);
}
public void sendMsg(final String num){
String SENT = "SMS_SENT";
final SmsManager sms = SmsManager.getDefault();
final PendingIntent sentPI = PendingIntent.getBroadcast(MyService.this, 0,new Intent(SENT), 0);
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
sms.sendTextMessage(num, null, "Hi MyApp SMS", sentPI, null);
}
}, 2000);
}
try to send SMS OnPost Method or run your AsynTask on Main Thread.
follow this link its help you
Related
Here is my service MyServiceSMS.java
Whenever I close my app I only receive a default toast of
broadcastreceiver "Message Recieved By : xxxxxxx"
Rest of the code is not executing below onReceiceve.
I have some task inside onReceiceve method, I want them to be executed even if the user closes the app.
public class MyServiceSMS extends Service {
private IntentFilter mIntentFilter;
private SMSGetter smsGetter;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
smsGetter = new SMSGetter();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsGetter, mIntentFilter);
Toast.makeText(this, "Hello I'm a service", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onDestroy() {
super.onDestroy();
//unregisterReceiver(smsGetter);
}
public class SMSGetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);
JSONObject data = new JSONObject();
try {
data.put("from", smsMessage.getDisplayOriginatingAddress());
data.put("message", smsMessage.getMessageBody());
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
if (sharedPreferences.contains(IP) && sharedPreferences.contains(IP)) {
sendSMsToServer sendTextToServer = new sendSMsToServer();
sendTextToServer.execute(data.toString(), sharedPreferences.getString(IP, ""), sharedPreferences.getString(PORT, ""));
Toast.makeText(context, "Your Ip :" + data.toString(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Your IP is empty .. Scan to get IP Again ..", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
// Toast.makeText(context, smsMessage.getDisplayMessageBody(), Toast.LENGTH_SHORT).show();
}
}
}
}
My Manifest
<service
android:name=".viewmodel.MyServiceSMS"
android:enabled="true"
android:exported="true"></service>
I have java class to programatically send an SMS from an android application. I want to generate a report after sending the meesage for that i need the status of the message activity which are
sending status;
receiving status;
Both the status are displaying properly in the toast , But when i tries to set the setter for these it returns me the default values. May be because the
mContext.registerReceiver(new BroadcastReceiver() ........... is on a different thread , How i can set the setter or can fetch te sending status from this function block?
public class SMSSending
{
private String phoneNo;
private String message;
private Context mContext;
Settings.Global global;
public void setSendingStatus(String sendingStatus) {
this.sendingStatus = sendingStatus;
}
private String sendingStatus;
public void setReceivingStatus(String receivingStatus) {
this.receivingStatus = receivingStatus;
}
private String receivingStatus;
public SMSSending(String phoneNo, Context mContext, String testID)
{
this.phoneNo = phoneNo;
this.mContext = mContext;
message = "This is a test message from " + testID;
}
public String getSendingStatus()
{
return sendingStatus;
}
public String getReceivingStatus()
{
return receivingStatus;
}
public void sendingMessage()
{
try
{
sendingStatus = "Failed to send SMS message";
receivingStatus = "Failed to deliver SMS ";
String SENT = "sent";
String DELIVERED = "delivered";
PendingIntent sentPI = PendingIntent.getBroadcast(mContext, 0, new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(mContext, 0,new Intent(DELIVERED), 0);
//setSendingStatus("Transmission successful");
//Register for SMS send action
mContext.registerReceiver(new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
switch (getResultCode())
{
case Activity.RESULT_OK:
sendingStatus = "Transmission successful";
break;
default:
sendingStatus = "Transmission failure";
break;
}
// Save sendingStatus in Database as test report for sending message.
Toast.makeText(mContext, sendingStatus,Toast.LENGTH_LONG).show();
setSendingStatus(sendingStatus);
}
}, new IntentFilter(SENT));
/* Register for Delivery event */
mContext.registerReceiver(new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
receivingStatus = "SMS Delivered Succesfully";
// Save sendingStatus in Database as test report for receiving message.
// This function will only be executed if message has been successful received
Toast.makeText(mContext, receivingStatus, Toast.LENGTH_LONG).show();
setReceivingStatus(receivingStatus);
}
},new IntentFilter(DELIVERED));
enter code here
//Send SMS
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null, message, sentPI, deliveredPI);
}
catch (Exception ex)
{
sendingStatus = "Failed to send SMS message";
receivingStatus = "Failed to deliver SMS ";
}
}
i got this error thing Leaked Intent Receiver that was originally registered here, but the apps is still up and running even with that error kind of thing, what causes that error ? and does this affects the apps ?
here's what im trying to do :
private void sendSMS(String phoneNumber, String message) {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>();
ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>();
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(
SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0,
new Intent(DELIVERED), 0);
try {
SmsManager sms = SmsManager.getDefault();
ArrayList<String> mSMSMessage = sms.divideMessage(message);
for (int i = 0; i < mSMSMessage.size(); i++) {
sentPendingIntents.add(i, sentPI);
deliveredPendingIntents.add(i, deliveredPI);
}
sms.sendMultipartTextMessage(phoneNumber, null, mSMSMessage,
sentPendingIntents, deliveredPendingIntents);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "SMS sending failed...", Toast.LENGTH_SHORT)
.show();
}
// ---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));
}
tnx in advance..
If you have registered the receiver in the onCreate then unregister it in it's onDestroy method.
If you have registered the receiver in the onResume then unregister it in it's onPause method.
If you have registered the receiver in the onStart then unregister it in it's onStop method.
The problem is likely because the Activity you are calling sendSMS from has exited, but that is the context in which you have registered your receivers as anonymous inner classes. You'll need to pull those receivers out, or retain references to them and unregister them in your onPause().
Since the receiver is being registered inside an activity and not on the manifest, you need to unregister it onPause or onStop
public void onStop() {
super.onStop();
if (myReceiver != null) {
unregisterReceiver(myReceiver);
}
I forgot to mention that you should created the BroadcastReceiver inside an inner class such as
private class myReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Add your code here
}
}
Hope it helps.
These codes below are used to encrypt SMS using PRINCE algorithm and sends the SMS to the receiver. Currently I am facing a problem where public void onClick(View v,String args) gives an error message of "The method onClick(View, String) from the type new View.OnClickListener(){} is never used locally". I have also referred to The method onClick(View) from the type new Thread(){} is never used locally but the solutions given does not help me. Is there any other solution for this problem?
btnSendSMS.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
if (phoneNo.length()>0 && message.length()>0)
{
LongBuffer messageBuf = TooLong.messageToLongBuffer(message);
messageBuf.flip();
long[] messageData = new long[messageBuf.remaining()];
LongBuffer i = messageBuf.get(messageData);
String v1=prince.Encrypt(i, k0, kop, k1, t);
sendSMS(phoneNo, v1);
}
else
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}
//---sends a SMS message to another device---
private void sendSMS(String phoneNumber, String v1)
{
/*
PendingIntent pi = PendingIntent.getActivity(this, 0,
new Intent(this, test.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, pi, null);
*/
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, v1, sentPI, deliveredPI);
}
}
The signature for an onClick() method is onClick(View), not onClick(View,String). The latter declares a new method that is never called and does not override the method in OnClickListener interface.
Remove the String argument from your method, and remove the other stub onClick(View).
public void `onClick(View v,String args)`
This method is never used locally because this method is an method written by you. OnButtonclick your method never get called. On click the onClick(View) method get invoked. Write your code inside onClick(View)
btnSendSMS.setOnClickListener(new View.OnClickListener()
{
// why have you written this method it not called from anywhere remove this
method put code in public void onClick(View v) method
public void onClick(View v,String args)
{
}
#Override
public void onClick(View v) {
String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
if (phoneNo.length()>0 && message.length()>0)
{
LongBuffer messageBuf = TooLong.messageToLongBuffer(message);
messageBuf.flip();
long[] messageData = new long[messageBuf.remaining()];
LongBuffer i = messageBuf.get(messageData);
String v1=prince.Encrypt(i, k0, kop, k1, t);
sendSMS(phoneNo, v1);
}
else
Toast.makeText(getBaseContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}
if you require this method (onClick(View v,String args) )then comment.
I am trying to develop an application that allows you to save a SQLite database of SMS on the phone as they arrive. I am using the broadcast receiver to recover the message then the activity component to insert into the database. But I'd replace activity by service for the application does not bother the user. Does anyone want to help me.Here is my code://
MainActivity.java
public class MainActivity extends BroadcastReceiver {
private final String ACTION_RECEIVE_SMS = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_RECEIVE_SMS)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] message = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
message[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
if (message.length > -1) {
String messageBody = message[0].getMessageBody();
String phoneNumber = message[0].getDisplayOriginatingAddress();
Toast.makeText(context, "Expediteur - numero :" + phoneNumber + " Sms : " + messageBody, Toast.LENGTH_SHORT).show();
Intent SecondeItent = new Intent(context, SmsActivity.class);
SecondeItent.putExtra("phoneNumber", phoneNumber);
SecondeItent.putExtra("messageBody", messageBody);
SecondeItent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(SecondeItent);
}
}
}
}
}
public class SmsActivity extends Activity {
smsdao.open();
smsdao.insertSms(sms);
Sms smsFromBdd = smsdao.getSmsWithNum(sms.getNum());
if (smsFromBdd != null) {
Toast.makeText(this, sms FromBdd.toString(), Toast.LENGTH_LONG).show();
}
smsdao.close();
}
}
Other file: SmsDao.java,MyBaseSQLite.java, Sms.java et AndroidManifest.xml, but there are no problems on these files.
A sample service
public class MainService extends Service {
public MainService() {
// TODO Auto-generated constructor stub
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
// your logic
return super.onStartCommand(intent, flags, startId);
}
}
Invoking service
Intent intent = new Intent(this, MainService.class);
startService(intent);
manifest
<service android:name="packageName.MainService" >
</service>