我有一个关于将数据从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。因此,在我的情况下它没有帮助。
在我的目标中,如果手机接到来电,它会将来电发送到onCreate
。 ReceiverActivity
接收消息并调用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);
答案 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传递到(现在在顶部)旧活动。 (你可以阅读更多......)
在这种情况下:如果您的应用正在运行并且您有一个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);
}