如何在片段中设置广播监听器接口?

时间:2016-03-13 13:18:02

标签: java android android-fragments broadcastreceiver intentservice

我有服务,它从API获取数据并将此数据发送到BroadcastReceiver类。另外,我创建了在Activity中使用的接口OnReceiveListener。看看这里的代码:

的活动:

public class StartActivity extends AppCompatActivity
    implements MyBroadcastReceiver.OnReceiveListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);

    MyBroadcastReceiver receiver = new MyBroadcastReceiver();
    receiver.setOnReceiveListener(this);
    LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
            new IntentFilter(MyBroadcastReceiver.START));
    ...
}

@Override
public void onReceive(Intent intent) {
    // Do smth here
}
}

MyBroadcastReceiver:

public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String START = "com.example.myapp.START";
public static final String GET_LINKS = "com.example.myapp.GET_LINKS";

private OnReceiveListener onReceiveListener = null;

public interface OnReceiveListener {
    void onReceive(Intent intent);
}

public void setOnReceiveListener(Context context) {
    this.onReceiveListener = (OnReceiveListener) context;
}

@Override
public void onReceive(Context context, Intent intent) {
    if(onReceiveListener != null) {
        onReceiveListener.onReceive(intent);
    }
}
}

服务对这个问题并不重要。

----问题----

那么,问题是什么:我想在片段中使用这个接收器,但是当它设置上下文时 - 我得到异常"启用强制转换"。我应该怎么做这个案子?

这是片段中的代码:

public class MainFragment extends Fragment
    implements MyBroadcastReceiver.OnReceiveListener {

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
    myBroadcastReceiver.setOnReceiveListener(getContext());
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
            new IntentFilter(MyBroadcastReceiver.GET_LINKS));
}

@Override
public void onReceive(Intent intent) {
    // Do smth here
}
}

3 个答案:

答案 0 :(得分:0)

您的MainFragment课程实现了OnReceiveListener界面,而不是Context返回的getContext()界面。不要将Context对象传递到setOnReceiveListener(),而是尝试直接传递OnReceiveListener实例。然后,您的片段和活动都可以调用setOnReceiveListener(this)

答案 1 :(得分:0)

您不需要动态注册接收器。我相信您必须使用<receiver>标记在清单中注册它。

这不是必需的:

  

LocalBroadcastManager.getInstance(的getContext())。registerReceiver(myBroadcastReceiver,               新的IntentFilter(MyBroadcastReceiver.GET_LINKS));

关于回调注册监听器,而不是使用getContext()使用MainFragment.this这样:

myBroadcastReceiver.setOnReceiveListener(MainFragment.this);

答案 2 :(得分:0)

在寻找合适的方法来实现此问题的解决方案数小时后,我终于找到了一种方法。它基于 RussHWolf 的回答。完整的代码解决方案如下:

通过这种方式,setListener() 方法被公开,以便 FragmentActivity 可以通过发送 IStatusChangeListener 的实例来设置侦听器。

public class StatusChangeReceiver extends BroadcastReceiver {
    private IStatusChangeListener listener;

    public void setListener(IStatusChangeListener listener) {
        this.listener = listener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (NetworkUtil.isNetworkConnected()) {
            listener.onConnected();
        } else {
            listener.onDisconnected();
        }
    }
}

这是界面:

public interface IStatusChangeListener {
    void onConnected(String status);
    void onDisonnected(String status);
}

现在,需要有一个 IStatusChangeListener 接口的实例,而不是实现 IStatusChangeListener 接口。然后,将此 IStatusChangeListener 实例传递给 setListener() 方法。

public class MainFragment extends Fragment { //Not implementing the interface

    private IStatusChangeListener listener = new IStatusChangeListener() {
        @Override
        void onConnected(String status) {
            //some log here
        }

        @Override
        void onDisonnected(String status) {
            //some log here
        }
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        StatusChangeReceiver r = new StatusChangeReceiver();
        r.setListener(listener); // pass the IStatusChangeListener instance
        LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
    }
}

注意:如果您从 LocalBroadcastManager 注册 BroadcastReceiver,请始终使用 Fragment