I try to get text of Cell Broadcast message just like sms, but it does'not work:
public class SMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null) {
// ---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
str =msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
Do you know any way to get it?
I also spent some time on investigation of this question. And it seems that there is no public API to do that. But I can share some results from my reverse engineering research...
My Samsung Galaxy S is able to receive CB messages, so I decompiled SMS app and looked into the code. It has the following BroadcastReceiver in its manifest file:
<receiver android:name=".transaction.PrivilegedSmsReceiver">
...
<intent-filter>
<action android:name="android.provider.Telephony.CB_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.CB_SETTINGS_AVAILABLE" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.SET_CB_ERR_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.provider.Telephony.GET_CB_ERR_RECEIVED" />
</intent-filter>
</receiver>
Note the android.provider.Telephony.CB_RECEIVED intent-filter. I did not find any documentation about it, but from its name I assumed that it's the only broadcast that I need to catch for now.
Then I searched through the code of decompiled apk and found that it uses android.provider.Telephony.Sms.Intents->getCbMessagesFromIntent() interface to access retrieve CB messages, which returns CbMessage class instance. This interface is outdated even for simple SMS messages, so I assumed that CbMessage should work with pdus as SmsMessage does. Finally I found the source of SmsCbMessage class which is pretty similar to SmsMessage by API. It depends on 5-6 internal Android java files, so for simplicity I just grab them from the same site and included them into my project.
The broadcastReceiver is the same as yours except the class SmsMessage is replaced by SmsCbMessage:
public class CbReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//---get the CB message passed in---
Bundle bundle = intent.getExtras();
SmsCbMessage[] msgs = null;
String str = "";
if (bundle != null) {
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsCbMessage[pdus.length];
for (int i=0; i<msgs.length; i++) {
msgs[i] = SmsCbMessage.createFromPdu((byte[])pdus[i]);
str += "CB lang " + msgs[i].getLanguageCode();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
}
//---display the new CB message---
abortBroadcast();
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
After installing my application into my SGS phone with the receiver above, and enabling receiving CB messages in phone SMS application, my app was able to show CB messages in toast in parallel with receiving them by standard SMS application.
The issues are still needed to be resolved:
How to enable/disable/configure_channels of CB messages in my
application? SMS app uses getCbSettings()/setCbSettings() functions,
but I did not find them. So temporarily I used other app for that.
How to
abort CB message broadcast, so other apps do not receive them? It
seems abortBroadcast() does not work here, because the broadcast
message is not ordered (isOrderedBroadcast() returns false).
Related
I've found a few tutorials on how to send/receive text SMS messages, but none on how to send/receive data SMS messages. I have a very small amount of data I would like the users of my app to be able to share.
I am able to send, but my BroadcastReceiver doesn't ever get called. It seems this is a known issue (http://code.google.com/p/android/issues/detail?id=1576) but has anyone figured out how to do this yet?
I tried sending/receiving a text SMS and that works fine, the thing is, I need to specify a port so only my app can listen for the SMS.
It seems this question has been asked here before and was never answered: how to receive text sms to specific port..
I know this is 1 year old at time of my response, but I thought it could still help someone.
Receiving:
Bundle bundle = intent.getExtras();
String recMsgString = "";
String fromAddress = "";
SmsMessage recMsg = null;
byte[] data = null;
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
for (int i=0; i<pdus.length; i++){
recMsg = SmsMessage.createFromPdu((byte[])pdus[i]);
try {
data = recMsg.getUserData();
} catch (Exception e){
}
if (data!=null){
for(int index=0; index<data.length; ++index)
{
recMsgString += Character.toString((char)data[index]);
}
}
fromAddress = recMsg.getOriginatingAddress();
}
Setting up Receiver in Manifest:
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.intent.action.DATA_SMS_RECEIVED" />
<data android:scheme="sms" />
<data android:port="8901" />
</intent-filter>
</receiver>
Sending:
String messageText = "message!";
short SMS_PORT = 8901; //you can use a different port if you'd like. I believe it just has to be an int value.
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendDataMessage("8675309", null, SMS_PORT, messageText.getBytes(), null, null);
My application uses some web services for performing actions in server and getting results from it. Now I want my app to work in offline mode. I have a sms panel that can handle sending and receiving messages to clients. So the thing I need is to listen to messages in client and respond to it if it has a special format. I know how to listen to incoming sms from code, here it is:
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// ---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
Log.d("checking", "sms received!");
String str = "";
if (bundle != null) {
// ---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
String sender = null;
String body = null;
for (int i = 0; i < msgs.length; i++) {
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
sender = msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
body = msgs[i].getMessageBody().toString();
str += "\n";
}
// ---display the new SMS message---
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
and it works properly. The thing here is I don't want my special messages appear in user inbox or even hide sms notification from him. Is this possible? Should I listen to all incoming messages?
update:
I assume that things are different in KitKat so any solution works in api 19 appreciated.
thanks in advanced.
Try abortBroadcast(); in your BroadcastReceiver
if (intent.getAction().equals(android.provider.Telephony.SMS_RECEIVED)) {
abortBroadcast();
}
i don't know if this works on KitKat or not.
I want my program to be able to receive sms from a special number("+9856874236"). But, if the SMS is from any other number, it should go to the phone's message inbox and not to my application.
please help me my dears
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
public class receiver extends BroadcastReceiver {
public String str = "";
#Override
public void onReceive(Context context, Intent intent) {
// ---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++)
{
msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
//for get sms from special number===============================
String msg_from = msgs[i].getOriginatingAddress();
Log.v("msg_from >>",msg_from);
if(msg_from.equals("+9830007546"))
{
//===============================
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
Intent act = new Intent(context, ReceiveSMS.class);
act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
act.putExtra("message", str);
context.startActivity(act);
this.abortBroadcast();
}
}
// ---display the new SMS message---
// Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
}
}
}
main class :
private TextView showSms;
private String ReceivedSms;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//this.setContentView(R.layout.receivesms);
/*Removing system bar from screen*/
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.receivesms);
Intent act = getIntent();
ReceivedSms = act.getStringExtra("message");
showSms = (TextView) this.findViewById(R.id.textView2);
showSms.setText(ReceivedSms);
Give your BroadcastReceiver a high priority in your AndroidManifest. This will put your receiver first in line to process the broadcast.
<receiver
android:name=".SmsReceiver">
<intent-filter
android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Inside your BroadcastReceiver, check if the number of the incoming sms equals your given number. If true, then cancel the broadcast with abortBroadcast().
Edit
There are a couple of things to watch out for:
When you do the number matching, be aware of phone number formatting. If the incoming number is 0123456789 and you use String.equals('+XX0123456789'), then your check will fail, even though its technically correct. Have a look at PhoneNumberUtils to find a solution for this.
If I recall correctly, some device manufacturers have given the default SMS application priority one on processing sms broadcasts. This will mess with your application. Be sure to test this out ;)
Assuming you meant to say that your special number should not show up in the inbox...
You cannot re-route the message being received by the phone. So instead you have to upon receiving that message then look it up in the MMS database and delete it, there is no other way.
I am developing a simple SMS Application in android,i am able to send and receive messages.
during receiving of sms i want my application should open whenever the sms comes from a specified number with some notification within the app and it shouldnot open whenever it comes from unspecified number..
what i am able to do is open the app whenever the message comes from the specified number but not able to stop my application from getting invoked(incase of unspecified number).
Help..
Your problem lies here:
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
phNum = msgs[i].getOriginatingAddress();
if("9716009159".equals(phNum)){
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
abortBroadcast();
}
else{
clearAbortBroadcast();
}
}
//---display the new SMS message---
//Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
//---launch the MainActivity--
Intent mainActivityIntent = new Intent(context, MainActivity.class);
mainActivityIntent.putExtra("ph", phNum);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);
//---send a broadcast to update the SMS received in the activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
}
}
The launching of your activity should only happen when the message is from the number you specify. At the moment you launch the activity as long as the message is not null. Instead of the code above, use this:
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
phNum = msgs[i].getOriginatingAddress();
if("9716009159".equals(phNum)){
str += "SMS from " + msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
str += "\n";
//---display the new SMS message---
//Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
//---launch the MainActivity--
Intent mainActivityIntent = new Intent(context, MainActivity.class);
mainActivityIntent.putExtra("ph", phNum);
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityIntent);
//---send a broadcast to update the SMS received in the activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
abortBroadcast();
}
else{
clearAbortBroadcast();
}
}
}
}
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();// note this line gives your contact number
str += " ::::::::::::::::::::";
str += msgs[i].getMessageBody().toString();
str += "\n";
}
}
This code what you are writing in your broad cast reciver
see // code which gives the incoming message number
get the number from there and check the number with the number which you want to restrict if true then dont start you application if false start your application thats it
If you need more assistance comment me
It's not a good idea to open your application when the SMS comes. Imagine your user playing a game or watching youtube, and when the SMS comes your application appears in the foreground without user expecting it. This is not pleasant for your users. Good practice is to implement a service, that will scan received SMS and check whether number is specified or not. Then if number is specified you can add a notification to the notification bar to make user see the alert. When user clicks on your notification he opens your app and sees the information you provide. Hope this helps you.
You need to handle the sms received event in a broadcastreceiver, not an activity. In the broadcastreceiver's onReceive method you can filter the phone numbers, and if it is a phone number you're interested in, you can launch your activity.
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
if(phone number matches your filter){
startActivity(your intent);
}
}
}
}
And to declare the receiver in the manifest:
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
EDIT: The phone number you get from the system probably contains country code, area code etc, and therefore you should compare the strings like this:
if(extractedNumber.contains(yourNumber)){
//do your stuff
}
I've found a few tutorials on how to send/receive text SMS messages, but none on how to send/receive data SMS messages. I have a very small amount of data I would like the users of my app to be able to share.
I am able to send, but my BroadcastReceiver doesn't ever get called. It seems this is a known issue (http://code.google.com/p/android/issues/detail?id=1576) but has anyone figured out how to do this yet?
I tried sending/receiving a text SMS and that works fine, the thing is, I need to specify a port so only my app can listen for the SMS.
It seems this question has been asked here before and was never answered: how to receive text sms to specific port..
I know this is 1 year old at time of my response, but I thought it could still help someone.
Receiving:
Bundle bundle = intent.getExtras();
String recMsgString = "";
String fromAddress = "";
SmsMessage recMsg = null;
byte[] data = null;
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
for (int i=0; i<pdus.length; i++){
recMsg = SmsMessage.createFromPdu((byte[])pdus[i]);
try {
data = recMsg.getUserData();
} catch (Exception e){
}
if (data!=null){
for(int index=0; index<data.length; ++index)
{
recMsgString += Character.toString((char)data[index]);
}
}
fromAddress = recMsg.getOriginatingAddress();
}
Setting up Receiver in Manifest:
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.intent.action.DATA_SMS_RECEIVED" />
<data android:scheme="sms" />
<data android:port="8901" />
</intent-filter>
</receiver>
Sending:
String messageText = "message!";
short SMS_PORT = 8901; //you can use a different port if you'd like. I believe it just has to be an int value.
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendDataMessage("8675309", null, SMS_PORT, messageText.getBytes(), null, null);