I've created a simple BroadcastReceiver which react on SMS received.
One message should be able to start an alarm and another one to stop it. The alarm is triggered with a mediaPlayer and works well. But I can't stop it. I know that a new instance of mediaplayer is created each time the right SMS is received but even with a singleton, I can't make it work...
Here is a code snippet :
Bundle myBundle = intent.getExtras();
SmsMessage [] messages = null;
String strMessage = "";
if (myBundle != null)
{
Object [] pdus = (Object[]) myBundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
strMessage += messages[i].getMessageBody();
}
if (strMessage.equals("ATELIO&SON")){
if(onoff == 1){
Toast.makeText(context, "Démarrage localisation sonore", Toast.LENGTH_LONG).show();
playSound();
}
}
else if(strMessage.equals("ATELIO&SON&FIN")){
Toast.makeText(context, "Fin localisation sonore", Toast.LENGTH_LONG).show();
stopSound();
}
}
playsound() and stopsound() are two really simple method, the first one starting the sound and the second one checking if mediaplayer is null and acting accordingly.
Related
I am working on an android project, that deals with device authentication via sms.
The problem I am facing is, when the authentication key is being sent, the receiving device gets a garbled text and not the original sent content.
I am using two instances of the emulator to test the code.
Here is the relevant code :
String MyPublic = "__key("+N.toString()+")yek__";
ArrayList<String> parts = smsmgr.divideMessage(MyPublic);
smsmgr.sendMultipartTextMessage(senderNumber, null, parts, null, null);
How ever when I am sending a single sms within 160 characters, then this problem isn't disappears.
Here is the code I am using to listen for incoming messages.
public void onReceive(final Context context, Intent intent) {
msgReceived = false;
Object[] pdus=(Object[])intent.getExtras().get("pdus");
Bundle bundle = intent.getExtras();
if (bundle != null) {
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]);
}
SmsMessage sms = messages[0];
String body;
if (messages.length == 1 || sms.isReplace()) {
body = sms.getDisplayMessageBody();
} else {
StringBuilder bodyText = new StringBuilder();
for (int i = 0; i < messages.length; i++) {
bodyText.append(messages[i].getMessageBody());
}
body = bodyText.toString();
}
}
The message that is received when the 'Multi-part' thing is used is of this type :
The "HelloWorld" was sent as a single-part message(Non-Multipart) and the 3rd and second from below are parts of that multipart authentication key.
Need Help resolving this.
Regards
Priyabrata.
Well, I have a class extending broadcastreceiver which is listening for messages. Now whenever it receives a message I creates a new instance of my app. So when I am closing it I have to tap back button 2 times.
public class SMSReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle myBundle = intent.getExtras();
SmsMessage [] messages = null;
String strMessage = "";
String phoneNumber = "";
if (myBundle != null) {
Object [] pdus = (Object[]) myBundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
strMessage += "SMS From: " + messages[i].getOriginatingAddress();
strMessage += " : ";
strMessage += messages[i].getMessageBody();
strMessage += "\n";
phoneNumber = messages[i].getDisplayOriginatingAddress();
}
if (phoneNumber.equals("T-Mobile")) {
Toast.makeText(context, strMessage, Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
}
}
First of all, I don't really think it is creating a new instance of your app. What is more likely happening is that an activity is being brought to the front. I think you should look at the manifest or post it so we can see how the broadcasts are being directed. It could be that the target of the broadcast also has the effect of starting the activity. So check the manifest, there is nothing in the broadcast receiver that will cause this. Having said that its really up to the Android OS what gets shown when. But as far as two instances. Thats just not happening.
PS. I don't know the exact reason but I would say probably don't issue Toast from a broadcast reeiver, instead communicate to an activity using startActivity().
I'm having trouble receiving multiPartTextMessages.
My application divides and then sends messages part by part.
However, whenever a part is coming broadcastreceiver works.
I need to combine this part to get the original message.
How can I do it?
put a special text at the start of every part like #myTag_msg1_part1. In broadcast receiver check the special text of every message to know the partno, then accordingly you can join them.
This should help
#Override
public void onReceive(Context context, Intent intent) {
Log.d(ClassName, "received SMS");
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
// here is what I need, just combine them all :-)
final SmsMessage[] messages = new SmsMessage[pdus.length];
Log.d(ClassName, String.format("message count = %s", messages.length));
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
}
}// onReceive()
I can catch newly incoming SMS messages. But if that is a multipart message, my broadcast receiver receives all parts of the message at several times.
Is there a way to receive the whole message at one time - like default messaging app does?
Holy...!
After reading the Android source (this file), I realize that this is such a stupid question...
Here is my receiver:
#Override
public void onReceive(Context context, Intent intent) {
Log.d(ClassName, "received SMS");
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
// here is what I need, just combine them all :-)
final SmsMessage[] messages = new SmsMessage[pdus.length];
Log.d(ClassName, String.format("message count = %s", messages.length));
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
}
}// onReceive()
Oops... I was too lazy to look at my code. I already got all parts of the message at a time.
I have an application, which has to listen for specific SMS. So far easy.
But when I receive the message, it's multipart. Is there a proper way to receive the SMS as one message?
Now my activity starts two times, for each part of the sms. Should I concatenate the SMS by hand?
It may be useful to look at how gTalkSMS handles incoming SMS'es, as it appears to handle multipart messages correctly.
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[]) bundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++)
{
messages[i] =
SmsMessage.createFromPdu((byte[]) pdus[i]);
}
SmsMessage sms = messages[0];
try {
if (messages.length == 1 || sms.isReplace()) {
body = sms.getDisplayMessageBody();
} else {
StringBuilder bodyText = new StringBuilder();
for (int i = 0; i < messages.length; i++) {
bodyText.append(messages[i].getMessageBody());
}
body = bodyText.toString();
}
} catch (Exception e) {
}
Shorter solution:
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle bundle = intent.getExtras(); //---get the SMS message passed in---
SmsMessage[] msgs = null;
if (bundle != null) {
//---retrieve the SMS message received---
try {
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
String msgBody = "";
String msg_from = "";
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
msg_from = msgs[i].getOriginatingAddress();
msgBody += msgs[i].getMessageBody();
}
} catch (Exception e) {
// Log.d("Exception caught",e.getMessage());
}
}
}
Yes you should concatenate the SMS by hand, but obviously you don't want to be starting up a new activity for each message segment.
I suggest setting your Activity's launchMode attribute to singleTask or singleInstance so that that doesn't happen.
Alternatively have your SMS's received by a Service, which will fire up a new Activity only once it has a complete message.
I am not aware of a way to recive a multipart message as once. But if you have the right intent-filter setup you get only one Intent for more than one SMS. In fact, the Intent can contain SMS from different senders and/or zero or more multipart SMS .
You could try this approach:
Add an SmsReceiver Class with intent-filter android.provider.Telephony.SMS_RECEIVED in the Manifest.
The classes onReceive Method will get an intent with a bundle of pdus. These pdu's can origin from different senders each and/or there can be more pdus from the same sender in case of a multipart text message, which you have to concatenate.