首页 > 代码库 > 安卓下载功能中的广播接收器
安卓下载功能中的广播接收器
公司项目中要使用webview下载程序,所以必须用到广播接收器,配合service下载。
忘记的东西重来一遍。
后面有最经典的音乐播放器的源码,Service BroadCastReeiver都用到了
简单4步,动态加载广播
1.定义一个广播接收器
public class MyReceiver extends BroadcastReceiver
{
}
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中一直打印消息,无论程序是否退出
最经典的音乐播放器的例子:源码
- package com.wwj.sb.service;
- import java.util.List;
- import android.annotation.SuppressLint;
- import android.app.Service;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.MediaPlayer;
- import android.media.MediaPlayer.OnCompletionListener;
- import android.media.MediaPlayer.OnPreparedListener;
- import android.os.Handler;
- import android.os.IBinder;
- import android.util.Log;
- import com.wwj.sb.activity.PlayerActivity;
- import com.wwj.sb.domain.AppConstant;
- import com.wwj.sb.domain.Mp3Info;
- import com.wwj.sb.utils.MediaUtil;
- /***
- * 2013/5/25
- * @author wwj
- * 音乐播放服务
- */
- @SuppressLint("NewApi")
- public class PlayerService extends Service {
- private MediaPlayer mediaPlayer; // 媒体播放器对象
- private String path; // 音乐文件路径
- private int msg;
- private boolean isPause; // 暂停状态
- private int current = 0; // 记录当前正在播放的音乐
- private List<Mp3Info> mp3Infos; //存放Mp3Info对象的集合
- private int status = 3; //播放状态,默认为顺序播放
- private MyReceiver myReceiver; //自定义广播接收器
- private int currentTime; //当前播放进度
- private int duration; //播放长度
- //服务要发送的一些Action
- public static final String UPDATE_ACTION = "com.wwj.action.UPDATE_ACTION"; //更新动作
- public static final String CTL_ACTION = "com.wwj.action.CTL_ACTION"; //控制动作
- public static final String MUSIC_CURRENT = "com.wwj.action.MUSIC_CURRENT"; //当前音乐播放时间更新动作
- public static final String MUSIC_DURATION = "com.wwj.action.MUSIC_DURATION";//新音乐长度更新动作
- /**
- * handler用来接收消息,来发送广播更新播放时间
- */
- private Handler handler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- if (msg.what == 1) {
- if(mediaPlayer != null) {
- currentTime = mediaPlayer.getCurrentPosition(); // 获取当前音乐播放的位置
- Intent intent = new Intent();
- intent.setAction(MUSIC_CURRENT);
- intent.putExtra("currentTime", currentTime);
- sendBroadcast(intent); // 给PlayerActivity发送广播
- handler.sendEmptyMessageDelayed(1, 1000);
- }
- }
- };
- };
- @Override
- public void onCreate() {
- super.onCreate();
- Log.d("service", "service created");
- mediaPlayer = new MediaPlayer();
- mp3Infos = MediaUtil.getMp3Infos(PlayerService.this);
- /**
- * 设置音乐播放完成时的监听器
- */
- mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
- @Override
- public void onCompletion(MediaPlayer mp) {
- if (status == 1) { // 单曲循环
- mediaPlayer.start();
- } else if (status == 2) { // 全部循环
- current++;
- if(current > mp3Infos.size() - 1) { //变为第一首的位置继续播放
- current = 0;
- }
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- path = mp3Infos.get(current).getUrl();
- play(0);
- } else if (status == 3) { // 顺序播放
- current++; //下一首位置
- if (current <= mp3Infos.size() - 1) {
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- path = mp3Infos.get(current).getUrl();
- play(0);
- }else {
- mediaPlayer.seekTo(0);
- current = 0;
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- }
- } else if(status == 4) { //随机播放
- current = getRandomIndex(mp3Infos.size() - 1);
- System.out.println("currentIndex ->" + current);
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- path = mp3Infos.get(current).getUrl();
- play(0);
- }
- }
- });
- myReceiver = new MyReceiver();
- IntentFilter filter = new IntentFilter();
- filter.addAction(PlayerActivity.CTL_ACTION);
- registerReceiver(myReceiver, filter);
- }
- /**
- * 获取随机位置
- * @param end
- * @return
- */
- protected int getRandomIndex(int end) {
- int index = (int) (Math.random() * end);
- return index;
- }
- @Override
- public IBinder onBind(Intent arg0) {
- return null;
- }
- @Override
- public void onStart(Intent intent, int startId) {
- path = intent.getStringExtra("url"); //歌曲路径
- current = intent.getIntExtra("listPosition", -1); //当前播放歌曲的在mp3Infos的位置
- msg = intent.getIntExtra("MSG", 0); //播放信息
- if (msg == AppConstant.PlayerMsg.PLAY_MSG) { //直接播放音乐
- play(0);
- } else if (msg == AppConstant.PlayerMsg.PAUSE_MSG) { //暂停
- pause();
- } else if (msg == AppConstant.PlayerMsg.STOP_MSG) { //停止
- stop();
- } else if (msg == AppConstant.PlayerMsg.CONTINUE_MSG) { //继续播放
- resume();
- } else if (msg == AppConstant.PlayerMsg.PRIVIOUS_MSG) { //上一首
- previous();
- } else if (msg == AppConstant.PlayerMsg.NEXT_MSG) { //下一首
- next();
- } else if (msg == AppConstant.PlayerMsg.PROGRESS_CHANGE) { //进度更新
- currentTime = intent.getIntExtra("progress", -1);
- play(currentTime);
- } else if (msg == AppConstant.PlayerMsg.PLAYING_MSG) {
- handler.sendEmptyMessage(1);
- }
- super.onStart(intent, startId);
- }
- /**
- * 播放音乐
- *
- * @param position
- */
- private void play(int currentTime) {
- try {
- mediaPlayer.reset();// 把各项参数恢复到初始状态
- mediaPlayer.setDataSource(path);
- mediaPlayer.prepare(); // 进行缓冲
- mediaPlayer.setOnPreparedListener(new PreparedListener(currentTime));// 注册一个监听器
- handler.sendEmptyMessage(1);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 暂停音乐
- */
- private void pause() {
- if (mediaPlayer != null && mediaPlayer.isPlaying()) {
- mediaPlayer.pause();
- isPause = true;
- }
- }
- private void resume() {
- if (isPause) {
- mediaPlayer.start();
- isPause = false;
- }
- }
- /**
- * 上一首
- */
- private void previous() {
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- play(0);
- }
- /**
- * 下一首
- */
- private void next() {
- Intent sendIntent = new Intent(UPDATE_ACTION);
- sendIntent.putExtra("current", current);
- // 发送广播,将被Activity组件中的BroadcastReceiver接收到
- sendBroadcast(sendIntent);
- play(0);
- }
- /**
- * 停止音乐
- */
- private void stop() {
- if (mediaPlayer != null) {
- mediaPlayer.stop();
- try {
- mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- @Override
- public void onDestroy() {
- if (mediaPlayer != null) {
- mediaPlayer.stop();
- mediaPlayer.release();
- mediaPlayer = null;
- }
- }
- /**
- *
- * 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放
- *
- */
- private final class PreparedListener implements OnPreparedListener {
- private int currentTime;
- public PreparedListener(int currentTime) {
- this.currentTime = currentTime;
- }
- @Override
- public void onPrepared(MediaPlayer mp) {
- mediaPlayer.start(); // 开始播放
- if (currentTime > 0) { // 如果音乐不是从头播放
- mediaPlayer.seekTo(currentTime);
- }
- Intent intent = new Intent();
- intent.setAction(MUSIC_DURATION);
- duration = mediaPlayer.getDuration();
- intent.putExtra("duration", duration); //通过Intent来传递歌曲的总长度
- sendBroadcast(intent);
- }
- }
- public class MyReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- int control = intent.getIntExtra("control", -1);
- switch (control) {
- case 1:
- status = 1; // 将播放状态置为1表示:单曲循环
- break;
- case 2:
- status = 2; //将播放状态置为2表示:全部循环
- break;
- case 3:
- status = 3; //将播放状态置为3表示:顺序播放
- break;
- case 4:
- status = 4; //将播放状态置为4表示:随机播放
- break;
- }
- }
- }
- }
安卓下载功能中的广播接收器