MediaPlayer

最近打算做一个日语学习的应用,用来辅助我学习日语,主要是播放前文、单词什么的,最好lrc能配合滚动,因此学习一下MediaPlayer。

一、Controlling Your App’s Volume and Playback

STREAM_MUSIC

setVolumeControlStream() 音量控制
setVolumeControlStream(AudioManager.STREAM_MUSIC);
在初始化的onCreate()中调用,只需调用一次

Use Hardware Playback Control Keys to Control Your App’s Audio Playback

二、Managing Audio Focus

翻译好难还是直接看原文吧。。
You must specify which stream you're using and whether you expect to require transient(短暂) or permanent(常驻) audio focus. Request transient focus when you expect to play audio for only a short time (for example when playing navigation(导航) instructions(说明). Request permanent audio focus when you plan to play audio for the foreseeable(可预见的) future (for example, when playing music).

The following snippet(片段) requests permanent audio focus on the music audio stream. You should request the audio focus immediately before you begin playback, such as when the user presses play or the background music for the next game level begins.

AudioManager am = mContext.getSystemService(Context.AUDIO_SERVICE);
...
// Request audio focus for playback
int result = am.requestAudioFocus(afChangeListener,                                 
                                  // Use the music stream.                                 
                                  AudioManager.STREAM_MUSIC,                                 
                                  // Request permanent focus.                                 
                                  AudioManager.AUDIOFOCUS_GAIN);

if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {   
    am.registerMediaButtonEventReceiver(RemoteControlReceiver);    
    // Start playback.
}

Once you've finished playback be sure to call abandonAudioFocus(). This notifies the system that you no longer require focus and unregisters the associated AudioManager.OnAudioFocusChangeListener. In the case of abandoning transient focus, this allows any interupted app to continue playback.(为了防止放弃短暂焦点,它允许任何中断的app能够继续回放)

// Abandon audio focus when playback complete
am.abandonAudioFocus(afChangeListener);

When requesting transient audio focus you have an additional option: whether or not you want to enable "ducking(低头,闪避)." Normally, when a well-behaved audio app loses audio focus it immediately silences its playback. By requesting a transient audio focus that allows ducking you tell other audio apps that it’s acceptable for them to keep playing, provided they lower their volume until the focus returns to them.

// Request audio focus for playback
int result = am.requestAudioFocus(afChangeListener,                            
                                  // Use the music stream.                             
                                  AudioManager.STREAM_MUSIC,                             
                                  // Request permanent focus.                                                                          
                                  AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);

if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {    
    // Start playback.
}

Ducking is particularly suitable for apps that use the audio stream intermittently(间歇的), such as for audible(能听到的) driving directions.

Whenever another app requests audio focus as described(描述) above, its choice between permanent and transient (with or without support for ducking) audio focus is received by the listener you registered when requesting focus.

  • Handle the Loss(损失) of Audio Focus

If your app can request audio focus, it follows that it will in turn lose that focus when another app requests it. How your app responds to a loss of audio focus depends on the manner of that loss.

The onAudioFocusChange() callback method of the audio focus change listener you registered when requesting audio focus receives a parameter that describes the focus change event(收到一个描述焦点改变事件的参数). Specifically, the possible focus loss events mirror(反映) the focus request types from the previous section—permanent loss, transient loss, and transient with ducking permitted.(特别地,那个可能的焦点事件跟前面的请求类型有关,短暂、常驻还是常驻躲避)

Generally speaking, a transient (temporary) loss of audio focus should result in your app silencing it’s audio stream, but otherwise maintaining the same state. You should continue to monitor changes in audio focus and be prepared to resume playback where it was paused once you’ve regained the focus.
(通常来说,audio focus的transient loss会导致播放暂停,但是除此以外维持同样的状态。你应该继续监视audio focus变化,在你暂停的地方准备恢复播放 当你重新获取到焦点时。)

If the audio focus loss is permanent, it’s assumed that another application is now being used to listen to audio and your app should effectively end itself. In practical terms, that means stopping playback, removing media button listeners—allowing the new audio player to exclusively(独占,只,仅仅) handle those events—and abandoning your audio focus. At that point, you would expect a user action (pressing play in your app) to be required before you resume playing audio.
(如果是permanent loss,它被假定为另一个应用现在正在听音频,你的app应该有效的结束它自己。在实际项目中,这意味着停止播放,移除media button监听器——允许新的音频播放器独占处理这些事件——放弃你的音频焦点。在那时候,你应该期望用户行为(在你app里点击播放)在你重新播放之前。)

In the following code snippet, we pause the playback or our media player object if the audio loss is transient and resume it when we have regained the focus. If the loss is permanent, it unregisters our media button event receiver and stops monitoring audio focus changes.

AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() {        
    public void onAudioFocusChange(int focusChange) {            
        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT) {                
            // Pause playback            
        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {                
            // Resume playback            
        } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {                      
            am.unregisterMediaButtonEventReceiver(RemoteControlReceiver); 
            am.abandonAudioFocus(afChangeListener);                
            // Stop playback            
        }        
    }    
};

In the case of a transient loss of audio focus where ducking is permitted, rather than pausing playback, you can "duck" instead.

  • Duck!

Ducking is the process of lowering your audio stream output volume to make transient audio from another app easier to hear without totally disrupting the audio from your own application.
(Ducking 是降低你的音频音量,使其它app的短暂音频更容易被听到,而不完全被你的音频干扰。)

In the following code snippet lowers the volume on our media player object when we temporarily lose focus, then returns it to its previous level when we regain focus.

OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {    
    public void onAudioFocusChange(int focusChange) {        
        if (focusChange == AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {            
            // Lower the volume        
        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {            
            // Raise it back to normal        
        }    
    }
};

A loss of audio focus is the most important broadcast to react to, but not the only one. The system broadcasts a number of intents to alert you to changes in user’s audio experience. The next lesson demonstrates(演示) how to monitor them to improve the user’s overall experience.

三、Dealing with Audio Output Hardware

  • Check What Hardware is Being Used

How your app behaves might be affected by which hardware its output is being routed to.
You can query the AudioManager to determine if the audio is currently being routed to the device speaker, wired headset(有线耳机), or attached Bluetooth device as shown in the following snippet(代码段):

if (isBluetoothA2dpOn()) {    
    // Adjust output for Bluetooth.
}else if (isSpeakerphoneOn()) {    
    // Adjust output for Speakerphone.
} else if (isWiredHeadsetOn()) {    
    // Adjust output for headsets
} else {    
    // If audio plays and noone can hear it, is it still playing?
}
  • Handle Changes in the Audio Output Hardware

When a headset is unplugged(拔出), or a Bluetooth device disconnected, the audio stream automatically reroutes to the built in speaker. If you listen to your music at as high a volume as I do, that can be a noisy surprise.

Luckily the system broadcasts an ACTION_AUDIO_BECOMING_NOISY intent when this happens. It’s good practice to register a BroadcastReceiver that listens for this intent whenever you’re playing audio. In the case of music players, users typically expect the playback to be paused—while for games you may choose to significantly(显著地) lower the volume.
(当你的耳机被拔出,断开蓝牙时,暂停播放)

四、Samples

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容