简体   繁体   中英

Pass data from broadcast receiver to activity

I have a broadcast receiver which is listening to the WifiManager.SCAN_RESULTS_AVAILABLE_ACTION. In that receiver I filter all the available networks and return a list of networks with a specific SSID. I nned to pass that list back to the MainActivity of my application. I know I can create an inner class for my Broadcast receiver but I prefer to create a separate class for better organization.

I am thinking in creating a static variable in my mainActivity class and then set that value. Is this a good practice?

A good way of sharing and access information a cross of Activites and other classes is by using the application object. You can access the application object from all your classes as long as you have the application context.

See this tutorial about application object: How to use application object

Usage from activities:

MyApplicationObject app = (MyApplicationOjbject)getApplicationContext();

app.setMyVariable(variable);

From other classes outside activity :

MyApplicationObject app = (MyApplicationOjbject)context.getApplicationContext();
app.setMyVariable(variable);

Stefan is right, this static link is not pretty. You can sometimes have multiple instance of the same activity (when recreated, until Garbage collector collect it). Or multiple broadcast happening, overwriting your static variable value.

If you don't want to use an anonymous inner class, you can override the constructor and pass a reference to your current activity that you will be able to use to send the results when processing onReceive() . Just clean up this reference when you are done to avoid leaking your activity.

I've used the same technique with success. The one time this bit me was when I did not consider that the user could tilt the screen and the activity would be recreated. I failed to check if the static variable was already set and replaced it repeatedly. Watch out for that.

One more technique I can think of is to share a callback between the activity and the broadcast receiver. The receiver makes a call to the callback which stores a reference to the right activity and calls runOnUiThread(action) to make UI updates. References should be updated onStart() and onStop(). I've never really used this pattern. Thought about it in the shower :)

I recommend to not use a static variable to deliver the information. If your main activity is the only object receiving the information from the receiver make the BroadcastReceiver local to the main activity. Doing so groups those elements which share a responsibility.

if ur launching an Main activity form the receiver and then u can pass the list in by using putextra(), and then you can get that in the main activity.

some thing like this.

Intent intent = new Intent(ctx.getApplicationContext(), targetActivity); intent.putCharSequenceArrayListExtra(name, value);

This is how I get data from broadcasts, little bit of more code but its way simpler to read for future, in case of complex stuff get going.

Intent intent = new Intent(context, BroadcastReciever.class);
SimpleResultReciever resultReciever = new SimpleResultReciever(new Handler())
         .setCallback(new OnLocationCallback() {
             @Override
             public void onRecieverLocation(Location location) {
                  if(location != null) {
                        MainActivity.this.location = location;
                   }
             }
         });
intent.putExtra(SimpleResultReciever.KEY_RESULT_RECIEVER, resultReciever);
//call intent or create pending intent you will use broadcast stuff.


public class SimpleResultReciever extends ResultReceiver {

    public final static String KEY_RESULT_RECIEVER = "bundle.broadcast.reciever.callback";

    private OnLocationCallback callback;

    public LocationResultReciever setCallback(OnLocationCallback callback) {
        this.callback = callback;
        return this;
    }

    /**
     * Create a new ResultReceive to receive results.  Your
     * {@link #onReceiveResult} method will be called from the thread running
     * <var>handler</var> if given, or from an arbitrary thread if null.
     *
     * @param handler
     */
    public LocationResultReciever(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        Location location = resultData.getParcelable(LocationManager.KEY_LOCATION_CHANGED);
        if(callback != null) {
            callback.onRecieverLocation(location);
        }
    }
}



public class LocationBroadcastReciever extends BroadcastReceiver {

    public LocationBroadcastReciever() {
        super();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle extra = intent.getExtras();
        Location location = extra.getParcelable(LocationManager.KEY_LOCATION_CHANGED);
        ResultReceiver res = extra.getParcelable(LocationResultReciever.KEY_RESULT_RECIEVER);
        if(res != null) {
            Bundle data = new Bundle();
            data.putParcelable(LocationManager.KEY_LOCATION_CHANGED, location);
            res.send(Activity.RESULT_OK, data);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM