web-dev-qa-db-ja.com

AndroidでBroadcastReceiverからActivityメソッドを呼び出す

ここでは、インターネットのみに依存するオンラインアプリケーションを作成しています。

そのため、ネットワークエラーが発生するたびに、ユーザーに通知する必要があります。そのために、ネットワーク接続が失われたときにコールを受信するBroadcastReciver(インターネット)を作成しました。

これはすべて完全に機能します。ここで必要なのは、アラートダイアログを作成したこのブロードキャストレシーバーからアクティビティのメソッドを呼び出す必要があることです。

Stack-overflow.comで多くの回答を読んでおり、そのメソッドを静的と宣言し、アクティビティ名のみを使用して呼び出すことができます。

例:MyActivityName.myMethod()

ただし、メソッドを静的に宣言することはできません。アラートダイアログを使用しており、オンラインでエラーが表示されるためです。

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

that 静的コンテキストではこれを使用できません

だから、どのようにブロードキャストレシーバからアクティビティのメソッドを呼び出すことができますか(静的ではなく、そのアクティビティを開始しないでください)?

また、現在実行中のBroadcast ReceiverからActivity(またはフラグメント)名を取得できますか?

29
Jay Vyas

このコードを試してください:

インターネットの失われたクラスのブロードキャスト受信者クラス:

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

アラートダイアログを開いている場所からアクティビティにブール変数を追加します

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

インターフェース: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を異なるアクティビティでどのように再利用できますか?次に これを読む

1
Rohit Singh

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に移動すると、アクティビティがバックグラウンドにある場合でも通知を受けることができます。

0
Adeel Ahmad

アクティビティのコンテキストを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);
    }
}

それが役に立てば幸い

0
junhaotee