Error in broadcast receiver for android, it listens to all SMSs that my phone receives - android

I'm doing an encryption SMS app, in which, user can encrypt the text and send SMS through my apps.
I used the following broadcast receiver.
The problem is that its listen to all the SMS that come to my phone.
How to make it so that it will only listen to the SMS sent from my apps? Other sms's should open as normal, using default SMS application
public class SmsBroadCastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
// Specify the bundle to get object based on SMS protocol "pdus"
Object[] object = (Object[]) bundle.get("pdus");
SmsMessage sms[] = new SmsMessage[object.length];
Intent in=new Intent(context,DisplaySMSActivity.class);
in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String msgContent = "";
String originNum = "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < object.length; i++) {
sms[i] = SmsMessage.createFromPdu((byte[]) object[i]);
// get the received SMS content
msgContent = sms[i].getDisplayMessageBody();
//get the sender phone number
originNum = sms[i].getDisplayOriginatingAddress();
//aggregate the messages together when long message are fragmented
sb.append(msgContent);
//abort broadcast to cellphone inbox
abortBroadcast();
}
//fill the sender's phone number into Intent
in.putExtra("originNum", originNum);
//fill the entire message body into Intent
in.putExtra("msgContent", new String(sb));
//start the DisplaySMSActivity.java
context.startActivity(in);
}

Maybe you are not correctly registering your receiver.
When declaring a Receiver in the manifest (or programmatically), you can also specify an intent filter. You can specify the 'action' you want to receive in your receiver.
For example: "com.your_app_package.sms_encrypted_msg".
Either way, remember to check the action in the onReceive method:
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals('com.your_app_package.sms_encrypted_msg')){
...
}
}

Related

Hide sms notifications with a broadcastreceiver in KitKat

I'm trying to intercept the received SMSs by using a broadcast receiver. Here is the code:
<receiver android:name=".receivers.SmsReceiver" android:enabled="true"
android:exported="true" android:priority="999">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
and:
public class SmsReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent) {
if (SMS_RECEIVED.equals(intent.getAction())) {
this.abortBroadcast();
Bundle bundle = intent.getExtras();
if (bundle != null) {
// get sms objects
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus.length == 0) {
return;
}
// large message might be broken into many
SmsMessage[] messages = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append(messages[i].getMessageBody());
}
String sender = messages[0].getOriginatingAddress();
String message = sb.toString();
Log.d("sms", sender);
Log.d("sms", message);
}
}
}
}
The SMS is intercepted fine, but the stock Android SMS app is still showing its notifications and I can also find the message inside the stock app sms list.
Is there any way to stop the stock SMS app notifications and to avoid the message from appearing inside its list?
You need to call abortBroadcast();, see my answer to communication between two device using sms
If you are running Android 4.4 KitKat, it seems to be more difficult to do these sorts of things and have not looked into it yet myself.
As you said you are running KitKat, then answer is - you cannot mute default SMS app. You can also receive messages or send (that's why you get messages), but still, you cannot "consume" the message.
If user has set your application as default SMS app, then he/she is not going to get an SMS notification. You have to handle the notification, as well as other feature of the SMS in your app.
For more information read this blog.
Check out other blog and sample app.

Update widget after sms receive

i'm having some trouble about this operation.
I have a widget that update some things. When arrive an sms , i wanna update it after receiving. I have written a BrodCastReceiver Class, but it update before arrive.
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;
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
ComponentName name = new ComponentName(context, Randomnuberwidget.class);
int [] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(name);
Intent update = new Intent();
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
update.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
context.sendBroadcast(update);
}
i think you need to add an if statement checking the action of the intent... as far as i can tell a broadcastreciever is capable of picking up any implicit broadcast intent, so your code will fire anytime there is such a broadcast intent the way you have it set up now...
try adding
if (bundle.getAction().equals("android.provider.Telephony.SMS_RECEIVED"){
//update widget
}
grant i'm not certain about the if statement, but it should be a minor variation on that...

Broadcast Receiver does not trigger when Mobile Screen Locks

When I install the app everything works fine. I am able to print Message body every time I send a message until I lock mobile screen. After that, the app stops printing incoming messages. I tried many ways to overcome this problem but with no luck. Please help me...
public class SmsReceiveActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
Object[] pdus = (Object[]) bundle.get("pdus");
final android.telephony.SmsMessage[] messages = new android.telephony.SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = android.telephony.SmsMessage.createFromPdu((byte[]) pdus[i]);
incomingMsgString += messages[i].getMessageBody().toString();
}
// Print Incoming message Body
}
}
}
getApplication().registerReceiver(receiver, new IntentFilter(SMS_RECEIVED));
}
}
Per the BroadcastReceiver docs, when you register a receiver with registerReceiver(), "You won't receive intents when paused". If you want a receiver that is independent of your activity, you should implement it as a named class and publish it in your manifest. For example, create a named class with your anonymous BroadcastReceiver,
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
Object[] pdus = (Object[]) bundle.get("pdus");
final android.telephony.SmsMessage[] messages = new android.telephony.SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = android.telephony.SmsMessage.createFromPdu((byte[]) pdus[i]);
incomingMsgString += messages[i].getMessageBody().toString();
}
// Print Incoming message Body
}
}
}
And in your manifest add the receiver inside your application tag
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/ >
</intent-filter>
</receiver>
Then when an SMS message is received your onReceive method will be invoked. There you can package up the information you need and launch an intent to your Activity or Service for further processing.
Create your broadcast as static inner class and register it in manifest. Try this link. Receiver as inner class in Android

How to prevent SMS going to inbox in Android?

I'm developing a business SMS application. In this app, if an incoming message is from a particular number, say 999999999, it should go to the application's inbox and not to the default native inbox. All other messages should go to the phone's native inbox. How do I do this?
When SMS is received by the Android system, it broadcasts an ordered broadcast Intent with action "android.provider.Telephony.SMS_RECEIVED". All registered receivers, including the system default SMS application, receive this Intent in order of priority that was set in their intent-filter. The order for broadcast receirers with the same priority is unspecified. Any BroadcastReceiver could prevent any other registered broadcast receivers from receiving the broadcast using abortBroadcast().
So, everything you need is broadcast receiver like this:
public class SmsFilter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
Bundle extras = intent.getExtras();
if (extras != null) {
Object[] pdus = (Object[])extras.get("pdus");
if (pdus.length < 1) return; // Invalid SMS. Not sure that it's possible.
StringBuilder sb = new StringBuilder();
String sender = null;
for (int i = 0; i < pdus.length; i++) {
SmsMessage message = SmsMessage.createFromPdu((byte[]) pdus[i]);
if (sender == null) sender = message.getOriginatingAddress();
String text = message.getMessageBody();
if (text != null) sb.append(text);
}
if (sender != null && sender.equals("999999999")) {
// Process our sms...
abortBroadcast();
}
return;
}
}
// ...
}
}
Looks like the system default SMS processing application uses priority of 0, so you could try 1 for your application to be before it. Add these lines to your AndroidManifest.xml:
<receiver android:name=".SmsFilter">
<intent-filter android:priority="1">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Don't forget about necessary permissions:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
By the way, you can find all registered receivers and their priorities using this code:
Intent smsRecvIntent = new Intent("android.provider.Telephony.SMS_RECEIVED");
List<ResolveInfo> infos = context.getPackageManager().queryBroadcastReceivers(smsRecvIntent, 0);
for (ResolveInfo info : infos) {
System.out.println("Receiver: " + info.activityInfo.name + ", priority=" + info.priority);
}
Update: As FantasticJamieBurn said below, starting from Android 4.4 the only app that can intercept SMS (and block if it wish) is the default SMS app (selected by user). All other apps can only listen for incoming SMS if default SMS app not blocked it.
See also SMS Provider in the Android 4.4 APIs.
With the release of Android 4.4 KitKat (API level 19), the option to block an SMS message and prevent it from being delivered to the default SMS app has been removed. Non-default SMS app's may observe SMS messages as they are received, but any attempt to abort the broadcast will be ignored by Android 4.4+.
If you have an existing app which relies on aborting SMS message broadcasts then you may want to consider the impact this change in behaviour will have when your users upgrade to Android 4.4+.
http://android-developers.blogspot.co.uk/2013/10/getting-your-sms-apps-ready-for-kitkat.html
Yes it can be DOne
public void onReceive(Context context, Intent intent)
{
Bundle bundle=intent.getExtras();
Object[] messages=(Object[])bundle.get("pdus");
SmsMessage[] sms=new SmsMessage[messages.length];
Toast.makeText(context, "Hello", 1).show();
for(int n=0;n<messages.length;n++){
sms[n]=SmsMessage.createFromPdu((byte[]) messages[n]);
}
for(SmsMessage msg:sms){
if(msg.getOriginatingAddress().endsWith(number))
{
SMS.updateMessageBox("\nFrom: "+msg.getOriginatingAddress()+"\n"+
"Message: "+msg.getMessageBody()+"\n");
/*((SMS) context).delete();*/
abortBroadcast();
}
}
}
just use abortbroadcast() after receiving in app
Are you the one sending the messages? If so consider using datasms instead as they will not show up in the inbox.
Check this question for more info on how to use it
Check the sender number is equal to the mobile number of your sms sending phone.
replace the following code line of Mr "praetorian droid"
if (sender != null && sender.equals("999999999")) {
to
if (sender != null && sender.equals("YOUR SMS SENDING MOBILE NUMBER HERE")) {
further more you can give a setting to user to manually add sms sending number if he want to change it.

Is it possible to receive SMS message on appWidget?

Is it possible to receive SMS message on appWidget?
I saw android sample source(API Demos).
In API Demos, ExampleAppWidgetProvider class extends AppWidgetProvider, not Activity.
So, I guess it is impossible to regist SMS Receiver like this,
rcvIncoming = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("telephony", "SMS received");
Bundle data = intent.getExtras();
if (data != null) {
// SMS uses a data format known as a PDU
Object pdus[] = (Object[]) data.get("pdus");
String message = "New message:\n";
String sender = null;
for (Object pdu : pdus) {
SmsMessage part = SmsMessage.createFromPdu((byte[])pdu);
message += part.getDisplayMessageBody();
if (sender == null) {
sender = part.getDisplayOriginatingAddress();
}
}
Log.i(sender, message);
}
}
};
registerReceiver(rcvIncoming, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
My goal is to receive SMS message on my custom appWidget.
Any help would be appreciated!!
AppWidgetProvider is a derived class of BroadcastReceiver. Therefore, you can override onReceive() to handle SMS message. Of course, you have to setup intent filter for SMS_RECEIVED in the manifest correctly first.

Categories

Resources