Sending group SMS android - android

I need to crete an application like group messaging. For that I am using SmsManager class.
MY code look like
static List<String> phone_num = new ArrayList<String>();
static List<String> SMS = new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
readExcelFile(this, "/sdcard/Excel.xls");
View readExcelButton = findViewById(R.id.buttonSend);
readExcelButton.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonSend:
for(int i=0;i<phone_num.size();i++)
{
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone_num.get(i),SMS.get(i), null, null);
}
Toast.makeText(getBaseContext(), "Sendingfinished",Toast.LENGTH_SHORT).show();
break;
default: break;
}
}
My question is, is it a right method for sending group sms. Or should I create pendingIntent with broadcast receiver to monitor the sending process and wait inside the for loop until each message send finished to send next.
Thanks in advance....

Related

Android SMS multi text groups

My project is a checklist of phone numbers in a recyclerView/cardView. The phone numbers/businesses can be added or subtracted by a checkBox to make individual groups. I want to be able to send a group multi-text to the selected individuals.
My problem is that only the first phone number (recipient) in a group receives the message while the rest receive nothing, but the numbers still display in the edit text (the first is the only functioning number).
I have tried a lot of different ways but nothing has worked, I am about to give up.
No one seems to know how to fix this problem. If this problem can be solved please let me know.
I don't want to loop the numbers and text individually, that was a suggested fix.
This is the phone activity:
public class ACPhone extends AppCompatActivity {
private static final String SEPARATOR = ";";
EditText txtPhoneNo;
EditText txtMessage;
TextView txtView;
Button btnsend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_acphone);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);
txtMessage = (EditText) findViewById(R.id.txtMessage);
txtView = (TextView)findViewById(R.id.txtMessageMass);
btnsend = (Button) findViewById(R.id.btnSend);
Intent intent = getIntent();
if (intent != null){
ArrayList<CharSequence> selectedNumbers =
intent.getCharSequenceArrayListExtra(SELECTED_NUMBERS);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < selectedNumbers.size(); i++) {
sb.append(selectedNumbers.get(i));
if (i != selectedNumbers.size() - 1){
sb.append(SEPARATOR);
}
}
txtPhoneNo.setText(sb.toString());
}
btnsend.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
String messageView = txtView.getText().toString();
if (phoneNo.length() > 0 && message.length() > 0) {
sendMessage(phoneNo, message, messageView);
} else {
Toast.makeText(getBaseContext(), "Please enter message",
Toast.LENGTH_SHORT).show();
}
}
});
}
private void sendMessage(String phoneNo,String message, String staticMessage){
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo,null,message + "\n" +
staticMessage,null,null);
Toast.makeText(getApplicationContext(), "Message Sent",
Toast.LENGTH_SHORT).show();
}
catch (Exception e){
Toast.makeText(getApplicationContext(), "Unable to send. Please try again", Toast.LENGTH_SHORT).show();
}
}
}
You could create a list of all the numbers and do a for loop through the list in your onclick or in a method and call it in onclick. That's how I would do it anyway.
Following are the some steps to send one single message to multiple contact when it is checked.
Step 1 : In your MainActivity.class like this,
public class MainActivity extends AppCompatActivity {
ListView listView;
EditText editMessage;
ProgressDialog progressDialog;
Handler progresshandler;
boolean isThreadRunning;
int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contactsView);
editMessage = (EditText) findViewById(R.id.editMessage);
listView.setAdapter(new ContactAdapter(this, contacts));
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Sending Messages.. Please wait!");
progresshandler = new Handler() {
public void handleMessage(Message msg) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Messages Sent",
Toast.LENGTH_LONG).show();
}
};
}
}
Step 2 : Create one class within this MainActivity.class(Put this class below onCreate() method)
class SendMessagesThread extends Thread {
Handler handler;
public SendMessagesThread(Handler handler) {
this.handler = handler;
}
public void run() {
SmsManager smsManager = SmsManager.getDefault();
// Find out which contacts are selected
for (int i = 0; i < listView.getCount(); i++) {
View item = (View) listView.getChildAt(i);
boolean selected = ((CheckBox) item.findViewById(R.id.selected)).isChecked();
if (selected) {
String mobile = ((TextView) item.findViewById(R.id.mobile)).getText().toString();
try {
smsManager.sendTextMessage(mobile, null, editMessage.getText().toString(), null, null);
} catch (Exception ex) {
Log.d("Mobile", "Could not send message to " + mobile);
}
}
}
Message m = handler.obtainMessage();
handler.sendMessage(m);
} // run
} // Thread
Step 3: Create one method(put this method below step - 2)
public void sendMessages(View v) {
if (editMessage.getText().toString().length() > 0) {
SendMessagesThread thread = new SendMessagesThread(progresshandler);
thread.start();
progressDialog.show();
} else {
Toast.makeText(this, "Please enter message!", Toast.LENGTH_LONG)
.show();
}
}
Note : According to my project, I am not using any SQLite database or webservice.Basically, I am fetching all the contact from device contact book and displaying that contact to listview. So, Try to understand and modify.
public class TextActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<CharSequence> selectedNumbers
=getIntent().getCharSequenceArrayListExtra(SELECTED_NUMBERS);;
String phNumbers = "";
for (CharSequence s: selectedNumbers) {
phNumbers += s + ";";
}
// for (int i = 0; i < selectedNumbers.size(); i++) {
// phNumbers += selectedNumbers.get(i);
// if (i != selectedNumbers.size()-1){
// phNumbers += ";";
// }
// }
phNumbers = phNumbers.substring(0, phNumbers.length() - 1);
String message = "";
Intent smsIntent = new Intent(Intent.ACTION_VIEW);
smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("address", phNumbers);
smsIntent.putExtra("sms_body",message);
startActivity(smsIntent);
}
}

How can I check whether response is came within one minute after sending SMS in android?

I am creating an application in which I am sending SMS automatically on button click.When SMS is sent I get a response from server in form of SMS.I read that message and perform task on it. Now problem is that when I receive SMS I want to consider only messages received within one minute after button click. What to do.?
public class IncomingSms extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Global mApplication = ((Global)context.getApplicationContext());
String getPPN=mApplication.getPPN();
String getStatus=mApplication.getvStatus();
String ClientId=mApplication.getvClientId();
String MobileNo=mApplication.getvStrMobile();
String LocationId=mApplication.getVstrLocation();
String IMEI=mApplication.getVstrIMEI();
final Bundle bundle = intent.getExtras();
try {
if (bundle != null)
{
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj .length; i++)
{
SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
String phoneNumber = currentMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber ;
String message = currentMessage .getDisplayMessageBody();
mApplication.setvSenderNumber(senderNum);
mApplication.setvMessageBody(message);
String IsBroadCast=mApplication.getvAuthenticatedUser();
try
{
if(IsBroadCast=="1")
{
context.sendBroadcast(new Intent("Message_Recived"));
}
}
catch(Exception e){}
}
}
} catch (Exception e)
{
}
}
}
This class is called when SMS received and take me to Arming Activity's on receive method.
But I need that..Broadcast receiver only receive message only within 1 minute after sendinf SMS
ArmingActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arming);
registerReceiver(broadcastReceiver, new IntentFilter("Message_Recived"));}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// internet lost alert dialog method call from here...
// if(strPPN.equals())
Global globalVariable = (Global) getApplicationContext();
String vvSenderNumber=globalVariable.getvSenderNumber();
String vvMessageBody=globalVariable.getvMessageBody();
String vvPPN=strPPN;
};
public void sendSms(String PPN, String smsBody) {
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(PPN, null, smsBody, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
if (strActionText.equals("1"))
{
sendSms(strPPN, MsgBody);
}
Here when send SMS start Broadcast receiver to start receiving SMS for 1 minute.
What to do?
you can do this with the Handler
for that start/register receiver and also start the Handler for the one minute
//start your broadcast here.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// write code to stop/unregister receiver.
}
}, 60*1000);
for further display time you can use CountDownTimer class.

Send SMS failed via Android Device

I am writing an app in which i am trying to send SMS to a Recepient, but whenever i do click on Send, getting message:- SMS faild, please try again later!
Either i am using Emulator or Android Device....
Like you can see in below screen shot, here i am trying to send message to Pratik, which is saved in my Phonebook Contacts, but whenever i am trying to message to Pratik not able to send message to Pratik
Please see below screen shot, like you can see, here i am trying to send message to Rahul...
Manifest.xml:
<uses-permission android:name="android.permission.SEND_SMS" />
Please check below code:
private TextView name;
private ListView list;
private Database db;
private Contact contact;
ImageButton buttonSend;
EditText textSMS;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editor);
// bind GUI components
this.name = (TextView) findViewById(R.id.editor_name);
this.list = (ListView) findViewById(R.id.editor_list);
// check if contact id is valid
this.db = new Database(getContentResolver());
int contactId = getIntent().getIntExtra(CONTACT_ID, NO_CONTACT_ID);
this.contact = this.db.getContact(contactId);
if (this.contact == null) {
finish();
}
this.name.setText(this.contact.getName());
// pre-load information about all account types
AuthenticatorDescription[] authTypes = AccountManager.get(this).getAuthenticatorTypes();
for (AuthenticatorDescription authDesc : authTypes) {
this.map.put(authDesc.type, authDesc);
}
// bind list events
this.list.setOnItemClickListener(this);
this.list.setOnCreateContextMenuListener(this);
// create the GUI
updateView();
saveGreeting = (ImageButton) findViewById(R.id.greeting);
saveGreeting.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
customGreeting(v);
}
});
buttonSend = (ImageButton) findViewById(R.id.buttonSend);
textSMS = (EditText) findViewById(R.id.editTextSMS);
buttonSend.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String sms = textSMS.getText().toString();
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(CONTACT_ID, null, sms, null, null);
Toast.makeText(getApplicationContext(), "SMS Sent!",
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"SMS faild, please try again later!",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
}
Do not use recipient name to send message , use mobile number to send message .
Get contact number from contact list and use that contact number instead of name in sendTextMessage function.

How to check user entered own phone number in EditText?

Mobile number will be entered in an edittext by user on registration page in my Android application. How can I check that user entered his/her mobile number not other's ?
I've tried this :
TelephonyManager tMgr =(TelephonyManager)mAppContext.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneNumber = tMgr.getLine1Number();
And compare this variable with edittext's text. But mPhoneNumber returns NULL in my case. Is there any other options? How to solve this ?
Any help would be appreciable.
I have tried this : Check source code :
public class MainActivity extends Activity{
Button submit;
EditText contact;
String phNo;
ProgressDialog progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contact = (EditText)findViewById(R.id.mobileNumber);
submit = (Button) findViewById(R.id.button1);
submit.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
phNo = contact.getText().toString();
new CheckOwnMobileNumber().execute();
Toast.makeText(getApplicationContext(), phNo, Toast.LENGTH_LONG).show();
}
});
}
private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
{
#Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
if(progress.isShowing())
{
progress.dismiss();
// Check SMS Received or not after that open dialog date
/*if(SMSReceiver.str.equals(phNo))
{
Toast.makeText(getApplicationContext(), "Thanks for providing your number.", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Provide your own mobile number please.", Toast.LENGTH_LONG).show();
return;
}*/
}
}
#Override
protected String doInBackground(String... params)
{
// TODO Auto-generated method stub
String msg = phNo;
try
{
sendSMS(phNo, msg);
}
catch(Exception ex)
{
Log.v("Exception :", ""+ex);
}
return null;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
progress.setIndeterminate(true);
progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
super.onPreExecute();
}
}
private void sendSMS(String phoneNumber, String message)
{
//PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
}
}
Receiver to listen SMS received or not ?
public class SMSReceiver extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
Context mContext;
private Intent mIntent;
static String address, str = null;
// Retrieve SMS
public void onReceive(Context context, Intent intent) {
mContext = context;
mIntent = intent;
String action = intent.getAction();
if(action.equals(ACTION_SMS_RECEIVED))
{
SmsMessage[] msgs = getMessagesFromIntent(mIntent);
if (msgs != null)
{
for (int i = 0; i < msgs.length; i++)
{
address = msgs[i].getOriginatingAddress();
str = msgs[i].getMessageBody().toString();
}
}
// ---send a broadcast intent to update the SMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
}
}
public static SmsMessage[] getMessagesFromIntent(Intent intent)
{
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++)
{
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++)
{
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
}
LOGCAT :
03-13 17:31:02.049: E/ActivityManager(161): ANR in com.example.test
03-13 17:31:02.049: E/ActivityManager(161): Reason: Broadcast of Intent { act=android.provider.Telephony.SMS_RECEIVED cmp=com.example.test/.SMSReceiver (has extras) }
03-13 17:31:02.049: E/ActivityManager(161): 54% 3732/com.example.test: 54% user + 0% kernel / faults: 21 minor
03-13 17:31:02.049: E/ActivityManager(161): 40% 3732/com.example.test: 40% user + 0% kernel / faults: 2 minor
03-13 17:31:30.699: I/ActivityManager(161): Killing com.example.test (pid=3732): user's request
03-13 17:31:30.799: I/ActivityManager(161): Process com.example.test (pid 3732) has died.
03-13 17:31:30.799: I/WindowManager(161): WIN DEATH: Window{40992f50 com.example.test/com.example.test.MainActivity paused=false}
03-13 17:31:30.819: E/InputDispatcher(161): channel '40818670 com.example.test/com.example.test.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8
03-13 17:31:30.819: E/InputDispatcher(161): channel '40818670 com.example.test/com.example.test.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
03-13 17:34:59.649: I/ActivityManager(161): Start proc com.example.test for broadcast com.example.test/.SMSReceiver: pid=4037 uid=10098 gids={}
Its not guaranteed that tMgr.getLine1Number(); will always return your SIM card's number. Because it depends on the availability of number in SIM card. Like in my case, my Tre-Sweden SIM card doesn't contain my phone number.
But if you put the SIM card into an old SonyEricsson or Nokia phone, then you would get an option to edit this number (on SIM). Once its done, the android device will recognize the number and will show you.
Besides, if you do get your phone number through the code, then the best way to compare two numbers is:
boolean isSame = PhoneNumberUtils.compare(num1, num2);
Alternatively, you may implement some sort of pin-code verification logic (like Viber, WhatsApp or other application does) in which you ask the user to enter their phone number during registration. Later, that phone number is sent to the server and a pin-code is generated against that number which is sent to the user via SMS. Finally, the user has to enter that pin-code (received in SMS) to complete the registration.
Or
Simply send an SMS from user's device (with a consent) to your server/device and get to know their phone number.
Getting the phone number using getLine1Number() is not secure nor certain.
It is generally accepted because this whole "getting the phone number" is clash of multiple issues such as user's privacy, carrier's branding, and even the vendor's.
Anyway, unlike ios, android's android.provider.Telephony.SMS_RECEIVED makes the whole process very convenient and seemless to the user: You get to capture the sms and read it without any need of the user's intervention.
What is one way of doing it?
On your server, upon receiving the request to verify a phone number, you should generate a secret code, tokenSent, and send it to the app. Now, your server should send this code by sms to the specified phone number. The app by now should have a registered receiver listening for the android.provider.Telephony.SMS_RECEIVED intent. Once received, the app verifies that the tokenSent is identical to what it received from the server. At this point, phone registration is done and the server can be notified.
What could go wrong?
Generally, such apps are usually paid apps and it is not the user's good to attempt anything. Still, the user might enter a wrong number which he right now has. Then upon receiving the sms, he could forward it to the mobile where the app is registering. The app will then receive the tokenSent and wrongly verify the phone number.
How can we tackle this?
The feasibility of the solution depends on whether the sms provider allows your server to know the sender's phone number. This is probably (AFAIK) not gonna happen but if it does then you're in luck. That way, the app can, upon receiving the tokenSent, send it back to the server along with the sender of the sms. The server then can verify that this is the sms that was originated from your service provider.
Any more feasible solution? (If I am really paranoid)
In this case, the best solution, I believe, would be to request a tokenSent from your server. The server saves a generated tokenSent along with the phone number entered and sends this token to the app. The app notifies the user that registration will cost him 1 sms. Once the user accepts, you can easily send an sms in the background containing this tokenSent to a certain service. The server, once receives this tokenSent verifies the user using the token and the sender of the sms. Of course, this may seem a bit harassing and infringing to the user but it is the most secure way especially for such a paranoid (reading this part).
Formalities :P
Add Permissions in Manifest
<uses-permission android:name="android.permission.RECEIVE_SMS">
Register the receiver (Do this just before you send the sms to the phone)
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getExtras() != null)
{
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
String from = msgs[i].getOriginatingAddress();
String body = msgs[i].getMessageBody().toString();
//here is the body
//...
unregisterReceiver(this); //If you are done with verification
}
}
}
}, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
I solved it my self. Here is my working code.
MainActivity Class :
public class MainActivity extends Activity
{
Button submit;
EditText contact;
static String phNo;
ProgressDialog progress;
static Boolean wasMyOwnNumber;
static Boolean workDone;
final static int SMS_ROUNDTRIP_TIMOUT = 30000;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contact = (EditText)findViewById(R.id.mobileNumber);
submit = (Button) findViewById(R.id.button1);
wasMyOwnNumber = false;
workDone = false;
submit.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
phNo = contact.getText().toString();
new CheckOwnMobileNumber().execute();
}
});
}
private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
{
#Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
if(progress.isShowing())
{
progress.dismiss();
if(wasMyOwnNumber)
{
Toast.makeText(getApplicationContext(), "Number matched.", Toast.LENGTH_LONG).show();
wasMyOwnNumber = false;
workDone = false;
}
else
{
Toast.makeText(getApplicationContext(), "Wrong number.", Toast.LENGTH_LONG).show();
wasMyOwnNumber = false;
workDone = false;
return;
}
}
super.onPostExecute(result);
}
#Override
protected String doInBackground(String... params)
{
// TODO Auto-generated method stub
String msg = phNo;
try
{
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phNo, null, msg, null, null);
timeout();
}
catch(Exception ex)
{
Log.v("Exception :", ""+ex);
}
return null;
}
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
progress.setIndeterminate(true);
progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
super.onPreExecute();
}
}
private boolean timeout()
{
int waited = 0;
while (waited < SMS_ROUNDTRIP_TIMOUT)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
waited += 100;
if(phoneNumberConfirmationReceived())
{
waited=SMS_ROUNDTRIP_TIMOUT;
workDone = true;
}
}
/*Log.v("MainActivity:timeout2: Waited: " , ""+waited);
Log.v("MainActivity:timeout2:Comparision: ", ""+ phoneNumberConfirmationReceived());
Log.v("MainActivity:timeout2: WorkDone value after wait complete : ", ""+workDone);*/
return workDone;
}
private boolean phoneNumberConfirmationReceived()
{
if(wasMyOwnNumber)
{
workDone = true;
}
return workDone;
}
}
SMSReceiver Code :
public class SMSReceiver extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
Context mContext;
private Intent mIntent;
static String address, str = null;
boolean isSame;
// Retrieve SMS
public void onReceive(Context context, Intent intent)
{
mContext = context;
mIntent = intent;
String action = intent.getAction();
if(action.equals(ACTION_SMS_RECEIVED))
{
SmsMessage[] msgs = getMessagesFromIntent(mIntent);
if (msgs != null)
{
for (int i = 0; i < msgs.length; i++)
{
address = msgs[i].getOriginatingAddress();
str = msgs[i].getMessageBody().toString();
}
}
Log.v("Originating Address : Sender :", ""+address);
Log.v("Message from sender :", ""+str);
isSame = PhoneNumberUtils.compare(str, MainActivity.phNo);
Log.v("Comparison :", "Yes this true. "+isSame);
if(isSame)
{
MainActivity.wasMyOwnNumber = isSame;
MainActivity.workDone=true;
}
// ---send a broadcast intent to update the SMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
}
}
public static SmsMessage[] getMessagesFromIntent(Intent intent)
{
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++)
{
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++)
{
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
}
No ANR found.
public class MainActivity extends Activity{
Button submit;
EditText contact;
String phNo;
ProgressDialog progress;
Boolean wasMyOwnNumber = false;
Boolean workDone = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contact = (EditText)findViewById(R.id.mobileNumber);
submit = (Button) findViewById(R.id.button1);
submit.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
phNo = contact.getText().toString();
new CheckOwnMobileNumber().execute();
Toast.makeText(getApplicationContext(), phNo, Toast.LENGTH_LONG).show();
}
});
}
private class CheckOwnMobileNumber extends AsyncTask<String, Void, String>
{
#Override
protected void onPostExecute(String result)
{
// TODO Auto-generated method stub
if(progress.isShowing())
{
progress.dismiss();
// Check SMS Received or not after that open dialog date
/*if(SMSReceiver.str.equals(phNo))
{
Toast.makeText(getApplicationContext(), "Thanks for providing your number.", Toast.LENGTH_LONG).show();
wasMyOwnNumber=true;workDone=true;
}
else
{
Toast.makeText(getApplicationContext(), "Provide your own mobile number please.", Toast.LENGTH_LONG).show();
wasMyOwnNumber=false;workDone=true;
return;
}*/
}
}
#Override
protected String doInBackground(String... params)
{
// TODO Auto-generated method stub
String msg = phNo;
try
{
sendSMS(phNo, msg);
int count=0;
while(!workDone)
{count++;}
}
catch(Exception ex)
{
Log.v("Exception :", ""+ex);
}
return null;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progress = ProgressDialog.show(MainActivity.this, "","Checking Mobile Number...");
progress.setIndeterminate(true);
progress.getWindow().setLayout(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
super.onPreExecute();
}
}
private void sendSMS(String phoneNumber, String message)
{
//PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(), MainActivity.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, null, null);
}
public class SMSReceiver extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
Context mContext;
private Intent mIntent;
static String address, str = null;
// Retrieve SMS
public void onReceive(Context context, Intent intent) {
mContext = context;
mIntent = intent;
String action = intent.getAction();
if(action.equals(ACTION_SMS_RECEIVED))
{
SmsMessage[] msgs = getMessagesFromIntent(mIntent);
if (msgs != null)
{
for (int i = 0; i < msgs.length; i++)
{
address = msgs[i].getOriginatingAddress();
str = msgs[i].getMessageBody().toString();
}
}
// ---send a broadcast intent to update the SMS received in the
// activity---
workDone=true;
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
}
}
public static SmsMessage[] getMessagesFromIntent(Intent intent)
{
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++)
{
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++)
{
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
}
}
Just want to add a bit here to above explanations in the above answers. Which will save time for others as well.
In my case this method didn't returned any mobile number, an empty string was returned. It was due to the case that I had ported my number on the new sim. So if I go into the Settings>About Phone>Status>My Phone Number it shows me "Unknown".
This is probably because you have ported the number from one network to other.
If you are not able to check the number from API Then:
One way of doing that is you generate a text message to the Number and send a Random Generated no to the Mobile Number. You will have to ask the user to enter this Random generated number into your Application. Once it is entered in the application then you can send it onto the server to check whether the number passed in the text is correct or not (Which you have already saved on server against that mobile number).
I hope this makes sense.

Which request is my onReceive answering to?

I have an ArrayList of contacts that contains a phone number and a status field. I want to update the status field on a successful send result.
I even tried passing the index of the ArrayList item in to the Pending Intent with contacts.indexOf(c.getPhoneNumber()) as the int requestCode. I just cant' figure out how to tell which message is reporting back as successful and update my contact item.
package com.example.SMS;
public class SendSMSActivity extends SMSActivity {
private EditText smsMessageBody;
private Button send_button;
private SmsManager sms;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sendsmsactivity);
setupViews();
}
private void setupViews() {
smsMessageBody = (EditText) findViewById(R.id.smsText_editText1);
broadcast_button = (Button) findViewById(R.id.sendsms_button);
send_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (smsMessageBody.getText().toString().length() > 0 ) {
if (!getSendSMSApplication().getCurrentContacts().isEmpty()) {
sendSMSLoop();
Toast.makeText(getBaseContext(), R.string.messages_sent, Toast.LENGTH_SHORT).show();
getSendSMSApplication().setCurrentContacts(null); // Clear existing contacts after send
finish();
} else {
Toast.makeText(getBaseContext(), R.string.error_no_numbers, Toast.LENGTH_SHORT).show();
} // there are phone numbers to send to?
} else {
Toast.makeText(getBaseContext(), R.string.error_no_message, Toast.LENGTH_SHORT).show();
} // user entered a message?
}
});
}
protected void sendSMSLoop() {
ArrayList<ContactItem> contacts = getSendSMSApplication().getCurrentContacts();
for (ContactItem c:contacts) {
sendSMS(c.getPhoneNumber().toString(), smsMessageBody.getText().toString(), contacts.indexOf(c.getPhoneNumber()));
}
}
public void sendSMS(String phoneNumber, String message, int messageIndex)
{
String SENT = "SMS_SENT";
PendingIntent sentPI = PendingIntent.getBroadcast(this, messageIndex, new Intent(SENT), 0);
registerReceiver(new BroadcastReceiver(){
#Override
public void onReceive(Context arg0, Intent arg1) {
switch (getResultCode())
{
case Activity.RESULT_OK:
Toast.makeText(getBaseContext(), R.string.sms_sent, Toast.LENGTH_SHORT).show();
break;
}
}
}, new IntentFilter(SENT));
sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
}
}
I am trying to do this myself at the moment. I guess you have got the same problem as me and if you are sending more than 1 message, they are all returning the same sent code for all 3 messages. I think the trick here is to 'thread' each message so that each 'thread' will have a different return code. I can't guarantee this is the solution but it is the path I am next going to go down for solving this issue.
Hope this helps, if you work it out please let me know too.
This is some code taken from my actual code:
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++)
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
if (messages.length > -1) {
//The 2 variables you need (from and body)
messages[0].getOriginatingAddress();
messages[0].getMessageBody();
...
Try passing the received/delivered intent to this function (complete the function to add the functionality you need), I will be trying it in a few weeks time so let me know how it goes if you beat me to it.
Just re-looked over your code...
sms.sendTextMessage(phoneNumber, null, message, sentPI, null);
My code looks more like:
sms.sendTextMessage(phoneNumber, null, message, sentPI, deliveredPI);
You need to add the extra intent to work with the pdus, as far as I am aware.

Categories

Resources