利用Android SoundPool播放通知铃声

2020-02-19  本文已影响0人  辣辣不乖

初衷是应用到腾讯IM项目的即时通讯SDK,项目自带通知采用非安卓原生,各种实际应用有通知,无消息铃声,无奈只能自己添加铃声!

起初用的是RingtoneManager.getRingtone方式播放通知铃声

Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bubble);
if (NotificationManagerCompat.from(DemoApplication.this).areNotificationsEnabled()) {
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), uri);
                        r.play();
                    } else {
                        //NOT ENABLED
                    }

上面的代码存在mediaPlayer未释放资源的问题,会导致其它模块播放media时出现各种BUG,比如本APP挂后台,另外开启音乐软件会导致音乐软件出现各种异常 . . .

百度了一堆优劣分析,于是改用SoundPool实现

SoundPool.Builder builder = new SoundPool.Builder();
builder.setMaxStreams(3);
AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();    //转换音频格式
attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC);
builder.setAudioAttributes(attrBuilder.build());
SoundPool soundPool = builder.build();
final int voiceId = soundPool.load(DemoApplication.this, R.raw.bubble, 1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
                        @Override
                        public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                            //判断APP是否通知允许
                            if (status == 0 && NotificationManagerCompat.from(DemoApplication.this).areNotificationsEnabled()) {
                                //第一个参数soundID
                                //第二个参数leftVolume为左侧音量值(范围= 0.0到1.0)
                                //第三个参数rightVolume为右的音量值(范围= 0.0到1.0)
                                //第四个参数priority 为流的优先级,值越大优先级高,影响当同时播放数量超出了最大支持数时SoundPool对该流的处理
                                //第五个参数loop 为音频重复播放次数,0为值播放一次,-1为无限循环,其他值为播放loop+1次
                                //第六个参数 rate为播放的速率,范围0.5-2.0(0.5为一半速率,1.0为正常速率,2.0为两倍速率)
                                soundPool.play(voiceId, 1, 1, 1, 0, 1);
                            }
                        }
                    });
                    //释放音频内存
                    soundPool.release();

以上方式目前运行良好,如果非要问为什么不用原生的Notification模块,那当然是我不会啊。。。腾讯IM SDK里面 自己封装了非原生Notification,如下:

for (TIMMessage msg : msgs) {
                    TIMOfflinePushNotification notification = new TIMOfflinePushNotification(DemoApplication.this, msg);
                    notification.doNotify(DemoApplication.this, R.drawable.default_user_icon);
}
//明显的,这我看不懂啊
//虽然提供了声音接口,setSound(android.net.Uri sound),但是不会用,折腾了半天也不成功。

顺便安利以下SoundPool相对于MediaPlayer的优点

1.SoundPool适合 短且对反应速度比较高 的情况(游戏音效或按键声等),文件大小一般控制在几十K到几百K,最好不超过1M,

2.SoundPool 可以与MediaPlayer同时播放,SoundPool也可以同时播放多个声音;

3.SoundPool 最终编解码实现与MediaPlayer相同;

4.MediaPlayer只能同时播放一个声音,加载文件有一定的时间,适合文件比较大,响应时间要是那种不是非常高的场景

学习参考链接:

https://www.jianshu.com/p/6a0b046ef164

https://www.jianshu.com/p/62a22367caef

https://www.jianshu.com/p/d7c40d796166

上一篇 下一篇

猜你喜欢

热点阅读