Using findViewById inside BroadcastReceiver
-
29-06-2021 - |
Question
I'm creating an sms app that handles receiving sms operation for 2 user defined lists. For each list I created an activity, and xml file such as favourite_list.xml and contact_list.xml. Inside these xml files there are 2 toggle buttons. What I'm trying to do is, whenever an sms receives, learn the status (on/off) of every toggle button.
Here is my SmsReceiver class
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ToggleButton;
import android.telephony.SmsMessage;
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
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];
String str="";
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
}
}
}
}
I know I should use findViewById() to reach the status of the buttons, but I can't directly use it because SmsReceiver isn't extended from Activity. So far, what I tried to use findViewById
1- Cast context to Activity
try{
tb = (ToggleButton) ((Activity)context).findViewById(R.id.toggleButton3);
if(tb.isChecked())
Log.d("sms","SOUND-ON");
else if(!tb.isChecked())
Log.d("sms","SOUND-OFF");
}catch(Exception e){
Log.d("sms","Error " + e);
}
It gives java.lang.ClassCastException: android.app.ReceiverRestrictedContext
2- Use LayoutInflater
try{
LayoutInflater mInf = LayoutInflater.from(context);
View myView = mInf.inflate(R.layout.activity_favorite_list, null);
tb = (ToggleButton) myView.findViewById(R.id.toggleButton3);
if(tb.isChecked())
Log.d("sms","SOUND-ON");
else if(!tb.isChecked())
Log.d("sms","SOUND-OFF");
}catch(Exception e){
Log.d("sms","Error" + e);
}
This is not working too, because it gives only the status of Toggle Button when app is started. Please help, thanks.
Solution
If you just have a ToggleButton
in each of the two activities you could use two preferences fields that will be written in the activities each time you modify their status. In the BroadcastReceiver
you would use the same preferences fields to see the ToggleButton
's statuses.
If you have a ToggleButton
in each row of the lists from the two activities you would use the same approach only that will have to use another structure that holds all the values from all rows(like a String
where each row's ToggleButton
status will be a value separated by a delimiter(like |
)).
OTHER TIPS
To make the fields within an activity available within the BroadcastReceiver
you could make the BroadcastReceiver
an anonymous class within the activity
//within activity
BroadcastReceiver receiver ;
ToggleButton tb;
// within on create
receiver = new BroadcastReceiver(){
public void onReceive(Context p1, Intent p2)
{
// access tb here
}
};