首页 > 代码库 > 安卓下载功能中的广播接收器

安卓下载功能中的广播接收器

公司项目中要使用webview下载程序,所以必须用到广播接收器,配合service下载。

忘记的东西重来一遍。

后面有最经典的音乐播放器的源码,Service  BroadCastReeiver都用到了


简单4步,动态加载广播

1.定义一个广播接收器

public class MyReceiver extends BroadcastReceiver

{

         public MyReceiver()

         {

                   Log.i(TAG,"MyReceiver");

         }

        

         //可用IntentgetAction()区分接收到的不同广播

         @Override

         public void onReceive(Context arg0, Intent arg1)

         {

                   String action=intent.getAction();

                   //TO-DO LIST

         }

 

}

 

2.发送广播,定义好action标志,用Intent发送

 

//实例化该BroadcastReceiver

MyReceiver mReceiver=new MyReceiver();

//设置唯一action,用Intent发送

Intent intent=new Intent();

intent.setAction(str);

sendBroadcast(intent);

 

3.注册只接收指定action的广播接收器

IntentFilter filter1=new IntentFilter();

filter1.addAction(str);

registerReceiver(mReceiver,filter1);

 

4.取消该广播接收器

unregisterReceiver(mReceiver);



1.广播的定义

广播接收程序是android四大组件之一,可对客户端发出的广播消息作出响应的组件,消息本身是一个intent,可由多个接收程序接收

2.注册方式

a.动态注册,即通过程序注册(Context.registerReceiver()),程序退出后广播即实效

b.静态注册,即在manifest.xml中通过receiver tag注册,可作为全局广播

注意:对于动态注册,如果不执行Context.unregisterReceiver,也可作为全局广播,通常,在项目中,一般把注册放在Activity.onResume方法中,把取注册放在Activity.onPause中

3.发送广播

广播有两种接收方式

a.普通广播(Context.sendBroadcast)

完全异步的,所有的广播接收者在同一时刻以未定义的顺序运行。

b.顺序广播(Context.sendOrderedBroadcast)

所有的广播接收者按顺序执行,其中一个执行的广播接受者可以将结果传递给下一个广播接受者,也可以退出广播以便于不将结果传递到下一个广播接受者,可以在manifest.xml中使用android:priority属性来确定广播接收者的优先级。同一优先级的接受者将以随机顺序执行

二、广播高级话题

1.安全性

a.确保Intent的Action名称是你自己应用的命名空间,否则你会在不经意间和其他应用冲突

b.当你使用 registerReceiver(BroadcastReceiver, IntentFilter)时,其他应用也能够发送相关广播到那个注册的接收者中,这时你应  该使用相关权限来控制谁能够发送广播到那个接收者

c.可以使用android:exported="false"来防止其他应用发送广播到你发布的广播接收者中

d.当你使用sendBroadcast(Intent)时,通过一些权限控制来阻止发送广播到其他接收者中,从android4.0开始可以用Intent.setPackage

2.接收者生命周期

一个BroadcastReceiver对象的生命周期仅存在于onReceive方法中,当你的代码从该方法中返回时,系统会认为该接收者对象不再有效

不要在onReceive方法中进行一些异步操作的处理,因为该方法结束后整个接收者的生命周期就已经结束了

不要在onReceive方法中显示一个dialog或者绑定service,对于前者,你可以使用NotificationManager,而对于后者使用Context.startService来发送一个命令到service中

3.进程生命周期

当前进程是指执行该广播接收程序的进程,它是一个前台进程,即使该广播生命周期结束后,也会继续运行,直到系统内存紧张被回收

如果当广播接收程序生命周期结束后,该进程就会变为空进程,有可能会被系统回收,你可以结合service和broadcast receiver使用,这样可以使该进程不被回收

三、demo示例

1.动态注册

该程序中,当点击按钮时会发送一个广播,在该广播中执行在控制台打印广播参数的操作,并且每隔10秒发送一次广播,当退出程序后该广播生命周期结束,不会再在控制台打印

2.静态注册

a.项目结构

b.MainActivity

c.TestReceiver2

d.AndroidManefist.xml

e.运行结果

点击按钮后回在logcat中一直打印消息,无论程序是否退出



最经典的音乐播放器的例子:源码


  1. package com.wwj.sb.service;  
  2.   
  3. import java.util.List;  
  4.   
  5. import android.annotation.SuppressLint;  
  6. import android.app.Service;  
  7. import android.content.BroadcastReceiver;  
  8. import android.content.Context;  
  9. import android.content.Intent;  
  10. import android.content.IntentFilter;  
  11. import android.media.MediaPlayer;  
  12. import android.media.MediaPlayer.OnCompletionListener;  
  13. import android.media.MediaPlayer.OnPreparedListener;  
  14. import android.os.Handler;  
  15. import android.os.IBinder;  
  16. import android.util.Log;  
  17.   
  18. import com.wwj.sb.activity.PlayerActivity;  
  19. import com.wwj.sb.domain.AppConstant;  
  20. import com.wwj.sb.domain.Mp3Info;  
  21. import com.wwj.sb.utils.MediaUtil;  
  22. /*** 
  23.  * 2013/5/25 
  24.  * @author wwj 
  25.  * 音乐播放服务 
  26.  */  
  27. @SuppressLint("NewApi")  
  28. public class PlayerService extends Service {  
  29.     private MediaPlayer mediaPlayer; // 媒体播放器对象  
  30.     private String path;            // 音乐文件路径  
  31.     private int msg;  
  32.     private boolean isPause;        // 暂停状态  
  33.     private int current = 0;        // 记录当前正在播放的音乐  
  34.     private List<Mp3Info> mp3Infos;   //存放Mp3Info对象的集合  
  35.     private int status = 3;         //播放状态,默认为顺序播放  
  36.     private MyReceiver myReceiver;  //自定义广播接收器  
  37.     private int currentTime;        //当前播放进度  
  38.     private int duration;           //播放长度  
  39.       
  40.     //服务要发送的一些Action  
  41.     public static final String UPDATE_ACTION = "com.wwj.action.UPDATE_ACTION";  //更新动作  
  42.     public static final String CTL_ACTION = "com.wwj.action.CTL_ACTION";        //控制动作  
  43.     public static final String MUSIC_CURRENT = "com.wwj.action.MUSIC_CURRENT";  //当前音乐播放时间更新动作  
  44.     public static final String MUSIC_DURATION = "com.wwj.action.MUSIC_DURATION";//新音乐长度更新动作  
  45.       
  46.     /** 
  47.      * handler用来接收消息,来发送广播更新播放时间 
  48.      */  
  49.     private Handler handler = new Handler() {  
  50.         public void handleMessage(android.os.Message msg) {  
  51.             if (msg.what == 1) {  
  52.                 if(mediaPlayer != null) {  
  53.                     currentTime = mediaPlayer.getCurrentPosition(); // 获取当前音乐播放的位置  
  54.                     Intent intent = new Intent();  
  55.                     intent.setAction(MUSIC_CURRENT);  
  56.                     intent.putExtra("currentTime", currentTime);  
  57.                     sendBroadcast(intent); // 给PlayerActivity发送广播  
  58.                     handler.sendEmptyMessageDelayed(11000);  
  59.                 }  
  60.                   
  61.             }  
  62.         };  
  63.     };  
  64.   
  65.     @Override  
  66.     public void onCreate() {  
  67.         super.onCreate();  
  68.         Log.d("service""service created");  
  69.         mediaPlayer = new MediaPlayer();  
  70.         mp3Infos = MediaUtil.getMp3Infos(PlayerService.this);  
  71.           
  72.   
  73.         /** 
  74.          * 设置音乐播放完成时的监听器 
  75.          */  
  76.         mediaPlayer.setOnCompletionListener(new OnCompletionListener() {  
  77.   
  78.             @Override  
  79.             public void onCompletion(MediaPlayer mp) {  
  80.                 if (status == 1) { // 单曲循环  
  81.                     mediaPlayer.start();  
  82.                 } else if (status == 2) { // 全部循环  
  83.                     current++;  
  84.                     if(current > mp3Infos.size() - 1) {  //变为第一首的位置继续播放  
  85.                         current = 0;  
  86.                     }  
  87.                     Intent sendIntent = new Intent(UPDATE_ACTION);  
  88.                     sendIntent.putExtra("current", current);  
  89.                     // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  90.                     sendBroadcast(sendIntent);  
  91.                     path = mp3Infos.get(current).getUrl();  
  92.                     play(0);  
  93.                 } else if (status == 3) { // 顺序播放  
  94.                     current++;  //下一首位置  
  95.                     if (current <= mp3Infos.size() - 1) {  
  96.                         Intent sendIntent = new Intent(UPDATE_ACTION);  
  97.                         sendIntent.putExtra("current", current);  
  98.                         // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  99.                         sendBroadcast(sendIntent);  
  100.                         path = mp3Infos.get(current).getUrl();  
  101.                         play(0);  
  102.                     }else {  
  103.                         mediaPlayer.seekTo(0);  
  104.                         current = 0;  
  105.                         Intent sendIntent = new Intent(UPDATE_ACTION);  
  106.                         sendIntent.putExtra("current", current);  
  107.                         // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  108.                         sendBroadcast(sendIntent);  
  109.                     }  
  110.                 } else if(status == 4) {    //随机播放  
  111.                     current = getRandomIndex(mp3Infos.size() - 1);  
  112.                     System.out.println("currentIndex ->" + current);  
  113.                     Intent sendIntent = new Intent(UPDATE_ACTION);  
  114.                     sendIntent.putExtra("current", current);  
  115.                     // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  116.                     sendBroadcast(sendIntent);  
  117.                     path = mp3Infos.get(current).getUrl();  
  118.                     play(0);  
  119.                 }  
  120.             }  
  121.         });  
  122.   
  123.         myReceiver = new MyReceiver();  
  124.         IntentFilter filter = new IntentFilter();  
  125.         filter.addAction(PlayerActivity.CTL_ACTION);  
  126.         registerReceiver(myReceiver, filter);  
  127.     }  
  128.   
  129.     /** 
  130.      * 获取随机位置 
  131.      * @param end 
  132.      * @return 
  133.      */  
  134.     protected int getRandomIndex(int end) {  
  135.         int index = (int) (Math.random() * end);  
  136.         return index;  
  137.     }  
  138.   
  139.     @Override  
  140.     public IBinder onBind(Intent arg0) {  
  141.         return null;  
  142.     }  
  143.   
  144.     @Override  
  145.     public void onStart(Intent intent, int startId) {  
  146.         path = intent.getStringExtra("url");        //歌曲路径  
  147.         current = intent.getIntExtra("listPosition", -1);   //当前播放歌曲的在mp3Infos的位置  
  148.         msg = intent.getIntExtra("MSG"0);         //播放信息  
  149.         if (msg == AppConstant.PlayerMsg.PLAY_MSG) {    //直接播放音乐  
  150.             play(0);  
  151.         } else if (msg == AppConstant.PlayerMsg.PAUSE_MSG) {    //暂停  
  152.             pause();      
  153.         } else if (msg == AppConstant.PlayerMsg.STOP_MSG) {     //停止  
  154.             stop();  
  155.         } else if (msg == AppConstant.PlayerMsg.CONTINUE_MSG) { //继续播放  
  156.             resume();     
  157.         } else if (msg == AppConstant.PlayerMsg.PRIVIOUS_MSG) { //上一首  
  158.             previous();  
  159.         } else if (msg == AppConstant.PlayerMsg.NEXT_MSG) {     //下一首  
  160.             next();  
  161.         } else if (msg == AppConstant.PlayerMsg.PROGRESS_CHANGE) {  //进度更新  
  162.             currentTime = intent.getIntExtra("progress", -1);  
  163.             play(currentTime);  
  164.         } else if (msg == AppConstant.PlayerMsg.PLAYING_MSG) {  
  165.             handler.sendEmptyMessage(1);  
  166.         }  
  167.         super.onStart(intent, startId);  
  168.     }  
  169.   
  170.     /** 
  171.      * 播放音乐 
  172.      *  
  173.      * @param position 
  174.      */  
  175.     private void play(int currentTime) {  
  176.         try {  
  177.             mediaPlayer.reset();// 把各项参数恢复到初始状态  
  178.             mediaPlayer.setDataSource(path);  
  179.             mediaPlayer.prepare(); // 进行缓冲  
  180.             mediaPlayer.setOnPreparedListener(new PreparedListener(currentTime));// 注册一个监听器  
  181.             handler.sendEmptyMessage(1);  
  182.         } catch (Exception e) {  
  183.             e.printStackTrace();  
  184.         }  
  185.     }  
  186.   
  187.     /** 
  188.      * 暂停音乐 
  189.      */  
  190.     private void pause() {  
  191.         if (mediaPlayer != null && mediaPlayer.isPlaying()) {  
  192.             mediaPlayer.pause();  
  193.             isPause = true;  
  194.         }  
  195.     }  
  196.   
  197.     private void resume() {  
  198.         if (isPause) {  
  199.             mediaPlayer.start();  
  200.             isPause = false;  
  201.         }  
  202.     }  
  203.   
  204.     /** 
  205.      * 上一首 
  206.      */  
  207.     private void previous() {  
  208.         Intent sendIntent = new Intent(UPDATE_ACTION);  
  209.         sendIntent.putExtra("current", current);  
  210.         // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  211.         sendBroadcast(sendIntent);  
  212.         play(0);  
  213.     }  
  214.   
  215.     /** 
  216.      * 下一首 
  217.      */  
  218.     private void next() {  
  219.         Intent sendIntent = new Intent(UPDATE_ACTION);  
  220.         sendIntent.putExtra("current", current);  
  221.         // 发送广播,将被Activity组件中的BroadcastReceiver接收到  
  222.         sendBroadcast(sendIntent);  
  223.         play(0);  
  224.     }  
  225.   
  226.     /** 
  227.      * 停止音乐 
  228.      */  
  229.     private void stop() {  
  230.         if (mediaPlayer != null) {  
  231.             mediaPlayer.stop();  
  232.             try {  
  233.                 mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数  
  234.             } catch (Exception e) {  
  235.                 e.printStackTrace();  
  236.             }  
  237.         }  
  238.     }  
  239.   
  240.     @Override  
  241.     public void onDestroy() {  
  242.         if (mediaPlayer != null) {  
  243.             mediaPlayer.stop();  
  244.             mediaPlayer.release();  
  245.             mediaPlayer = null;  
  246.         }  
  247.           
  248.     }  
  249.   
  250.     /** 
  251.      *  
  252.      * 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放 
  253.      *  
  254.      */  
  255.     private final class PreparedListener implements OnPreparedListener {  
  256.         private int currentTime;  
  257.   
  258.         public PreparedListener(int currentTime) {  
  259.             this.currentTime = currentTime;  
  260.         }  
  261.   
  262.         @Override  
  263.         public void onPrepared(MediaPlayer mp) {  
  264.             mediaPlayer.start(); // 开始播放  
  265.             if (currentTime > 0) { // 如果音乐不是从头播放  
  266.                 mediaPlayer.seekTo(currentTime);  
  267.             }  
  268.             Intent intent = new Intent();  
  269.             intent.setAction(MUSIC_DURATION);  
  270.             duration = mediaPlayer.getDuration();  
  271.             intent.putExtra("duration", duration);  //通过Intent来传递歌曲的总长度  
  272.             sendBroadcast(intent);  
  273.         }  
  274.     }  
  275.   
  276.     public class MyReceiver extends BroadcastReceiver {  
  277.   
  278.         @Override  
  279.         public void onReceive(Context context, Intent intent) {  
  280.             int control = intent.getIntExtra("control", -1);  
  281.             switch (control) {  
  282.             case 1:  
  283.                 status = 1// 将播放状态置为1表示:单曲循环  
  284.                 break;  
  285.             case 2:  
  286.                 status = 2//将播放状态置为2表示:全部循环  
  287.                 break;  
  288.             case 3:  
  289.                 status = 3//将播放状态置为3表示:顺序播放  
  290.                 break;  
  291.             case 4:  
  292.                 status = 4//将播放状态置为4表示:随机播放  
  293.                 break;  
  294.             }  
  295.         }  
  296.     }  
  297.   
  298. }  

安卓下载功能中的广播接收器