如何在没有onCreate()的情况下将数据从BroadcastReceiver传递给Activity

时间:2016-08-15 11:31:26

标签: android sockets broadcastreceiver android-broadcast

我有一个关于将数据从BroadcastReceiver传递到Activity的严重问题。让我们仔细看看我的问题。我有一个班级PhoneStateReceiver extends BroadcastReceiver曾经收到过来电。

public class PhoneStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            System.out.println("Receiver start");
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){

            }            
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

来电将发送至名为Activity的{​​{1}}。 ReceiverActivity接收传入的电话并通过套接字连接将其发送到服务器。套接字连接在ReceiverActivity函数中初始化。我用Google搜索并找到服务器方式将数据从onCreate传递到BroadcastReceiver。常见的方法是通过Activity函数发送数据并调用putExtra。但是,该方法将再次调用startActivity,然后连接套接字,再次绘制UI。因此,在我的情况下它没有帮助。

在我的目标中,如果手机接到来电,它会将来电发送到onCreateReceiverActivity接收消息并调用send函数。这是最好的方法吗?谢谢

将数据从ReceiverActivity传递到我使用的BroadcastReceiver的常用方法如下

PhoneStateReceiver 类中:

ReceiverActivity

ReceiverActivity 类中:

Intent intent_phonenum = new Intent(context, ReceiverActivity.class);
intent_phonenum.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent_phonenum.putExtra("phone_num", incomingNumber);
context.startActivity(intent_phonenum);

3 个答案:

答案 0 :(得分:5)

简单,没有任何第三方库。

确保BroadcastReceiver上必须注册OnPause()并取消注册。

你必须做两件事

在您的活动中注册接收器,如下所示。

public class MainActivity extends Activity {

    Context context;
    BroadcastReceiver updateUIReciver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        IntentFilter filter = new IntentFilter();
        filter.addAction("service.to.activity.transfer");
        updateUIReciver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //UI update here
                if (intent != null)
                    Toast.makeText(context, intent.getStringExtra("number").toString(), Toast.LENGTH_LONG).show();
            }
        };
        registerReceiver(updateUIReciver, filter);
    }
}

现在在你的服务中

public class PhoneStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            System.out.println("Receiver start");
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                Intent local = new Intent();
                local.setAction("service.to.activity.transfer");
                local.putExtra("number", incomingNumber);
                context.sendBroadcast(local);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

答案 1 :(得分:4)

您可以使用非常简单的设计模式来简化类之间的沟通,并解除代码:Me!tbBirthday.Value = DateValue(Me!cmbName.Column(3)) 。我最喜欢的库是publisher/subscriber

首先,添加到 build.gradle 文件中:

EventBus

然后,像这样创建一个简单的compile 'org.greenrobot:eventbus:3.0.0'

POJO - Plain Old Java Object

接下来,通过将public class OnReceiverEvent{ private String phoneNumber; public OnReceiverEvent(String phone){ this.phoneNumber = phone; } public String getPhoneNumber(){ return phoneNumber; } } 课程设为Receiver,将publisher设为Activity,您应该可以轻松地将信息传递给您的活动,如下所示:

subscriber

接下来,在您的活动中,只需执行以下操作:

//inside your PhoneStateReceiver class when you want to pass info

EventBus.getDefault().post(new OnReceiverEvent(phoneNumber));

最后,处理发布的数据,即phoneNumber值:

//onStart
@Override
public void onStart(){
   super.onStart();
   EventBus.getDefault().register(this);
}

//onStop
@Override
public void onStop(){
   super.onStop();

   EventBus.getDefault().unregister(this);
}

<强>更新

如果您希望此活动订阅另一个事件,只需使用@Subscribe public void onPhoneNumberReceived(OnReceiverEvent event){ //get the phone number value here and do something with it String phoneNumber = event.getPhoneNumber(); //display or something? } 注释创建第一个方法。

@Subscribe

这是将数据从接收器传递到活动的最简单方法,而不必担心反复启动活动!

我希望这有帮助并祝你好运!

答案 2 :(得分:1)

所以我知道你不想每次都重新创建你的活动。

Intent更改此标记会对您有所帮助:

intent_phonenum.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

如果您阅读FLAG_ACTIVITY_CLEAR_TOP的方法摘要:

,请在Intent类中
  
      
  • 如果设置,则正在启动的活动已在
  • 中运行   
  • 当前任务,然后不是启动该活动的新实例,
  •   
  • 其上的所有其他活动都将被关闭,此意图
  •   
  • 将作为新的Intent传递到(现在在顶部)旧活动。 (你可以阅读更多......)
  •   

在这种情况下:如果您的应用正在运行并且您有一个Activity实例,那么Intent将无法重新创建您的活动。但假设您的应用处于关闭状态,并且当BroadcastReceiver触发时,Intent将创建新的活动,因为您没有该活动的实例。

@Edit:

您可以在BroadcastReceiver

中指定类似的特殊意图
public void onReceive(Context context, Intent intent) {
  Bundle extras = intent.getExtras();
  Intent i = new Intent("mycustombroadcast");
  i.putExtra("phone_num", incomingNumber); 
  context.sendBroadcast(i);
}

然后在你的onCreate()内的活动注册接收器中:

 BroadcastReceiver broadcastReceiver =  new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        Bundle bundle = intent.getExtras();

        int incoming_number= bundle.getInt("phone_num");

        Log.e("incoming number", "" + incoming_number);
    }
};
//then register receiver like that :
registerReceiver(broadcastReceiver, new IntentFilter("mycustombroadcast"));

您可以在onDestroy()中取消注册Receiver:unregisterReceiver(broadcastReceiver);

另一种方法是覆盖您的活动中的onNewIntent()

@Override
protected void onNewIntent(Intent intent) {
 //your intent is here, you can do sth.
 super.onNewIntent(intent);
}