什么场景适合?

如果你的app有长时间(大于一两秒)使用到音频,比如音乐视频的播放,录音,或者网络软件通话。这些场景在音频被占用时,你是需要做适当处理 或暂停,或退出,或降低音量;在音频被其他软件释放时,再及时恢复app状态。

本文章的bug:部分手机可以监听音频被占用的情况,但是监听不到释放的情况,导致恢复app状态的动作不能执行(在这样的手机上发现其他app也无法恢复状态—>疑是系统释放了)。

下面的案例没有正儿八经使用音频,具体使用只需要实现最底下的四个方法即可。

其实对音频的控制只做app占用的情况还不够全面,应该加上对电话状态的监听才全面,请看最下面一段代码

注意点:

1.有版本的区别

2.type最好使用music,这是恢复播放比较好的一种类型了

public class SoftCallListenerActivity extends AppCompatActivity implements AudioManager.OnAudioFocusChangeListener {public static final String TAG = "SoftCallListenerActivity";AppCompatTextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_solf_call_listener);textView = findViewById(R.id.atv);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {audioListener();} else {audioListenerD26();}}AudioManager audioManager;AudioAttributes playbackAttributes;AudioFocusRequest focusRequest;final Object focusLock = new Object();private void audioListenerD26() {audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);int result = audioManager.requestAudioFocus(this,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {playbackNow();}}@RequiresApi(api = Build.VERSION_CODES.O)private void audioListener() {audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);playbackAttributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).setAudioAttributes(playbackAttributes).setAcceptsDelayedFocusGain(true).setOnAudioFocusChangeListener(this, handler).build();request();}@Overrideprotected void onResume() {super.onResume();Logs.w(TAG, "onResume:  request" );if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {request();}}@RequiresApi(api = Build.VERSION_CODES.O)private void request(){int res = audioManager.requestAudioFocus(focusRequest);synchronized (focusLock) {if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {playbackNowAuthorized = false;} else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {playbackNowAuthorized = true;playbackNow();} else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {playbackDelayed = true;playbackNowAuthorized = false;}}}Handler handler = new Handler(Looper.getMainLooper()) {@Overridepublic void handleMessage(Message msg) {Logs.w(TAG, "handleMessage:" + msg.what);}};boolean playbackDelayed = false;boolean playbackNowAuthorized = false;boolean resumeOnFocusGain = false;@Overridepublic void onAudioFocusChange(int focusChange) {Logs.w(TAG, "onAudioFocusChange:" + focusChange);switch (focusChange) {case AudioManager.AUDIOFOCUS_GAIN:if (playbackDelayed || resumeOnFocusGain) {synchronized (focusLock) {playbackDelayed = false;resumeOnFocusGain = false;}playbackNow();}break;case AudioManager.AUDIOFOCUS_LOSS:synchronized (focusLock) {resumeOnFocusGain = false;playbackDelayed = false;}pausePlayback();break;case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:synchronized (focusLock) {resumeOnFocusGain = true;playbackDelayed = false;}pausePlayback();break;case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:playDependsYourDear();break;}}private void playDependsYourDear() {Logs.w(TAG, "playDependsYourDear");}private void playbackNow() {Logs.w(TAG, "playbackNow");}private void pausePlayback() {Logs.w(TAG, "pausePlayback");}/***当app的音频使用完毕,应该主动释放,这样其他app才能及时响应*/private void playComplete() {Logs.w(TAG, "playComplete");audioManager.abandonAudioFocus(this);}
}
private void telephony() {if (mTelephonyManager == null)mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);mPanelBroadcastReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {try {JSONObject jsonObject = new JSONObject();int state = mTelephonyManager.getCallState();switch (state) {case TelephonyManager.CALL_STATE_IDLE:// 电话挂断 Logs.w(TAG, "电话挂断..."); break;case TelephonyManager.CALL_STATE_OFFHOOK: //电话通话的状态 Logs.w(TAG, "正在通话...");break;case TelephonyManager.CALL_STATE_RINGING: //电话响铃的状态 Logs.w(TAG, "电话响铃...");break;}sendMessage(jsonObject.toString());} catch (JSONException e) {e.printStackTrace();}}}};IntentFilter panelFilter = new IntentFilter();panelFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);panelFilter.setPriority(Integer.MAX_VALUE);mContext.registerReceiver(mPanelBroadcastReceiver, panelFilter, null, null);}

android 多媒体音频占用情况监听相关推荐

  1. Android USB摄像头插拔监听

    Android USB摄像头插拔监听 一.简要介绍 二.使用广播监听USB摄像头插拔情况 1.注册监听USB设备插拔广播 2.判断UsbDevice是否是Camera设备 (重点) 二.通过UsbMa ...

  2. Android DownloadManager下载完成事件监听(系列4)

     Android DownloadManager下载完成事件监听(系列4) 我在之前写了写一些关于Android DownloadManager 的文章: (系列1)<Android大数据. ...

  3. Android的Usb设备的监听(Dev)外设端口的判定以及耳机的插拔

    最近在公司用到外设,需要判断接入的外设的VendorId和ProductId,然后给大家说一下自己的学习成果把 ,首先我门可以通过android.hardware.usb.action.USB_STA ...

  4. android 监听物理返回键,Android应用开发之react-native 监听Android物理返回键

    本文将带你了解Android应用开发之react-native 监听Android物理返回键,希望本文对大家学Android有所帮助. 1. componentWillMount(){         ...

  5. android 窗口监听按键,Android编程实现Dialog窗体监听的方法

    本文实例讲述了Android编程实现Dialog窗体监听的方法.分享给大家供大家参考,具体如下: 今天做了一个Dialong窗体监听包括窗体内的xml监听. 效果图: test.class代码 pac ...

  6. android 关机消息广播,Android开机、关机播音监听

    Android开机.关机广播监听 一.开机广播的监听 1.在AndroidManifest.xml文件注册接收开机广播 2.在BroadcastReceiver里执行要做的事情 public clas ...

  7. Android实现双击事件的监听

    本文转自:Android实现双击事件的监听 Android实现view的双击事件监听,一般使用的场景,列表双击顶部回到第一条! 双击监听 /*** view双击监听事件*/ public class ...

  8. Linux - netstat 查看系统端口占用和监听情况

    文章目录 功能 语法 示例 显示 tcp,udp 的端口和进程 Show both listening and non-listening sockets List all tcp ports. Li ...

  9. Android通过广播接收器BroadcastReceiver监听蓝牙连接变化

    上一篇介绍了通过广播对蓝牙的打开关闭等变化的监听,这一篇将对蓝牙连接状态的变化进行封装. 首先是广播接收器BlueToothConnectReceiver 类 import android.bluet ...

  10. Android Home键按键事件监听

    平时用的比较多的是Back键按键的监听,但是后来修改相机问题时遇到了需要监听Home键的情况,遂各种搜索资料,get到如下技能: Home键的监听也需要注册广播接收器(采用动态注册的方式),通过拦截让 ...

最新文章

  1. Linux安装卸载mysql
  2. 二分图 crf的军训
  3. 函数计算帮助石墨文档突破性能瓶颈,有效节省服务器成本
  4. 跨时钟域电路设计——结绳法
  5. .Net Core 之 Ubuntu 14.04 部署过程
  6. 【MySQL原理解析】01. 一条SQL查询语句是如何执行的
  7. linux怎么设置ftp为主动模式,linux设置ftp服务器为主动模式
  8. 7-14 求整数段和
  9. ElasticSearch 7 正式发布!
  10. cisco hsrp备份小实验
  11. 4 个拥有绝佳命令行界面的终端程序
  12. Google登陆集成笔记-含坑
  13. 【软考信息系统项目管理师】必背重点之信息化和信息系统
  14. at指令 meid_【技术分享】使用AT调制解调器命令解锁LG Android屏幕
  15. 移动文件需要计算机管理员权限,win7系统提示“需要管理员权限才能移动文件夹”的解决方法...
  16. 2023啦 最新无人直播小白教程!
  17. dfrobot Mind+掌控板图形化编程
  18. 百度推出清风算法,SEO的标题该如何优化?
  19. html、js、css3制作一款辉光管时钟
  20. Smart Link详解及其配置

热门文章

  1. spring中注解及原理
  2. KNN算法(10折交叉验证)
  3. 拼多多显示内部服务器错误是怎么回事,拼多多提现出现错误怎么办?拼多多提现常见问题...
  4. Python识别同构数
  5. 【转】人脸识别:AI产品经理需要了解的CV通识
  6. 谈谈RJ45线序的打法及口诀
  7. 编写树莓派引脚驱动代码
  8. matlab匿名函数求导,MATLAB匿名函数和函数句柄
  9. 实训报告html前端开发,web前端开发实习报告比你想象中简单
  10. 2021国赛数学建模赛题与分析