This is the BroadcastReceiver in which context is cast into listener interface:
public class StatusChangeReceiver extends BroadcastReceiver {
private IStatusChangeListener listener;
@Override
public void onReceive(Context context, Intent intent) {
listener = (IStatusChangeListener) context; // getting error in this line when using LocalBroadcastManager
if (NetworkUtil.isNetworkConnected()) {
listener.onConnected();
} else {
listener.onDisconnected();
}
}
}
This is the interface:
public interface IStatusChangeListener {
void onConnected(String status);
void onDisonnected(String status);
}
Now I'm implementing the IStatusChangeListener
interface in a Fragment like below:
public class MainFragment extends Fragment implements IStatusChangeListener {
//some codes
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
StatusChangeReceiver r = new StatusChangeReceiver();
LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
//getContext().registerReceiver(r, new IntentFilter("connectionStatus"));
}
@Override
void onConnected(String status) {
//some log here
}
@Override
void onDisonnected(String status) {
//some log here
}
}
When I use getContext().registerReceiver(r, new IntentFilter("connectionStatus"));
then I get no error but I get no call in the implemented listener's methods in the Fragment.
When I use LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
then I get java.lang.ClassCastException error:
<ContextName> cannot be cast to IStatusChangeListener
So what is the solution to overcome this problem? Is there any standard way to implement BroadcastReceiver which casts context into listener?
You have to check if the context is instance of IStatusChangeListener
or not.
public class StatusChangeReceiver extends BroadcastReceiver {
private IStatusChangeListener listener;
@Override
public void onReceive(Context context, Intent intent) {
if(context instanceof IStatusChangeListener){
listener = (IStatusChangeListener) context; // getting error in this line //when using LocalBroadcastManager
if (NetworkUtil.isNetworkConnected()) {
listener.onConnected();
} else {
listener.onDisconnected();
}
}
}
}
In your activity
public class YourActivity extends AppCompatActivity implements IStatusChangeListener {
MainFragment mainFragment;
@Override
public void onConnected(String status) {
if (mainFragment!=null){
mainFragment.onConnected();
}
}
@Override
public void onDisonnected(String status) {
if (mainFragment!=null) {
mainFragment.onDisonnected();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mainFragment = MainFragment();
//do fragment trasaction
//get transaction
transaction.replace(R.id.fragment_container, mainFragment ); transaction.commit();
}
}
You can try the following,
public class SomeClass implements IStatusChangeListener,Parcelable {
// implement the required methods
}
Activity class
SomeClass someclass = new SomeClass();
intent.putExtra("someclass",someclass)
Reciever Class
@Override
public void onReceive(Context context, Intent intent) {
Bundel b = intent..getExtras()
if(b != null){
SomeClass someclass = b.getParcelable("someclass");
//rest of your logic
}
}
Edit:
just put the instance of the SomeClass
in the intent which you will be wrapping with a PendingIntent
and you can use the intent
and the rest of the logic remains same and by this way your MainActivity
need not to implement IStatusChangeListener
After searching for hours for the appropriate way to implement such a solution to this problem, I've found a way finally.
In this way, a setListener()
method is exposed so that Fragment
or Activity
can set the listener by sending an instance of IStatusChangeListener
.
public class StatusChangeReceiver extends BroadcastReceiver {
private IStatusChangeListener listener;
public void setListener(IStatusChangeListener listener) {
this.listener = listener;
}
@Override
public void onReceive(Context context, Intent intent) {
if (NetworkUtil.isNetworkConnected()) {
listener.onConnected();
} else {
listener.onDisconnected();
}
}
}
This is the interface:
public interface IStatusChangeListener {
void onConnected(String status);
void onDisonnected(String status);
}
Now, it is required to have an instance of IStatusChangeListener
interface instead of implementing the IStatusChangeListener
interface. And then, pass this instance of IStatusChangeListener
to setListener()
method.
public class MainFragment extends Fragment { //Not implementing the interface
private IStatusChangeListener listener = new IStatusChangeListener() {
@Override
void onConnected(String status) {
//some log here
}
@Override
void onDisonnected(String status) {
//some log here
}
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
StatusChangeReceiver r = new StatusChangeReceiver();
r.setListener(listener); // pass the IStatusChangeListener instance
LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
}
}
Note: Always use LocalBroadcastManager
if you register BroadcastReceiver
from Fragment
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.