如何更新BroadcastReceiver中的用户界面

我创build了一个应用程序,在我的主类( Main Activity )中注册了一个广播接收器,并且每当我收到我的BroadcastReceiver某些内容时,我想要更新用户界面,例如我想显示一个警告框或设置我的MainActivity文本视图。 我收到我的接收器中的所有值,但无法设置它们,有人可以帮助我,这样我就可以在BroadcastReceiver更新我的UI。

我的BroadcastReceiver类是这样的MainActivity的内部类: –

 public class MainActivity extends Activity { .......... public static class NissanTabBroadcast extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { SharedPreferences shrd = context.getSharedPreferences("NissanGallery", context.MODE_WORLD_READABLE); type = shrd.getString("type", "null"); badges = shrd.getString("badge_count", "null"); //badge_tips_text.setText(badges); /*Editor edit = shrd.edit(); edit.remove("type");*/ Toast.makeText(context, "" + type + "\n" + badge_tips_text.getText().toString(), Toast.LENGTH_LONG).show(); } } } 

任何帮助将是可观的

谢谢

我build议你使用Handler。

  1. 初始化Activity中的Handler,例如: handler = new Handler()
  2. 在构造函数中为BroadcastReceiver提供处理程序,就像我为上面的NissanTabBroadcast一样
  3. onReceive()方法中使用Handler实例的post()方法来提交更新UI的Runnable

这是我能想象到的最干净的解决scheme。

 public class MainActivity extends Activity { private MyReceiver receiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); receiver = new MyReceiver(new Handler()); // Create the receiver registerReceiver(receiver, new IntentFilter("some.action")); // Register receiver sendBroadcast(new Intent("some.action")); // Send an example Intent } public static class MyReceiver extends BroadcastReceiver { private final Handler handler; // Handler used to execute code on the UI thread public MyReceiver(Handler handler) { this.handler = handler; } @Override public void onReceive(final Context context, Intent intent) { // Post the UI updating code to our Handler handler.post(new Runnable() { @Override public void run() { Toast.makeText(context, "Toast from broadcast receiver", Toast.LENGTH_SHORT).show(); } }); } } } 

使用runOnUiThread

  MainActivity.this.runOnUiThread(new Runnable() { @Override public void run() { // show alert } }); 

我的情况是更新由MainActivity托pipe的一个片段中的文本字段。我发现最简单的解决scheme是:

在我的MainActivity类中检索MainActivtiy的运行实例。这是我的MAinActivity

 private static MainActivity mainActivityRunningInstance; public static MainActivity getInstace(){ return mainActivityRunningInstance; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mainActivityRunningInstance =this; ---------- } 

现在在Broadcast reciever的onRecieve方法中,获取该实例并调用更新方法

  @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().matches(Intents.PROVIDER_CHANGED_ACTION)) { String textValue="the text field value"; // the null check is for, if the activity is not running or in paused state, in my case the update was required onlyif the main activity is active or paused if(MainActivity.getInstace()!=null) MainActivity.getInstace().updateUI(textValue); } 

现在,我们需要在UIThread中运行更新的部分,MainActivity的updateUI方法将调用片段更新方法。

  public void updateUI(final String str) { MainActivity.this.runOnUiThread(new Runnable() { public void run() { //use findFragmentById for fragments defined in XML ((SimpleFragment)getSupportFragmentManager().findFragmentByTag(fragmentTag)).updateUI(str); } }); } 

最后一步是更新片段的文本字段

 public void updateUI(String str){ tv_content.setText(str); } 

和宾果,它做到了。 我提到这个链接来解决我的问题。 希望它能帮助别人。

我使用Intent让Broadcast Receiver知道主Activity活动线程的Handler实例,并使用Message将消息传递给Main活动

我已经使用这种机制来检查广播接收器是否已经注册。 有时,当您dynamic注册广播接收器时,如果广播接收器正在运行,则不需要进行两次或者向用户展示广播接收器。

主要活动:

 public class Example extends Activity { private BroadCastReceiver_example br_exemple; final Messenger mMessenger = new Messenger(new IncomingHandler()); private boolean running = false; static class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { running = false; switch (msg.what) { case BroadCastReceiver_example.ALIVE: running = true; .... break; default: super.handleMessage(msg); } } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); IntentFilter filter = new IntentFilter(); filter.addAction("pl.example.CHECK_RECEIVER"); br_exemple = new BroadCastReceiver_example(); getApplicationContext().registerReceiver(br_exemple , filter); //register the Receiver } // call it whenever you want to check if Broadcast Receiver is running. private void check_broadcastRunning() { /** * checkBroadcastHandler - the handler will start runnable which will check if Broadcast Receiver is running */ Handler checkBroadcastHandler = null; /** * checkBroadcastRunnable - the runnable which will check if Broadcast Receiver is running */ Runnable checkBroadcastRunnable = null; Intent checkBroadCastState = new Intent(); checkBroadCastState .setAction("pl.example.CHECK_RECEIVER"); checkBroadCastState .putExtra("mainView", mMessenger); this.sendBroadcast(checkBroadCastState ); Log.d(TAG,"check if broadcast is running"); checkBroadcastHandler = new Handler(); checkBroadcastRunnable = new Runnable(){ public void run(){ if (running == true) { Log.d(TAG,"broadcast is running"); } else { Log.d(TAG,"broadcast is not running"); } } }; checkBroadcastHandler.postDelayed(checkBroadcastRunnable,100); return; } ............. } 

广播接收机:

 public class BroadCastReceiver_example extends BroadcastReceiver { public static final int ALIVE = 1; @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Bundle extras = intent.getExtras(); String action = intent.getAction(); if (action.equals("pl.example.CHECK_RECEIVER")) { Log.d(TAG, "Received broadcast live checker"); Messenger mainAppMessanger = (Messenger) extras.get("mainView"); try { mainAppMessanger.send(Message.obtain(null, ALIVE)); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ......... } } 

我正在使用完全不同的方法。通过处理器的实例来广播接收者的意图。在广播接收器使用该处理程序发送消息给你的活动类更新您的自定义处理程序的onHandleMessage方法中的用户界面类。

 create handler class like public class MyHandler extends Handler{ onHandlerMessage(Message msg){//do whatever you want here after broadcast get fired} } 

现在使用Myhandler handler=new MyHandler(); 在活动中的全局级别范围上创build此处理程序对象。

现在把这个处理程序放入你的意图通过putExtra ,然后发送这个意图通过sendBraodcast(intent)

在广播接收器类中,通过getExtras获取这个处理器对象,并像下面的onReceive()方法一样使用它

  handler.sendEmptyMessage(); 

在我的情况下,我想用传入的短信更新我的活动中的文本视图,我所做的是使用putextra添加了所需的信息,然后从广播接收器启动了活动:

 Intent intentone = new Intent(context.getApplicationContext(), enroll.class); intentone.putExtra("pinbody",message); intentone.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intentone); 

然后在接收端,即在报名活动中,我使用下面的和更新的文本视图提取了这些信息:

 Bundle extras = getIntent().getExtras(); String message = extras.getString("pinbody"); 

不知道是否有帮助,但肯定会引导你到你想要的。

干杯!

我用Handler&它的post()方法。 而不是runOnUiThread()。 无需将上下文投射到活动。 它是runOnUiThread()的替代方法

 Handler handler = new Handler(); Runnable runnable = new Runnable() { private long startTime = System.currentTimeMillis(); public void run() { while (gameState == GameState.Playing) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } handler.post(new Runnable(){ public void run() { tvTime.setText("" + ((System.currentTimeMillis() - this.startTime) / 1000)); } }); } } }; new Thread(runnable).start(); 

你应该使广播接收器作为内部类,这样它将有权访问所有字段来更新UI。

看到这个格子应用程序由尼克屠夫格子 – 尼克·布彻(Github)

使用getters和setter可以轻松解决这个问题。

只需要声明一个类如下。

 public class DetailsGetters { private View view; public View getview() { return view; } public void setview(View view) { this.view = view; } } 

在您的主要活动或片段活动上,创build类DetailsGetters的一个实例。

 DetailsGetters newdetailsinstance=new DetailsGetters(); 

newdetailsinstance.setview(view);视图调用之前newdetailsinstance.setview(view);

在广播接收机上获取视图为newdetailsinstance.getview(view);

follwing可以用来从片段中获取视图,并使用setText等来更新Ui。

为了更新主要活动的UI,传递Textview并更改DeailsGetters类,并为Textview创buildgetter和setter。 希望这有助于某人。