我在这里创建一个仅依赖互联网的在线应用程序。
因此,每当出现网络错误时,都必须通知用户。为此,我创建了一个BroadcastReciver,它在网络连接丢失时接收呼叫(Internet)。
这一切都很完美。现在我需要的是我必须从这个广播接收器调用一个Activity方法,在那里我创建了一个警告对话。
我在stack-overflow.com上读了很多答案,我可以声明该方法是静态的,只使用Activity名称调用,
例如MyActivityName.myMethod()
但我不能声明我的方法是静态的,因为我在那里使用Alert Dialogue并且它在线显示错误,
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
无法在静态环境中使用。
那么,如何从广播接收器调用Activity方法(必须不是静态且不启动该活动)?
我可以从当前正在运行的Broadcast Receiver获取Activity(或片段)名称吗?
答案 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)
您可以建立CallBackListener接口。该接口将充当BroadcastReceiver
和Activity
之间的桥梁。
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变得很冗长,也许很难遵循。