如何在不使用 onCreate() 的情况下将数据从 BroadcastReceiver 传递到 Activity
How to pass data from BroadcastReceiver to Activity without in onCreate()
我在将数据从 BroadcastReceiver
传递到 Activity
时遇到了严重的问题。让我仔细看看我的问题。我有一个 class PhoneStateReceiver extends BroadcastReceiver
用来接收传入的 phone。
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();
}
}
}
传入的 phone 将被发送到名为 ReceiverActivity
的 Activity
。 ReceiverActivity
接收传入的 phone 并通过套接字连接将其发送到服务器。套接字连接在onCreate
函数中初始化。我用谷歌搜索并找到了将数据从 BroadcastReceiver
传递到 Activity
的服务器方式。常见的方式是通过putExtra
函数发送数据并调用startActivity
。但是,该方式将再次调用onCreate
,然后连接套接字,再次绘制UI。因此,这对我的情况没有帮助。
在我的目标中,如果 phone 收到来电,它将把来电发送到 ReceiverActivity
。 ReceiverActivity
接收消息并调用发送函数。哪种方法最好?谢谢
将数据从 BroadcastReceiver
传递到 ReceiverActivity
的常用方法如下
在 PhoneStateReceiver class 中:
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);
在ReceiverActivity中class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect_socket();
Intent intent = getIntent();
phone_num = intent.getStringExtra("phone_num");
send(phone_num);
}
所以我知道你不想每次都重新创建你的 Activity。
在您的 Intent
中更改此标志将帮助您 :
intent_phonenum.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
In Intent class 如果您阅读 FLAG_ACTIVITY_CLEAR_TOP
的方法摘要:
- If set, and the activity being launched is already running in the
- current task, then instead of launching a new instance of that activity,
- all of the other activities on top of it will be closed and this Intent
- will be delivered to the (now on top) old activity as a new Intent. (you can read more ...)
在这种情况下:如果您的应用是 运行 并且您有一个 Activity 实例,那么 Intent
将不会重新创建您的 Activity。但是假设您的应用程序处于关闭状态并且当 BroadcastReceiver 被触发时,Intent
将创建新的 Activity 因为您没有那个 Activity.
的实例
@编辑:
您可以在 BroadcastReceiver
:
中指定特殊的 Intent
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
Intent i = new Intent("mycustombroadcast");
i.putExtra("phone_num", incomingNumber);
context.sendBroadcast(i);
}
然后在你的 Activity 里面 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);
另一种方法是覆盖 Activity 中的 onNewIntent()
:
@Override
protected void onNewIntent(Intent intent) {
//your intent is here, you can do sth.
super.onNewIntent(intent);
}
您可以在此处使用一个非常简单的设计模式来简化 class 之间的通信并解耦代码:publisher/subscriber
。我最喜欢的图书馆是 EventBus
:
首先,添加到您的 build.gradle 文件:
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
class变成publisher
,你的Activity
变成subscriber
,你应该可以轻松传递信息给你的 activity 这样的:
//inside your PhoneStateReceiver class when you want to pass info
EventBus.getDefault().post(new OnReceiverEvent(phoneNumber));
接下来,在您的 activity 中,只需执行以下操作:
//onStart
@Override
public void onStart(){
super.onStart();
EventBus.getDefault().register(this);
}
//onStop
@Override
public void onStop(){
super.onStop();
EventBus.getDefault().unregister(this);
}
最后,处理发布的数据,即 phoneNumber 值:
@Subscribe
public void onPhoneNumberReceived(OnReceiverEvent event){
//get the phone number value here and do something with it
String phoneNumber = event.getPhoneNumber();
//display or something?
}
更新
如果您有另一个 Event 希望此 activity 订阅,只需创建一个方法,就像您在第一个方法中所做的那样,使用 @Subscribe
注释。
@Subscribe
public void onSomeOtherEvent(EventClassName event){
//get the variables here as usual;
}
这是将数据从接收器传递到 activity 的最简单方法,无需担心一遍又一遍地启动 activity!
希望对您有所帮助,祝您好运!
简单,没有任何第三方库。
确保 BroadcastReceiver
必须在 OnPause()
上注册并取消注册。
你必须做两件事
像下面那样在您activity中注册一个接收器。
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();
}
}
}
我在将数据从 BroadcastReceiver
传递到 Activity
时遇到了严重的问题。让我仔细看看我的问题。我有一个 class PhoneStateReceiver extends BroadcastReceiver
用来接收传入的 phone。
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();
}
}
}
传入的 phone 将被发送到名为 ReceiverActivity
的 Activity
。 ReceiverActivity
接收传入的 phone 并通过套接字连接将其发送到服务器。套接字连接在onCreate
函数中初始化。我用谷歌搜索并找到了将数据从 BroadcastReceiver
传递到 Activity
的服务器方式。常见的方式是通过putExtra
函数发送数据并调用startActivity
。但是,该方式将再次调用onCreate
,然后连接套接字,再次绘制UI。因此,这对我的情况没有帮助。
在我的目标中,如果 phone 收到来电,它将把来电发送到 ReceiverActivity
。 ReceiverActivity
接收消息并调用发送函数。哪种方法最好?谢谢
将数据从 BroadcastReceiver
传递到 ReceiverActivity
的常用方法如下
在 PhoneStateReceiver class 中:
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);
在ReceiverActivity中class:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connect_socket();
Intent intent = getIntent();
phone_num = intent.getStringExtra("phone_num");
send(phone_num);
}
所以我知道你不想每次都重新创建你的 Activity。
在您的 Intent
中更改此标志将帮助您 :
intent_phonenum.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
In Intent class 如果您阅读 FLAG_ACTIVITY_CLEAR_TOP
的方法摘要:
- If set, and the activity being launched is already running in the
- current task, then instead of launching a new instance of that activity,
- all of the other activities on top of it will be closed and this Intent
- will be delivered to the (now on top) old activity as a new Intent. (you can read more ...)
在这种情况下:如果您的应用是 运行 并且您有一个 Activity 实例,那么 Intent
将不会重新创建您的 Activity。但是假设您的应用程序处于关闭状态并且当 BroadcastReceiver 被触发时,Intent
将创建新的 Activity 因为您没有那个 Activity.
@编辑:
您可以在 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);
}
然后在你的 Activity 里面 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);
另一种方法是覆盖 Activity 中的 onNewIntent()
:
@Override
protected void onNewIntent(Intent intent) {
//your intent is here, you can do sth.
super.onNewIntent(intent);
}
您可以在此处使用一个非常简单的设计模式来简化 class 之间的通信并解耦代码:publisher/subscriber
。我最喜欢的图书馆是 EventBus
:
首先,添加到您的 build.gradle 文件:
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
class变成publisher
,你的Activity
变成subscriber
,你应该可以轻松传递信息给你的 activity 这样的:
//inside your PhoneStateReceiver class when you want to pass info
EventBus.getDefault().post(new OnReceiverEvent(phoneNumber));
接下来,在您的 activity 中,只需执行以下操作:
//onStart
@Override
public void onStart(){
super.onStart();
EventBus.getDefault().register(this);
}
//onStop
@Override
public void onStop(){
super.onStop();
EventBus.getDefault().unregister(this);
}
最后,处理发布的数据,即 phoneNumber 值:
@Subscribe
public void onPhoneNumberReceived(OnReceiverEvent event){
//get the phone number value here and do something with it
String phoneNumber = event.getPhoneNumber();
//display or something?
}
更新
如果您有另一个 Event 希望此 activity 订阅,只需创建一个方法,就像您在第一个方法中所做的那样,使用 @Subscribe
注释。
@Subscribe
public void onSomeOtherEvent(EventClassName event){
//get the variables here as usual;
}
这是将数据从接收器传递到 activity 的最简单方法,无需担心一遍又一遍地启动 activity!
希望对您有所帮助,祝您好运!
简单,没有任何第三方库。
确保 BroadcastReceiver
必须在 OnPause()
上注册并取消注册。
你必须做两件事
像下面那样在您activity中注册一个接收器。
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();
}
}
}