Android SMS BroadcastReceiver NullPointer - java

I'm trying to develop a basic SMS app, but i'm got a NullPointerException problem.
Well, there is the code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button btnSendSMS;
EditText txtPhoneNo;
EditText txtMessage;
sendSMS sendSMS=new sendSMS();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSendSMS = (Button) findViewById(R.id.btnSendSMS);
txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);
txtMessage = (EditText) findViewById(R.id.txtMessage);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.SEND_SMS},1);
btnSendSMS.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
if (phoneNo.length()>0 && message.length()>0) {
sendSMS.sendSMS(phoneNo, message,getApplicationContext());
}
else
Toast.makeText(getApplicationContext(),
"Please enter both phone number and message.",
Toast.LENGTH_SHORT).show();
}
});
}}
And there is the sendSMS class:
public class sendSMS extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
//---sends an SMS message to another device---
public void sendSMS(String phoneNumber, String message,Context context)
{
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI = PendingIntent.getBroadcast(context, 0,
new Intent(SENT), 0);
PendingIntent deliveredPI = PendingIntent.getBroadcast(context, 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);
}}
And there is the log about the error:
FATAL EXCEPTION: main
Process: com.example.lcssgml.appsmsmms, PID: 5861
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Intent android.content.Context.registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)' on a null object reference
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:586)
at com.example.lcssgml.appsmsmms.sendSMS.sendSMS(sendSMS.java:41)
at com.example.lcssgml.appsmsmms.MainActivity$1.onClick(MainActivity.java:46)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
I can't figure it out the problem. I hope you can help me! Thx

You've made your sendSMS class an Activity subclass, presumably so that the registerReceiver() methods would resolve. You cannot instantiate an Activity with new and have it work correctly. The Context member it keeps will never be properly initialized, which is why you're getting the NullPointerException.
You're already passing a Context into the sendSMS() method, so you can just call registerReceiver() on that.
context.registerReceiver(...);
Furthermore, the sendSMS class should not be an Activity subclass, so you should remove the extends Activity, and the onCreate() override. Also, the sendSMS() method can now be static, so you don't need to create an instance of the class to use it, and can just call the method directly on the class. I would also mention that class names in Java should begin with capital letters.
public class SendSMS {
public static void sendSMS(...) {
...
}
...
}
To call it:
SendSMS.sendSMS(...);
It would be advisable to unregister the Receivers when you're done with them, using Context#unregisterReceiver(). You might find it easier to do this by not using anonymous BroadcastReceiver instances.
I should also point out that the SmsManager#sendTextMessage() method will usually fail silently if you send a message that exceeds the character limit for a single-part message in the alphabet you're using.

Related

How to transfer Geofence transition values from broadcast receiver to my main activity

I'm working on a feature in my app that moves a marker to a certain latlng when the user exits the geofence.
Send the broadcast received data to any activity
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GeofenceBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
// Toast.makeText(context, "Geofence triggered...", Toast.LENGTH_SHORT).show();
NotificationHelper notificationHelper = new NotificationHelper(context);
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.d(TAG, "onReceive: Error receiving geofence event...");
return;
}
List<Geofence> geofenceList = geofencingEvent.getTriggeringGeofences();
for (Geofence geofence: geofenceList) {
Log.d(TAG, "onReceive: " + geofence.getRequestId());
}
// Location location = geofencingEvent.getTriggeringLocation();
int transitionType = geofencingEvent.getGeofenceTransition();
switch (transitionType) {
case Geofence.GEOFENCE_TRANSITION_ENTER:
Toast.makeText(context, "You are near the drop off location.", Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("You are near the drop off location", "", Home.class);
break;
case Geofence.GEOFENCE_TRANSITION_DWELL:
Toast.makeText(context, "Pickup/Drop off Location reached.", Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("Pickup/Drop off Location reached.", "", Home.class);
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
Toast.makeText(context, "Leaving Pickup/Drop off point.", Toast.LENGTH_SHORT).show();
notificationHelper.sendHighPriorityNotification("Leaving Pickup/Drop off point.", "", Home.class);
break;
}
}
}
I tried using intents but failed due to me being a beginner.
Using LocalBroadcastManager, we may transfer data from onReceive to another activity.
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
Intent intent = new Intent("broadCastName"); //new Intent(context, ReceiveText.class);
// Data you need to pass to another activity
intent .putExtra("message", extras.getString(Config.MESSAGE_KEY));
context.sendBroadcast(intent );
}

Broadcast Receiver is called multiple times after registering broadcast receiver

I'm developing android application which is suppose to send SMS. When first SMS is sent, the onReceive method of Broadcast Receiver shows the status of SMS as SMS Sent and SMS Delievered or Generic Failure depending upon the response received. But when again SMS is sent then onReceiver first shows the status of previous sent messsage and then newer message. Means everytime onReceiver is called it shows the status of every previous sent message. The following class is written by extending Worker so activity life cycle methods like onStop and onResume can't be overridden here.
Any help is appreciated. Code is given below.
PendingIntent sentPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
new Intent(SENT), PendingIntent.FLAG_ONE_SHOT);
PendingIntent deliveredPI = PendingIntent.getBroadcast(getApplicationContext(), 0,
new Intent(DELIVERED), PendingIntent.FLAG_ONE_SHOT);
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
status = sms_id + " : SMS Sent";
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
status = sms_id + " : Generic failure ";
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
status = sms_id + " : No service ";
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
status = sms_id + " : Null PDU ";
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
status = sms_id + " : Radio off ";
Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
break;
}
}
};
IntentFilter filter = new IntentFilter(SENT);
getApplicationContext().registerReceiver(broadcastReceiver, filter);
//---when the SMS has been delivered---
BroadcastReceiver broadcastReceiver1 = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
switch (getResultCode()) {
case Activity.RESULT_OK:
receiverStatus = sms_id + " : SMS delivered ";
Toast.makeText(context, receiverStatus, Toast.LENGTH_SHORT).show();
addItem(receiverStatus);
break;
case Activity.RESULT_CANCELED:
receiverStatus = sms_id + " : SMS not delivered ";
Toast.makeText(context, receiverStatus, Toast.LENGTH_SHORT).show();
addItem(receiverStatus);
break;
}
}
};
IntentFilter filter1 = new IntentFilter(DELIVERED);
getApplicationContext().registerReceiver(broadcastReceiver1, filter1);
try {
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
handler.post(() -> Toast.makeText(getApplicationContext(), " Do Work", Toast.LENGTH_SHORT).show());
return Result.success();
} catch (Exception e) {
handler.post(() -> Toast.makeText(getApplicationContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show());
return Result.retry();
}
You are doing plenty of wrong things here. First of all Broadcast Receiver should never be called inside Worker Thread. It always work on UI Thread. So whenever you will create a Work Request Broadcast Receiver is registered and hence will be registered as many times as work request is created. And you are not unregistering it any where.
So it will be executed multiple times.
You should register Broadcast Receiver inside onCreate and unregister it in onStop/onResume. So that they would not be registered twice.
Hope it Helps ;).

How to wait for a sending process

I'm trying to develop an android application that sends GPS coordinates via SMS with given time interval.
So I set up my main activity allowing the user to input a specific time in minutes. Transfer it to a alarmReceiver. Every alarm will request a locationupdate. And onlocationChanged will save it to the database before sending it via sms. I save it to the database before sending so that i will not lost any data if sending fails. I'm sending a message like this :
dbcon = new SQLController(ctx);
dbcon.open();
String SENT = "SMS_SENT";
final Cursor C = dbcon.readData_Location();
if(C.moveToFirst()){
getid = C.getString(0);
getLongitude = C.getString(1);
getLatitude = C.getString(2);
getTime = C.getString(3);
int id = Integer.valueOf(getid);
String phoneNo = "09061265887";
String msg = getLongitude +","+getLatitude+","+getTime;
Intent sendIntent = new Intent(SENT);
sendIntent.putExtra("loc_id", id);
PendingIntent sentPI = PendingIntent.getBroadcast(ctx, 0, sendIntent,0);
MainActivity.sendTextMessage(phoneNo, null, msg, sentPI, null);
}while(C.moveToNext());
The problem here is, it will send all the saved locations from the database continuously.
My plan is if the first sending fails, the sending using do-while loop must be stop.
I need to wait and check the result of sending process before sending another one. Im stock here and i dont know that to do. please help
MainActivity
public class MainActivity extends ActionBarActivity {
EditText et_timeinterval;
Button start,stop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_timeinterval= (EditText) findViewById(R.id.editText1);
start = (Button) findViewById(R.id.button1);
stop = (Button) findViewById(R.id.button2);
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int timeinminute = Integer.valueOf(et_timeinterval.getText().tostring());
Intent intent = new Intent(getBaseContext(),alarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), timeinminute * 60 * 1000, pendingIntent);
Toast.makeText(ctx, "Alarm Started", Toast.LENGTH_SHORT).show();
}
});
}
public static void sendSMS(String phoneNumber,String message) {
SmsManager smsManager = SmsManager.getDefault();
String SENT = "SMS_SENT";
PendingIntent sentPI = PendingIntent.getBroadcast(basecontext, 0, new Intent(SENT), 0);
// ---when the SMS has been sent---
basecontext.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(basecontext, "SMS sent",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(basecontext, "Generic failure",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(basecontext,"No Service",Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(basecontext, "Null PDU",
Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(basecontext, "Radio off",
Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));
// ---when the SMS has been delivered---
smsManager.sendTextMessage(phoneNumber, null, message, sentPI, null);
}
}
alarmReceiver.java
public class alarmReceiver extends BroadcastReceiver implements LocationListener{
private LocationManager locationManager;
private Context ctx;
SQLController dbcon;
String latitude,longitude,time;
#Override
public void onReceive(Context context, Intent arg1) {
// TODO Auto-generated method stub
ctx =context;
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1,1,this);
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Time currentTime = new Time(Time.getCurrentTimezone());
currentTime.setToNow();
String latitude = ""+location.getLatitude();
String longitude = ""+location.getLongitude();
String time = currentTime.format("%k:%M:%S");
//inserting to database
dbcon= new SQLController(ctx);
dbcon.open();
dbcon.insertData(latitude, longitude, time);
//sending
String SENT = "SMS_SENT";
Cursor C = dbcon.readData_Location();
if(C.moveToFirst()){
String getid = C.getString(0);
String getLongitude = C.getString(1);
String getLatitude = C.getString(2);
String getTime = C.getString(3);
int id = Integer.valueOf(getid);
String phoneNo = "09061265887";
String msg = getLongitude +","+getLatitude+","+getTime;
MainActivity.sendSMS(phoneNo,msg);
}while(C.moveToNext());
locationManager.removeUpdates(this);
dbcon.close();
}
I want to do something like this
int result_code; //i want to get the resultcode from getResultCode()
C.moveToFirst();
do{
sendSMS(phonenum,sms);
//check first if sendSMS sending process is done before the next loop
}while(C.moveToNext() && result_code==0)
// result code 0 = send success 1=generic failure etc etc
This is not a simple problem. First, since you will want to wait, you need to do this on a background thread (using AsyncTask or a simple thread). Second, if you want it to continue trying/operating after the user exits the activity, you will need a service.
That said, you already have the code in place to check for the "sent" PendingIntent for the message. You need your thread/service to wait for the broadcast receiver responde from the sent message to get a response.
In your "sendSMS" method, you are registering a broadcast receiver to listen for the status of the SMS send. It will tell you whether the send was successful or not, and then you can either continue sending location updates, try again or whatever.
Like this:
basecontext.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(basecontext, "SMS sent",
Toast.LENGTH_SHORT).show();
// add code here to send next message
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(basecontext, "Generic failure",
Toast.LENGTH_SHORT).show();
// add code here to try again or wait
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(basecontext,"No Service",Toast.LENGTH_SHORT).show();
// add code here to try again or wait
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(basecontext, "Null PDU",
Toast.LENGTH_SHORT).show();
// add code here to try again or wait
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(basecontext, "Radio off",
Toast.LENGTH_SHORT).show();
// add code here to try again or wait
break;
}
}
}, new IntentFilter(SENT + someMessageId));
Your intent filter also needs to identify the message (where I added "someMessageId") if you send more than one SMS before waiting for the receiver to respond.

SMSManager and Pending Intent

I have a question about an SMS app i am creating (learning purposes).
On sending an SMS i would like to have a toast message appear once it has been deleivered (or not)
Problem is once i have hit send i would like to close the activity but still have the toast message (in this case) appear giving me the info.
As i am new to this i am not sure how to go about this. All i have done is wait for the information to come through, set up the message then close the activity.
private void sendSMS() {
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), PendingIntent.FLAG_NO_CREATE);
deliverActivity = new BroadcastReceiver() {
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode()) {
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), "SMS delivered",
Toast.LENGTH_LONG).show();
finishActivity();
break;
case Activity.RESULT_CANCELED:
Toast.makeText(getBaseContext(), "SMS not delivered",
Toast.LENGTH_LONG).show();
finishActivity();
break;
}
}
};
registerReceiver(deliverActivity, new IntentFilter(DELIVERED));
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(toNo, null, toSend.getText().toString(), deliveredPI, null);
ContentValues values = new ContentValues();
values.put("address", toNo);
values.put("body", toSend.getText().toString());
this.getContentResolver().insert(Uri.parse("content://sms/sent"), values);
}
private void finishActivity() {
unregisterReceiver(deliverActivity);
Intent intent = new Intent();
setResult(123, intent);
finish();
}
Im sure this is possible somehow, even to pass it possibly to another activity.
It probably sounds a bit pedantic but it allows me to learn new ways of doing things... so if anyone can point me in the right direction that'd be great.
Thanks!
There are ways to show the toast after an activity is closed, for example see this question:
Android: Show toast after finishing application / activity
See this as well.

Sending out SMS messages from my Android phone in Java, how can I do them one at a time?

Sending out SMS messages from my Android phone in Java, how can I do them one at a time?
I made this application to send out a number of SMS messages from my phone, but how do I change it to send one at a time?
I am trying to make this send a SMS message and wait for the reply code to get back before sending the next one:
import android.telephony.gsm.SmsManager;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.util.Log;
import android.widget.Button;
import java.io.*;
import android.util.LogPrinter;
import java.io.*;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.TextView;
import android.os.*;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import java.io.*;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class JSSMS extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(JSSMS.this, "Starting SMS", Toast.LENGTH_LONG)
.show();
String message = "Hello This Is John, Please save my new number";
String number;
try {
BufferedReader buffreader = new BufferedReader(
new FileReader(Environment
.getExternalStorageDirectory().toString()
+ "/numbers.txt"));
int i = 0;
while ((number = buffreader.readLine()) != null) {
Toast.makeText(JSSMS.this, "Sending text to:" + number,
Toast.LENGTH_SHORT).show();
sendSMS(number, message);
}
buffreader.close();
} catch (java.io.FileNotFoundException e) {
Toast.makeText(JSSMS.this, e.toString(), Toast.LENGTH_SHORT)
.show();
} catch (Exception e) {
Toast.makeText(JSSMS.this, e.toString(), Toast.LENGTH_SHORT)
.show();
}
Toast.makeText(JSSMS.this, "DONE!!", Toast.LENGTH_LONG).show();
}
});
}
// ---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);
}
}
Here's a general hint to set you in the right direction. When you have a queue of items you want to process in some asynchronous manner, one approach is use the callback/event handler/call-it-what-you-will to trigger the processing of the next element in the queue.
set up your queue of messages
have a method, e.g. 'sendNextMessage' which pops the top message off the queue and sends it
now, in your onReceive method, you can call your sendNextMessage to trigger sending the next one in the queue
For this approach to work, you need to ensure you are guaranteed to get some kind callback regardless of success or failure.
Look at the sendSms() method in this class.
When you call sendTextMessage(), you can pass a "sent" and a "delivered" intent. Target these intents back to your own application. You can have a callback so to speak when the SMS is sent or delivered.
If you look at the AndroidManifest.xml file in that same project as the references source file, you can see there are two receivers defined that register for "sms_sent" (and "sms_received") intents. If you look at the method I mentioned, you can see that before calling sendTextMessage() it creates two intents with the action "sms_sent" and "sms_delivered". This is how you get notified when an SMS is done sending.
First thing first there are four to five steps
Step 1 open button click or any trigger u start sms sending
Step 2 create Pending Intent to be broadcasted with the intent object and OFCOURSE WITH MULTIPLE PENDING INTENT... for multiple sms sending capability...
Step 3 the registered broadcast receiver will receive the pending intent
Step 4 based on the result and the received INTENT, I REPEAT THE INTENT object u send the next message ... here is a code for it
i trust it's readable enough... stay awesome
public class SMSDoer extends Activity {
String SENT = "SMS_SENT";
String DELIVERED = "SMS_DELIVERED";
PendingIntent sentPI, deliveredPI;
BroadcastReceiver smsSentReceiver, smsDeliveredReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public void onResume() {
super.onResume();
//---create the BroadcastReceiver when the SMS is sent---
smsSentReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent intent) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), “SMS Gone With the wind”,
//db.query update database for recurrisive message calling
//using intent object for specific message
sendSMS(“db.phoneNumber", "db.msg");
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;
}
}
};
//---create the BroadcastReceiver when the SMS is delivered---
smsDeliveredReceiver = 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;
}
}
};
//---register the two BroadcastReceivers---
registerReceiver(smsDeliveredReceiver, new IntentFilter(DELIVERED));
registerReceiver(smsSentReceiver, new IntentFilter(SENT));
}
#Override
public void onPause() {
super.onPause();
//---unregister the two BroadcastReceivers---
unregisterReceiver(smsSentReceiver);
unregisterReceiver(smsDeliveredReceiver);
}
public void SmsMaker(View v) {
//query database
sendSMS(“db.phoneNumber", "db.msg", db.row);
}
//---sends an SMS message to another device---
private void sendSMS(String phoneNumber, String message, int rowId)
{
//create multiple Pending intent
sentPI = PendingIntent.getBroadcast(this,rowId, new Intent(SENT), 0);
deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, "+29170000017", message, sentPI,deliveredPI);
}
}

Categories

Resources