I have an SMS reader application and i am showing the senderno and message body into the Custom Listview. For the incoming messages i have registered a broadcast receiver and populating the listView.
Whenever a new message is coming in the broadcast Receiver i am able to get it but I want to this data to be passed onto the activity.
The code snippets are :
MainActvity.java
public class MainSmsActivity extends Activity{
private ListView smsList;
SmsAdapter smsAdapter;
private SmsDao smsDao;
private List<SmsDao> smsDataList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms_demo);
smsDataList = new ArrayList<SmsDao>();
Intent intent = new Intent();
intent.setAction("com.mobile.sms.IncomingSms");
sendBroadcast(intent);
populateSms();
}
public void populateSms(){
Uri inboxURI = Uri.parse("content://sms/inbox");
String[] reqCols = new String[] { "_id", "address", "body", "date" };
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(inboxURI, reqCols, null, null, null);
smsDataList.clear();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
smsDao = new SmsDao();
smsDao.setMessageBody(cursor.getString(1));
smsDao.setSenderNo(cursor.getString(2));
smsDao.setMessageTime(cursor.getLong(3));
smsDataList.add(smsDao);
}
smsAdapter = new SmsAdapter(this,smsDataList);
smsList.setAdapter(smsAdapter);
smsAdapter.notifyDataSetChanged();
cursor.close();
}
}
IncomingSms.Java
public class IncomingSms extends BroadcastReceiver {
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context context, Intent intent) {
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();
int duration = Toast.LENGTH_LONG; // HERE I WANT TO SEND MESSAGE BODY TO THE MAIN ACTIVITY CLASS
Toast toast = Toast.makeText(context,
"senderNum: " + senderNum + ", message: " + message, duration);
toast.show();
} // end for loop
} // bundle is null
} catch (Exception e) {
Log.e("SmsReceiver", "Exception smsReceiver" + e);
}
}
I am able to receive all the messages intially into the list view but I want that the ListView should get automatically updated as soon as new message arrives.
In your broadcasereceiver do something like this: (use that intent)
public class SMSReceiver extends BroadcastReceiver {
public static final String NOTIFICATION = "receiver_sms";
#Override
public void onReceive(Context context, Intent intent) {
Log.i("onReceive methode", "new SMS Comming");
Bundle myBundle = intent.getExtras();
SmsMessage[] messages = null;
String strMessage = "", address = "";
abortBroadcast();
if (myBundle != null) {
// get message in pdus format(protocol description unit)
Object[] pdus = (Object[]) myBundle.get("pdus");
// create an array of messages
messages = new SmsMessage[pdus.length];
Log.i("onReceive methode", "new SMS Comming");
for (int i = 0; i < messages.length; i++) {
// Create an SmsMessage from a raw PDU.
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
// get the originating address (sender) of this SMS message in
// String form or null if unavailable
address = messages[i].getOriginatingAddress();
// get the message body as a String, if it exists and is text
// based.
strMessage += messages[i].getMessageBody();
strMessage += "\n";
}
// show message in a Toast
}
// this is what you need
Intent broadcast = new Intent(NOTIFICATION);
broadcast.putExtra("data", strMessage);
LocalBroadcastManager.getInstance(context).sendBroadcast(broadcast);
}
and then register ur receiver in ur activity
public BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(tag, "SMS Received.");
// Intent i = getIntent();
Bundle b = intent.getBundleExtra("SMS");
// String bun = b.getString("MyData");
Log.i(tag, "Bundle: " + b);
String str = intent.getStringExtra("data");
parseSMSData(str);
}
};
and then in onResume():
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter(SMSReceiver.NOTIFICATION));
}
and in onDestroy() you must unregister that receiver like this:
#Override
protected void onDestroy() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
super.onDestroy();
}
and also don't forget to add this in ur manifest file in application tag:
<receiver android:name=".SMSBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
register your service in OnResume() then you can access easily within your class,
#Override
public void onResume()
{
super.onResume();
this.registerReceiver(this.yourservice, new IntentFilter("your service type"));
}
and unregister the service in your onpause()
#Override
public void onPause() {
super.onPause();
try
{
this.unregisterReceiver(this.your service);
}
catch(Exception e)
{
e.printStackTrace();
}
}
add the your broadcast receiver in your activity ,
private WakefulBroadcastReceiver IncomingSms = new WakefulBroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//use your receiver content
}
Put the following class in your MainSmsActivity so that you should be able to process your list.
private class IncomingSms extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("incomingSms")) {
//your impl here
}
}
}
and in onCreate() of your MainSmsActivity activity, place the following code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
IncomingSms broadcastReceiver = new IncomingSms(); // declare it outside so that it should be accessible in onDestroy()
IntentFilter intentFilter = new IntentFilter("incomingSms");
registerReceiver(broadcastReceiver , intentFilter);
}
and in onDestroy() place the following code
#Override
protected void onDestroy() {
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
super.onDestroy();
}
Related
Here is my service MyServiceSMS.java
Whenever I close my app I only receive a default toast of
broadcastreceiver "Message Recieved By : xxxxxxx"
Rest of the code is not executing below onReceiceve.
I have some task inside onReceiceve method, I want them to be executed even if the user closes the app.
public class MyServiceSMS extends Service {
private IntentFilter mIntentFilter;
private SMSGetter smsGetter;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
smsGetter = new SMSGetter();
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsGetter, mIntentFilter);
Toast.makeText(this, "Hello I'm a service", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onDestroy() {
super.onDestroy();
//unregisterReceiver(smsGetter);
}
public class SMSGetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);
JSONObject data = new JSONObject();
try {
data.put("from", smsMessage.getDisplayOriginatingAddress());
data.put("message", smsMessage.getMessageBody());
SharedPreferences sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
if (sharedPreferences.contains(IP) && sharedPreferences.contains(IP)) {
sendSMsToServer sendTextToServer = new sendSMsToServer();
sendTextToServer.execute(data.toString(), sharedPreferences.getString(IP, ""), sharedPreferences.getString(PORT, ""));
Toast.makeText(context, "Your Ip :" + data.toString(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Your IP is empty .. Scan to get IP Again ..", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
// Toast.makeText(context, smsMessage.getDisplayMessageBody(), Toast.LENGTH_SHORT).show();
}
}
}
}
My Manifest
<service
android:name=".viewmodel.MyServiceSMS"
android:enabled="true"
android:exported="true"></service>
In my Application I have a Broadcast receiver (registered in manifest) class from which I want to send an Intent to MainActivity. Therefore I have another broadcast receiver (dynamically registered) in MainActivity and an Intent Filter. But I don't receive the Intent in Main Activity.
This is the code:
public class SmsReceiver extends BroadcastReceiver {
public static final String SMS_BUNDLE = "pdus";
public SmsReceiver(){
}
String TAG = SmsReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent){
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] sms = (Object[]) bundle.get(SMS_BUNDLE);
String str = "";
for (int i=0; i < sms.length; i++) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);
String smsbody = smsMessage.getMessageBody().toString();
str += smsbody;
}
Intent bcIntent = new Intent();
bcIntent.setAction("SMS_RECEIVED_ACTION");
bcIntent.addCategory(Intent.CATEGORY_DEFAULT);
bcIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
bcIntent.putExtra("message", str);
context.sendBroadcast(bcIntent);
}
}
}
and in the MainActivity:
public class MainActivity extends AppCompatActivity
{
public boolean receivedSMS;
public String displaySMS;
private BroadcastReceiver iReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String qqq = intent.getExtras().getString("message");
info2(intent.getExtras().getString("message"));
evalMsg(qqq);
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
graphInit();
timerInit();
smnInit();
}
#Override
protected void onResume(){
super.onResume();
IntentFilter iFilter = new IntentFilter();
iFilter.addAction("SMS_RECEIVED_ACTION");
registerReceiver(iReceiver, iFilter);
}
#Override
protected void onPause(){
unregisterReceiver(iReceiver);
super.onPause();
}
Does anyone know why the broadcast receiver in the main activity doesnt receive the intent? There should be a text displayed in the TextView but it is never shown. thanks for any idea
When receiving the intent via SmsReceiver you can't know if the Activity is up and in what state.
What you should consider is using startActivity(android.content.Intent) from within your SmsReceiver.onReceive(). This way you'll have the same intent object available within Activity.onCreate (just call the getIntent() method)
But if you want to stick to your original design of double broadcasts, then here is your answer.
In a SMS aplication I want to pass a value of a String from de BroadcastReceiver to the main method.
public class LucesAlarma extends AppCompatActivity {
IntentFilter intentFilterLA;
private BroadcastReceiver intentRecieverLA = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
final String MENSAJE = intent.getExtras().getString("mensaje");
String NUMERODELMENSAJE = intent.getExtras().getString("numero");
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_luces_alarma);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
intentFilterLA = new IntentFilter();
intentFilterLA.addAction("SMS_RECEIVED_ACTION");
//I want to use the String Mensaje from the BroadcastReceiver here
}
#Override
protected void onResume()
{
registerReceiver(intentRecieverLA, intentFilterLA);
super.onResume();
}
#Override
protected void onPause()
{
unregisterReceiver(intentRecieverLA);
super.onPause();
}
}
Here is the SMS receiver code
public class ReceptorSMS extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
SmsMessage[]messages=null;
String str = "";
String num = "";
String men = "";
if(bundle != null)
{
Object[] pdus = (Object[]) bundle.get("pdus");
assert pdus != null;
messages = new SmsMessage[pdus.length];
for (int i=0 ; i<messages.length;i++)
{
messages[i]=SmsMessage.createFromPdu((byte[])pdus[i]);
num = messages[i].getDisplayOriginatingAddress();
str += "Mensaje de" +messages[i].getOriginatingAddress();
str += ":";
str += messages[i].getMessageBody();
str += "\n";
men = messages[i].getMessageBody();
}
// Toast.makeText(context,str,Toast.LENGTH_SHORT).show();
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
broadcastIntent.putExtra("mensaje", men);
broadcastIntent.putExtra("numero", num);
context.sendBroadcast(broadcastIntent);
}
}
}
Please I want to know how to get that String into the main methot.
I assume that you want to start activity when receive any SMS, than you should do like this
in your ReceptorSMS class
public void onReceive(Context context, Intent intent)
{.
.
.
Toast.makeText(context,str,Toast.LENGTH_SHORT).show();
Intent broadcastIntent = new Intent();
broadcastIntent .setClassName("<YOUR PACKAGE NAME>", "<YOUR PACKAGE NAME>.LucesAlarma");
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
broadcastIntent.putExtra("mensaje", men);
broadcastIntent.putExtra("numero", num);
context.startActivity(broadcastIntent);
}
after that in onCreate
Intent intent = getIntent();
String sms= intent.getStringExtra("sms");
String men = intent.getStringExtra("mensaje");
String num = intent.getStringExtra("numero");
I am working on an application that needs to read an incoming message. Now, i found out that i need to use the onReceive method from the BroadcastReceiver class. Now i got to know that java does not allow extending two classes, so how do i get it working, i have been stuck on this from a long time, please help! Also if there is some other way to do this, please do quote.
public class SMS extends Activity {
Button btnSendSMS;
EditText txtPhoneNo;
EditText txtMessage;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.sms);
btnSendSMS = (Button) findViewById(R.id.btnSendSMS);
txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo);
btnSendSMS.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
String phoneNo = txtPhoneNo.getText().toString();
if (phoneNo.length()>0)
sendSMS(phoneNo, phoneNo);
else
Toast.makeText(getBaseContext(),
"Please enter a valid Phone Number.",
Toast.LENGTH_SHORT).show();
}
});
}
private void sendSMS(String phoneNumber, String message)
{
PendingIntent pi = PendingIntent.getActivity(this, 0,
new Intent(this, SMS.class), 0);
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, pi, null);
}
Context context = getApplicationContext();
Intent intent = new Intent();
object.onReceive(context, intent); }
class SMSBroadcastReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static final String TAG = "SMSBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Intent recieved: " + intent.getAction());
Toast.makeText(context, "HI", Toast.LENGTH_SHORT).show();
if (intent.getAction().equals(SMS_RECEIVED)) {
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) {
Toast.makeText(context, "Message recieved: " + messages[0].getMessageBody(), 7000).show();
}
}
}
} }
You don't need to extend two classes (which is not possible and never required in java) to achieve your goal. For getting the last message simply create a static message variable, lets say in your SMSBroadcastReceiver and set that variable to latest message received in onreceive. This static variable can be accessed throughout your app using SmsReceiver.latestmessage
I have a receiver that is called whenever an SMS is received
public class SMSReceiver extends BroadcastReceiver {
private SharedPreferences prefs;
private String prefName = "MyPref";
private static final String NUMBER_KEY = "number";
#Override
public void onReceive(Context context, Intent intent) {
// ---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
String Sender = 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]);
Sender = msgs[i].getOriginatingAddress();
}
prefs = context
.getSharedPreferences(prefName, Context.MODE_PRIVATE);
String phoneNumber = (String) prefs.getString(NUMBER_KEY, "");
// If the sender of the SMS just received is the same as one chosen
// earlier
if (Sender.equals(phoneNumber)) {
Toast.makeText(context, "text message received",
Toast.LENGTH_LONG).show();
// ---Launch the minderActivity even when the app is not in the
// foreground---
Intent minderActivityIntent = new Intent(context, Minder.class);
minderActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(minderActivityIntent);
// ---send a broadcast intent to update the SMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("Sender", Sender);
context.sendBroadcast(broadcastIntent);
}
}
}
}
I register the receiver in an activity called "minder" using a button
registerReceiver(intentReceiver, intentFilter);
In this "minder" activity I also have a BroadcastReceiver
private BroadcastReceiver intentReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// ---gather up all the necessary user input---
prefs = getSharedPreferences(prefName, MODE_PRIVATE);
final Button btn2 = (Button) findViewById(R.id.btnContacts);
String phoneNumber = (String) prefs.getString(NUMBER_KEY, "");
String messageChosen = (String) prefs.getString(MESSAGE_KEY, "");
String delay = (String) prefs.getString(DELAY_KEY, "");
String Sender = (String) intent.getExtras().getString("Sender");
if (Sender.equals(phoneNumber)) {
sendSMS(phoneNumber, messageChosen, delay);
}
}
};
All of the permissions are defined in the manifest.
Unfortunately when I test the receiver (i.e. send an sms to the phone, after the receiver has been registered, from the number that is defined as "phoneNumber") the app performs no action. Any ideas what is missing from my above code?