今天学习了下android的BroadcastReceiver的两种实现方式(1.配置文件注册和后台程序注册方式)。

学习的目标:会用两种方式实现广播接收器,发送广播,两者区别及android里面一个让我很郁闷的情况,哪个线程创建的UI组件只能由哪个线程来操作。


下面是代码

/**
* 入口
*/
public class MainActivity extends Activity {
   //这里的activity_main.xml就不贴出来了,就是一堆button
   Button sendButtonId;
   Button sendButton2Id;
   Button registerReciver;
   Button deleteReciver;
   TextView textView = null;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       sendButtonId = (Button) findViewById(R.id.sendButtonId);
       registerReciver = (Button) findViewById(R.id.registerReciver);
       deleteReciver = (Button) findViewById(R.id.deleteReciver);
       sendButton2Id = (Button) findViewById(R.id.sendButton2Id);
       sendButtonId.setOnClickListener(licen);
       sendButton2Id.setOnClickListener(licen);
       registerReciver.setOnClickListener(licen);
       deleteReciver.setOnClickListener(licen);
       textView = (TextView)findViewById(R.id.textViewId);
   }

   OnClickListener licen = new OnClickListener() {
       @Override
       public void onClick(View view) {
           switch (view.getId()) {
           case R.id.sendButtonId:
               sendReciver();
               break;
           case R.id.sendButton2Id:
               sendReciver2();
               break;
           case R.id.registerReciver:
               registerReciver();
               break;
           case R.id.deleteReciver:
               deleteReciver();
               break;
           }}};

   /**
    * 发送自定义广播android.test.reciver
    */
   private void sendReciver() {
       Intent i = new Intent("android.test.reciver");
       sendBroadcast(i);
   }
   /**
    * 发送自定义广播android.test.reciver2.register
    */
   private void sendReciver2() {
       Intent i = new Intent("android.test.reciver2.register");
       sendBroadcast(i);
   }
   /**
    * 注册广播接收器,这种程序注册方式会随着应用的关闭而关闭
    */
   BroadCaseRecTest dateReceiver ;
   private void registerReciver() {
       dateReceiver = new BroadCaseRecTest();
       IntentFilter filter = new IntentFilter();
       filter.addAction("android.test.reciver2.register");
       MainActivity.this.registerReceiver(dateReceiver, filter);
   }
   /**
    * 销毁广播接收器
    */
   private void deleteReciver() {
       MainActivity.this.unregisterReceiver(dateReceiver);
       /*Thread1Test thread1 = new Thread1Test(this);
       Thread thread = new Thread(thread1);
       thread.start();这里开启线程去更新textView,但实际是会报错的*/
   }
   //更新textView方法
   public void setTextsd(String hello) {
       textView.setText(hello);
   }
}

在AndroidManifest.xml里配置第一种方式

           android:name="com.br.broadcastreceiver.DefineBroadcastReceiver">
           
               
           


       

第一个接收器

/**
* 接收器的实现有两种方法
* (1)在AndroidManifest.xml文件里注册,这种方法在应用程序关闭后接收器依然在运行
* (2)通过程序代码register方法创建接收器,这种方式的接收器随着程序的关闭而关闭
* 这里定义的是为第一种情况服务的广播接收器类
* 功能:将广播内容放入Notification里
* 点击Notification内容后Notification消失
* 跳转到一个NotificationActivity
*/
public class DefineBroadcastReceiver extends BroadcastReceiver {
   @SuppressWarnings("deprecation")
   @Override
   public void onReceive(Context context, Intent arg1) {
       // TODO Auto-generated method stub
       PendingIntent pending = PendingIntent.getActivity(context, 0, new Intent(
               context, NotificationActivity.class), 0);

       Notification noticed = new Notification();
       noticed.icon = R.drawable.u68_normal;
       noticed.tickerText = "状态栏通知";
       noticed.defaults = Notification.DEFAULT_SOUND;
       noticed.setLatestEventInfo(context, "这是一个状态栏通知", "查看",pending);

       NotificationManager noticedManager = (NotificationManager)
               context.getSystemService(context.NOTIFICATION_SERVICE);
       noticed.flags|=Notification.FLAG_AUTO_CANCEL;
       noticedManager.notify(1, noticed);
   }

}

第二个接收器

/**
* 自定义一个广播接收器接收register类型的广播
* 并将广播内容放入Notification里
* 点击Notification内容后Notification消失
* 跳转到一个NotificationActivity
*/
public class BroadCaseRecTest extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
           PendingIntent pending = PendingIntent.getActivity(context, 0, new Intent(
                   context, NotificationActivity.class), 0);
               Notification noticed = new Notification();
               noticed.icon = R.drawable.u68_normal;
               noticed.tickerText = "状态栏通知";
               noticed.defaults = Notification.DEFAULT_SOUND;
               noticed.setLatestEventInfo(context, "我是一个后台注册的reciver", "查看",pending);

               NotificationManager noticedManager = (NotificationManager)
                       context.getSystemService(context.NOTIFICATION_SERVICE);
               noticed.flags|=Notification.FLAG_AUTO_CANCEL;
               noticedManager.notify(1, noticed);

   }
}

一个线程类

/**
*这里是想在这个现场里更新TextView,但结果是不可行的。
*因为android规定所有UI组件必须只能由创建这个组件的线程操作。
*/
public class Thread1Test implements Runnable {
   MainActivity activity;
   public Thread1Test(MainActivity activity) {
       this.activity = activity;
   }
   @Override
   public void run() {
       int a=0;
       while(true) {
           if(a<20) {
               /**
                * 这里会报错,是因为android规定所有UI组件必须只能由创建这个组件的线程操作。
                * 所以这里会报错(因为他是在另外一个线程里去操作了)虽然这个activity是创建TextView的对象,但并不是创建它的线程
                * 如果非要在另一个线程里改变组件就需要用到SurfaceView 这里不做介绍了
                */
               activity.setTextsd(a+"");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {}
           } else {
               break;
           }}}}