一、FileProvider
前幾天學(xué)習(xí)了如何分享文字、圖片、音樂或其他流文件,那么提供讓我們選擇文件的應(yīng)用,比如圖庫不僅能查看圖片還能從其他應(yīng)用跳轉(zhuǎn)到圖庫去挑選圖片然后返回選擇的結(jié)果,這是如何做的呢?官方提供了 FileProvider 來幫助我們完成。
1、Manifest中聲明
<application> 標(biāo)簽中聲明 <provider>,例子中的屬性必須有

說明:
(1)authorities:android:package?+ fileprovider;
(2)<mete-data> 中指出 FileProvider 允許訪問的目錄
(3)這些目錄存放在 res/xml/filepath.xml 文件中

注意:(特別感謝小愛_小世界)
<file-path> 代表的根目錄:Context.getFilesDir()
<external-path> 代表的根目錄:Environment.getExternalStorageDirectory()
<cache-path> 代表的根目錄:getCacheDir()
2、選擇界面的創(chuàng)建-- Activity
Manifest中應(yīng)該這樣聲明

說明(針對(duì) <intent-filter>):
(1)<action>:android.Intent.action.PICK;
(2)<category>:DEFAULT 和 OPENABLE 都要有;
(3)<data>:要設(shè)置 MIME 類型。自己根據(jù)需求設(shè)置。
至于 Activity 的創(chuàng)建和其他沒有區(qū)別,一般是一個(gè)列表供用戶選擇。
3、選擇結(jié)果的處理及返回結(jié)果

說明:
(1)選擇文件后,會(huì)得到一個(gè)File對(duì)象,使用 FileProvider.getUriForFile(Context context,String authority,File file) 方法獲取Uri。如果該文件在不允許訪問的目錄下(filepath.xml),則會(huì)拋異常。
(2)返回結(jié)果的 Intent 要通過 addFlags(FLAG_GRANT_READ_URI_PERMISSION) 方法進(jìn)行臨時(shí)授權(quán),要設(shè)置 data 和 MIME type。
(3)使用 setResult(resultCode , intent) 將結(jié)果設(shè)置好,并 finish() 當(dāng)前 Activity。
二、音頻---Audio
1、音頻簡介
Android 音頻控制是由 AudioManager 來管理,通過 getSystemService(Context.AUDIO_SERVICE) ?來獲取該服務(wù)。
音頻分為 AudioManager.STREAM_SYSTEM、AudioManager.STREAM_MUSIC、AudioManager.STREAM_RING、AudioManager.STREAM_NOTIFICATION、AudioManager.STREAM_ALARM、AudioManager.STREAM_VOICE_CALL、AudioManager.STREAM_DTMF(雙音多頻,撥號(hào)鍵的聲音)七種。
2、音量
當(dāng)啟動(dòng)一個(gè)新應(yīng)用,要在 onCreate() 中使用 AudioManager.setVolumeControlStream(int type) 設(shè)置應(yīng)用控制的音量種類。
各種音量的最大值一般都一樣(自己測試得到)。
設(shè)置音量大小兩種方法:
(1)漸進(jìn)式
就是像按音量控制按鈕似的,一點(diǎn)一點(diǎn)的調(diào)節(jié)。
AudioManager.adjustStreamVolume(int streamType, int direction, int flags)
1)streamType 不介紹,同上面。
2)direction 是調(diào)整的方向:
ADJUST_LOWER?降低音量
ADJUST_RAISE?升高音量
ADJUST_SAME?保持不變,這個(gè)主要用于向用戶展示當(dāng)前的音量
3)flags 兩種常見:
FLAG_PLAY_SOUND 調(diào)整音量時(shí)播放聲音
FLAG_SHOW_UI?調(diào)整時(shí)顯示音量條,就是按音量鍵出現(xiàn)的界面
(2)直接設(shè)置
Audiom.setStreamVolume(streamType , index , flags)
index:音量大小
3、硬件按鍵控制
無論用戶按下設(shè)備上任意一個(gè)控制按鈕,系統(tǒng)都會(huì)廣播一個(gè)帶有ACTION_MEDIA_BUTTON的Intent。因此使用廣播來處理這些事件。


因?yàn)榭赡軙?huì)有多個(gè)程序在監(jiān)聽與媒體按鈕相關(guān)的事件,所以我們必須在代碼中控制應(yīng)用接收相關(guān)事件的時(shí)機(jī)。我們使用?AudioManager?來為我們的應(yīng)用注冊(cè)監(jiān)聽與取消監(jiān)聽媒體按鈕事件,當(dāng)Receiver被注冊(cè)上時(shí),它將是唯一一個(gè)能夠響應(yīng)媒體按鈕廣播的Receiver。

4、音頻焦點(diǎn)
由于可能會(huì)有多個(gè)應(yīng)用可以播放音頻,所以我們應(yīng)當(dāng)考慮一下他們應(yīng)該如何交互。為了防止多個(gè)音樂播放應(yīng)用同時(shí)播放音頻,Android 使用音頻焦點(diǎn)(Audio Focus)來控制音頻的播放——即只有獲取到音頻焦點(diǎn)的應(yīng)用才能夠播放音頻。
(1)處理焦點(diǎn)變化事件
使用 AudioManager.OnAudioFocusChangeListener,共有八種事件:
AUDIOFOCUS_GAIN:永久獲取焦點(diǎn),只有手動(dòng)釋放才會(huì)失去焦點(diǎn);
AUDIOFOCUS_GAIN_TRANSIENT:暫時(shí)獲取焦點(diǎn);
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:暫時(shí)獲取焦點(diǎn),其他音頻降低音量播放;
AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:暫時(shí)獲取焦點(diǎn),其他音頻停止播放。
對(duì)應(yīng)四種失去焦點(diǎn)事件 AUDIOFOCUS_LOSS、AUDIOFOCUS_LOSS_TRANSIEN、AUDIOFOCUS_LOSS_TRANSIENT_MAY_DUCK、AUDIOFOCUS_LOSS_TRANSIENT_EXCLUSIVE。
疑問:
經(jīng)過查閱資料和自己試驗(yàn),未發(fā)現(xiàn) TRANSIENT 和 TRANSIENT_EXCLUSIVE 的區(qū)別。
如有朋友知曉,請(qǐng)分享,謝謝。
(2)申請(qǐng)音頻焦點(diǎn)
AudioManager.requestAudioFocus( listener , streamType , durationHint )
1)listener:OnAudioFocusChangeListener,指處理申請(qǐng)成功之后 AudioFocus 變化情況的Listener,因?yàn)樵讷@得焦點(diǎn)期間可能又有別的應(yīng)用申請(qǐng)焦點(diǎn)。
2)streamType:音頻流類型
3)durationHint:(是 AudioManager 中的常量,有以下幾種值)
4)返回值是 AudioManager.AUDIOFOCUS_REQUEST_GAINED 或 AudioManager.AUDIOFOCUS_REQUEST_FAILED。
(3)釋放音頻焦點(diǎn)
abandonAudioFocus( listener )?這樣相當(dāng)于告知系統(tǒng)我們不再需要獲取焦點(diǎn)并且注銷所關(guān)聯(lián)的?AudioManager.OnAudioFocusChangeListener?監(jiān)聽器。
5、處理音頻輸出設(shè)備的改變
當(dāng)有線耳機(jī)被拔出或者藍(lán)牙設(shè)備斷開連接的時(shí)候,音頻流會(huì)自動(dòng)輸出到內(nèi)置的揚(yáng)聲器上。假設(shè)播放聲音很大,這個(gè)時(shí)候突然轉(zhuǎn)到揚(yáng)聲器播放會(huì)顯得非常嘈雜。幸運(yùn)的是,系統(tǒng)會(huì)在這種情況下廣播帶有?ACTION_AUDIO_BECOMING_NOISY?的 Intent,所以使用廣播來處理這些事件。