问题
Here I am creating an online application that depends only on Internet.
So whenever there is a network error it must notify user. For that, I have created a BroadcastReciver that receives call when network connection gets lost(Internet).
All this works perfectly. Now what I need is that I have to call a method of Activity from this Broadcast Receiver, where I have created an Alert Dialogue.
I have read many answers on stack-overflow.com that I can declare that method static and call by using only Activity name,
e.g MyActivityName.myMethod()
But I can't declare my method static, because I am using Alert Dialogue there and it shows me error on line,
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
that Cannot use this in a static context.
So, how can I call a method of Activity(must not static and without starting that activity) from a Broadcast Receiver ?
And can I get Activity(or fragment) name from Broadcast Receiver which is currently running?
回答1:
try this code :
your broadcastreceiver class for internet lost class :
public class InternetLostReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
context.sendBroadcast(new Intent("INTERNET_LOST"));
}
}
in your activity add this for calling broadcast:
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver(broadcastReceiver, new IntentFilter("INTERNET_LOST"));
}
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// internet lost alert dialog method call from here...
}
};
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}
回答2:
Add a boolean variable in you activity from where you are open alertdialog
boolean isDialogOpened = false;
// in broadcast recever check
if(isDialogOpened) {
alertDialog();
}
And replace your code for alertdialog with this one
public void alertDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setMessage("Network not found.");
alertDialog.setPositiveButton("Check Setting",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
isDialogOpened = false;
}
});
alertDialog.show();
}
回答3:
INTERFACE: Keep BroadCastReceiver and Activity code separate!
You can make a CallBackListener interface. The interface will work as a bridge between BroadcastReceiver
and Activity
.
1) Create a CallbackListener
interface ConnectionLostCallback{
public void connectionLost();
}
2) Provide ConnectionLostCallback
in your BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver{
private ConnectionLostCallback listener;
public MyBroadcastReceiver(ConnectionLostCallback listener ){
this.listener = listener //<-- Initialze it
}
@Override
public void onReceive(Context context, Intent intent) {
listener.connectionLost();
}
}
3) Implement the ConnectionLostCallback
in your Activity and override the method
YourActvity extends AppcompatActivity implements ConnectionLostCallback{
// Your Activity related code //
// new MyBroadcastReceiver(this); <-- create instance
private void showAlertMessage(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
}
@Override
public void connectionLost(){
showAlertMessage(); //<--- Call the method to shoe alert dialog
}
}
Relevant link:
If you want to know how to make a BroadcastReceiver independent of any activity ie How can you reuse the same BroadCastReceiver with different Activities? Then READ THIS
回答4:
Pass your Activity's context to BroadcastReceiver's contructor.
public class ResponseReceiver extends BroadcastReceiver{
MainActivity ma; //a reference to activity's context
public ResponseReceiver(MainActivity maContext){
ma=maContext;
}
@Override
public void onReceive(Context context, Intent intent) {
ma.brCallback("your string"); //calling activity method
}
}
and in your MainActivity
public class MainActivity extends AppCompatActivity {
...
public void onStart(){
...
ResponseReceiver responseReceiver = new ResponseReceiver(this); //passing context
LocalBroadcastManager.getInstance(this).registerReceiver(responseReceiver,null);
...
}
public void brCallback(String param){
Log.d("BroadcastReceiver",param);
}
}
hope it helps
回答5:
Same as Vijju' s answer but using Local Broadcasts instead
public class SampleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent intentToBroadcast = new Intent("YOUR_ACTION_HERE");
LocalBroadcastManager.getInstance(context).sendBroadcast(intentToBroadcast);
}
}
In your activity add this
public class SampleActivity extends Activity {
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mSampleReceiver, new IntentFilter(YOUR_ACTION_HERE));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mSampleReceiver);
super.onPause();
}
private SampleReceiver mSampleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// your code here
}
};
}
Note Move the register/unregister calls to onCreate/onDestroy is you want to be notified even when your activity is in the background.
来源:https://stackoverflow.com/questions/22241705/calling-a-activity-method-from-broadcastreceiver-in-android