Reputation: 549
I have service, which gets data from API and sends this data to BroadcastReceiver class. Also, I create interface OnReceiveListener, which used in Activity. Look at the code here:
Activity:
public class StartActivity extends AppCompatActivity
implements MyBroadcastReceiver.OnReceiveListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
receiver.setOnReceiveListener(this);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter(MyBroadcastReceiver.START));
...
}
@Override
public void onReceive(Intent intent) {
// Do smth here
}
}
MyBroadcastReceiver:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String START = "com.example.myapp.START";
public static final String GET_LINKS = "com.example.myapp.GET_LINKS";
private OnReceiveListener onReceiveListener = null;
public interface OnReceiveListener {
void onReceive(Intent intent);
}
public void setOnReceiveListener(Context context) {
this.onReceiveListener = (OnReceiveListener) context;
}
@Override
public void onReceive(Context context, Intent intent) {
if(onReceiveListener != null) {
onReceiveListener.onReceive(intent);
}
}
}
Service isn't important on this question.
---- Question ----
So, what's problem: I want to use this receiver in fragment, but when it sets context - I get exception "enable to cast". What I should to do on this case?
Here is my code in fragment:
public class MainFragment extends Fragment
implements MyBroadcastReceiver.OnReceiveListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
myBroadcastReceiver.setOnReceiveListener(getContext());
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
new IntentFilter(MyBroadcastReceiver.GET_LINKS));
}
@Override
public void onReceive(Intent intent) {
// Do smth here
}
}
Upvotes: 0
Views: 1520
Reputation: 199
After searching for hours for the appropriate way to implement such a solution to this problem, I've found a way finally. It is based on RussHWolf's answer. The complete solution with code is below:
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
.
Upvotes: 0
Reputation: 1105
you don't need to dynamically register the receiver. i believe you must have registered it in manifest using <receiver>
tag.
this is not required:
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver, new IntentFilter(MyBroadcastReceiver.GET_LINKS));
and about callback registering listener, instead of using getContext()
use MainFragment.this
like this:
myBroadcastReceiver.setOnReceiveListener(MainFragment.this);
Upvotes: 0
Reputation: 3664
Your MainFragment
class implements your OnReceiveListener
interface, not its Context
as returned by getContext()
. Instead of passing a Context
object into setOnReceiveListener()
, try directly passing an OnReceiveListener
instance. Then your fragment and activity can both call setOnReceiveListener(this)
.
Upvotes: 0