从Android中的BroadcastReceiver调用Activity方法

时间:2014-03-07 04:49:10

标签: android methods android-activity broadcastreceiver static-methods

我在这里创建一个仅依赖互联网的在线应用程序。

因此,每当出现网络错误时,都必须通知用户。为此,我创建了一个BroadcastReciver,它在网络连接丢失时接收呼叫(Internet)。

这一切都很完美。现在我需要的是我必须从这个广播接收器调用一个Activity方法,在那里我创建了一个警告对话。

我在stack-overflow.com上读了很多答案,我可以声明该方法是静态的,只使用Activity名称调用,

例如MyActivityName.myMethod()

但我不能声明我的方法是静态的,因为我在那里使用Alert Dialogue并且它在线显示错误,

AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

无法在静态环境中使用

那么,如何从广播接收器调用Activity方法(必须不是静态且不启动该活动)?

我可以从当前正在运行的Broadcast Receiver获取Activity(或片段)名称吗?

6 个答案:

答案 0 :(得分:64)

试试这段代码:

你的广播接收者上课失败的课程:

public class InternetLostReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
    context.sendBroadcast(new Intent("INTERNET_LOST"));
}
}

在您的活动中为呼叫广播添加此内容:

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);
}
}

答案 1 :(得分:4)

在您打开alertdialog

的活动中添加一个布尔变量
boolean isDialogOpened = false;

// in broadcast recever check 
if(isDialogOpened) {
    alertDialog();
}

用这个替换你的alertdialog代码

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();
}

答案 2 :(得分:1)

界面:将BroadCastReceiver和活动代码分开!

您可以建立CallBackListener接口。该接口将充当BroadcastReceiverActivity之间的桥梁。

1)创建一个CallbackListener

interface ConnectionLostCallback{

      public void connectionLost();

} 

2)在您的BroadcastReceiver中提供ConnectionLostCallback

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)在“活动”中实施ConnectionLostCallback,并覆盖方法

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

    }


}

相关链接:

  

如果您想知道如何使BroadcastReceiver独立于任何   活动,即如何与以下对象一起使用相同的BroadCastReceiver   不同的活动?然后READ THIS

答案 3 :(得分:0)

将您的活动上下文传递给BroadcastReceiver的构造函数。

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
    }

}

并在您的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);
    }
}

希望有所帮助

答案 4 :(得分:0)

与Vijju的答案相同,但改为使用本地广播

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);
    }
}

在您的活动中添加此

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
        }
    };
}

注意,即使您的活动处于后台,也希望收到通知时将注册/取消注册调用移至onCreate / onDestroy。

答案 5 :(得分:0)

使用 lambdas Consumer可以。

protected void onCreate(Bundle savedInstanceState) {
    ...

    receiver = new LocationBroadcastReceiver((whatever) -> doSomething(whatever));
    registerReceiver(receiver, new IntentFilter("YOUR_MESSAGE"));
}

在{strong>活动中,doSomething是一种方法。

...

class YourBroadcastReceiver extends BroadcastReceiver {

    private Consumer<Whatever> callback;

    public LocationBroadcastReceiver(Consumer<Whatever> callback) {
        this.callback = callback;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onReceive(Context context, Intent intent) {
            
        this.callback.accept(new Whatever());
    }
}

是其他所有替代品:

声明该方法为静态方法,并仅使用活动名称进行调用。

除了您的解释之外,这是一种耦合方式。

将您活动的上下文传递给BroadcastReceiver的构造函数。

那是行不通的,因为您要调用不属于AppCompatActivity的方法。是的,您可能会灰头土脸,但最终您会与自己的活动联系在一起。

改为使用其他广播或本地广播

那么,您只能以这种方式传递一堆原语。如果要传递对象怎么办?另外,声明一个新的BroadcastReceiver变得很冗长,也许很难遵循。