Is it possible to receive SMS message on appWidget? - android

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.

Related

How better send data from BroadcastReceiver to Activity?

I wan catch SMS in my app and show it o my view. I create BroadcastReceiver:
public class SMSMonitor extends BroadcastReceiver {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction() != null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) {
Object[] pduArray = (Object[]) intent.getExtras().get("pdus");
SmsMessage[] messages = new SmsMessage[pduArray.length];
for (int i = 0; i < pduArray.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]);
}
StringBuilder bodyText = new StringBuilder();
for (SmsMessage message : messages) {
bodyText.append(message.getMessageBody());
}
String body = bodyText.toString();
Toast.makeText(context, body, Toast.LENGTH_LONG).show();
abortBroadcast();
}
}
}
And it show Toast wuth SMS body. Now i dont know what should I do
Create Service and pass SMS to service. And get SMS from service
Use Otto observer and send data(SMS) from:
1. BroadcastReceiver
2. Service
and catch in my activity.
Another more correct way
And if I will use Otto (I want it) where better send data - from BroadcastReceiver or pass data to service and send otto message from Service?
Otto or EventBus is for me the most simple solution and the solution that will reflect best your Activity lifecycle.
A great start is to register/unregister your bus from onPause() and onResume like so :
#Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
#Override
public void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
Next, post an event from your BroadcastReceiver like BusProvider.getInstance().post(new SmsEvent());
Your fragment or Activity will received the event via the #Subscribe method and the SmsEvent parameter type of the method.
It seems you don't need any Service here except if you want to save the data when the activity is not open.

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

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')){
...
}
}

send data from a broadcast to an activity . how to do send?

how to send data from a broadcatReceiver to an activity in android as saying catch the received SMS and send the SMS (is the data) to the activity its my first time that i work with broadcatReceiver so can anyone help me i will appreciate any help.
i read several tutorials about the data transferring that have some steps :
create a class that extends activity
create a class that extends broadcastReceiver
but i did not know how is the communication between these 2 classes.
I would do something like that:
public class YourActivity extends Activity
{
private Handler handler = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.id.main_layout);
this.handler = new Handler() {
#Override
public void handleMessage(Message msg)
{
SmsMessage sms = (SmsMessage) msg.obj;
String senderNumber = sms.getOriginatingAddress();
}
};
// Register a new receiver that will trigger on SMS_RECEIVED event
IntentFiler filer = new IntentFilert("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(mSmsReceiver, filter);
}
#Override
protected void onDestroy()
{
super.onDestroy();
// Unregister the receiver
unregisterReceiver(mSmsReceiver);
}
private mSmsReceiver = new BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
if (bundle == null || bundle.containsKey("pdus") return;
// Decode the message
SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdus[0]);
// Notify the activity with the message
Message msg = new Message;
msg.obj = sms;
YourActivity.this.handler.sendMessage(msg);
}
};
}
The receiver and the Activity are separate entities and do not usually interact directly. Imagine the following scenario: you have a receiver getting lots of SMS messages, and every time you get one, you launch an Activity to show the message received. Wouldn't this be very annoying to the user?
I'd says that you can interact with the user by creating a Notification and if the user clicks on it, then you open the Activity you want to show the details.
As how to pass the data to the Activity (hopefully using a notification first), given that SMS messages are short in nature you can just put the data in the Intent.
How to set a Notification to launch an Activity: see Open application after clicking on Notification

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

Categories

Resources