Android音視頻錄制與播放功能簡述

安卓平臺和聲音錄制與播放相關的主要是4個類:MediaRecorderMediaPlayerSoundPool,AudioRecordAudioTrack

  1. MediaRecorder可以錄制視頻和音頻到文件
  2. MediaPlayer可以播放視頻和音頻文件
  3. SoundPool用于播放比較短的音頻片段
  4. AudioRecord可以提供接口讀取音頻流數據(byte數組或者short數組)
  5. AudioTrack提供接口用于播放音頻流數據。

其中MediaRecorder和AudioRecord用于聲音錄制,SoundPool、MediaPlayer和AudioTrack用于聲音播放。AudioRecord和AudioTrack用于操作音頻流數據,操作對象是byte數組(或者short數組),而MediaRecorder和MediaPlayer提供了經過更高層抽象和封裝接口,直接對文件進行操作,而且他倆功能更豐富,同時支持音頻和視頻。

一、MediaRecorder

Paste_Image.png
MediaRecorder的狀態簡述:

Initial:初始化。也就是MediaRecorder 剛被創建的時候。在這個時候我們去設置音頻或者視頻的來源了,可能這個時候就有人問了 音頻或者視頻的來源是什么意思,舉個例子吧,比如當我們在錄音的時候,這個聲音的來源就可以設置成手機的麥克風。
Initialized:初始化完成。這里我們已經知道音頻或者視頻的來源了,在這里我們就可以設置一些輸出的屬性了,比如輸出文件的保存格式,編碼格式等。
DataSourceConfigured:數據源配置改變。也就是我們改變了一些輸出的屬性,就會進入到這個狀態。
Prepered:處于這個狀態就說明了我們的配置已經完成了,現在準備去錄制了。
Recordeing:錄制中。
Released:資源被釋放了。
Error:錄制的時候發生了錯誤。

主要方法:
 setAudioChannels(int numChannels) 設置錄制的音頻通道數
 setAudioEncoder(int audio_encoder) 設置audio的編碼格式
 setAudioEncodingBitRate(int bitRate) 設置錄制的音頻編碼比特率
 setAudioSamplingRate(int samplingRate) 設置錄制的音頻采樣率
 setAudioSource(int audio_source) 設置用于錄制的音源
 setAuxiliaryOutputFile(String path) 輔助時間的推移視頻文件的路徑傳遞
 setAuxiliaryOutputFile(FileDescriptor fd)在文件描述符傳遞的輔助時間的推移視頻
 setCamera(Camera c) 設置一個recording的攝像頭
 setCaptureRate(double fps) 設置視頻幀的捕獲率
 setMaxDuration(int max_duration_ms) 設置記錄會話的最大持續時間(毫秒)
 setMaxFileSize(long max_filesize_bytes) 設置記錄會話的最大大小(以字節為單位)
 setOutputFile(FileDescriptor fd) 傳遞要寫入的文件的文件描述符
 setOutputFile(String path) 設置輸出文件的路徑
 setOutputFormat(int output_format) 設置在錄制過程中產生的輸出文件的格式
 setPreviewDisplay(Surface sv) 表面設置顯示記錄媒體(視頻)的預覽
 setVideoEncoder(int video_encoder) 設置視頻編碼器,用于錄制
 setVideoEncodingBitRate(int bitRate) 設置錄制的視頻編碼比特率
 setVideoFrameRate(int rate) 設置要捕獲的視頻幀速率
 setVideoSize(int width, int height) 設置要捕獲的視頻的寬度和高度
 setVideoSource(int video_source) 開始捕捉和編碼數據到setOutputFile(指定的文件)
 setLocation(float latitude, float longitude) 設置并存儲在輸出文件中的地理數據(經度和緯度)
 setProfile(CamcorderProfile profile) 指定CamcorderProfile對象
 setOrientationHint(int degrees)設置輸出的視頻播放的方向提示
 setOnErrorListener(MediaRecorder.OnErrorListener l)注冊一個用于記錄錄制時出現的錯誤的監聽器
 setOnInfoListener(MediaRecorder.OnInfoListener listener)注冊一個用于記錄錄制時出現的信息事件
 getMaxAmplitude() 獲取在前一次調用此方法之后錄音中出現的最大振幅
 prepare()準備錄制。
 release()釋放資源
 reset()將MediaRecorder設為空閑狀態
 start()開始錄制
 stop()停止錄制
MediaRecorder主要配置參數:
1、視頻編碼格式MediaRecorder.VideoEncoder
    default,H263,H264,MPEG_4_SP,VP8
2、音頻編碼格式MediaRecorder.AudioEncoder
    default,AAC,HE_AAC,AAC_ELD,AMR_NB,AMR_WB,VORBIS
3、視頻資源獲取方式MediaRecorder.VideoSource
    default,CAMERA,SURFACE
4、音頻資源獲取方式MediaRecorder.AudioSource
    defalut,camcorder,mic,voice_call,voice_communication,voice_downlink,voice_recognition, voice_uplink
5、資源輸出格式MediaRecorder.OutputFormat
    amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp,aac_adif, aac_adts, output_format_rtp_avp, output_format_mpeg2ts ,webm
實現錄音的一般步驟:
1、實例化MediaRecorder mr,調用構造方法 
2、初始化mr:mr.setAudioSource(MIC)/setVideoSource(CAMERA) 
3、配置DataSource:設置輸出文件格式/路徑,編碼器等 
4、準備錄制:mr.prepare() 
5、開始錄制:mr.start() 
6、停止錄制:mr.stop() 
7、釋放資源:mr.release() 
注:2,3不可調換順序 
添加權限: 
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.RECORD_AUDIO"> 

二、MediaPlayer

Paste_Image.png
1、當一個MediaPlayer對象被創建或者調用reset()方法之后,它處于空閑狀態,調用release()方法后處于結束狀態。
  • 一個MediaPlayer對象調用了reset()方法后,再調用其它方法可能會觸發OnErrorListener.onError()事件,未調用reset()方法則不會觸發。
  • 當Mediaplayer對象不再被使用時,最好調用release()方法對其進行釋放,使其處于結束狀態,此時它不能被使用
  • Mediaplayer對象被創建時(調用構造方法)處于空閑狀態,若使用create()方法創建后則處于準備狀態。
2、 一般情況下,一些常用的播放控制操作可能因為音頻、視頻的格式不被支持或者質量較差以及流超時,也有可能由于開發者的疏忽使得Mediaplayer對象處于無效狀態等而導致錯誤。此時可通過注冊setOnErrorListener方法實現監控。如果發生了錯誤,Mediaplayer對象將處于多霧狀態,可以使用reset()方法來回復錯誤。
3、任何Mediaplayer對象都必須先處于準備狀態,然后才開始播放
4、要開始播放Mediaplayer對象都必須成功調用start()方法,可通過isPlaying()方法來檢測是否正在播放
5、當Mediaplayer對象在播放時,可以進行暫停和停止操作,pause()方法暫停播放,stop()方法停止播放。處于暫停暫停時可通過start()方法恢復播放,但是處于停止狀態時則必須先調用prepare()方法使其處于準備狀態,再調用start()方法。

主要方法:

  1. 實例化方式
    使用直接new的方式:
    MediaPlayer mp = new MediaPlayer();
    使用create的方式:
    MediaPlayer mp = MediaPlayer.create(this, R.raw.test);
  2. 設置播放源
setDataSource(String path)//指定裝載path路徑所代表的文件。
setDataSource(Context context, Uri uri, Map<String, String headers)//指定裝載uri所代表的文件。
setDataSource(Context context, Uri uri)//指定裝載uri所代表的文件。
setDataSource(FileDescriptor fd, long offset, long length)//指定裝載fd所代表的文件中從offset開始長度為length的文件內容。
setDataSource(FileDescriptor fd)//指定裝載fd所代表的文件。
  1. 配置播放參數
setAudioStreamType(int streamtype)//設置音頻流的類型。
setDisplay(SurfaceHolder sh)//設置顯示方式。
setLooping(boolean looping)//設置是否循環播放。
setNextMediaPlayer(MediaPlayer next)//設置當前流媒體播放完畢,下一個播放的MediaPlayer。
setScreenOnWhilePlaying(boolean screenOn)//設置是否使用SurfaceHolder來顯示。
setSurface(Surface surface)//設置Surface。
setVideoScalingMode(int mode)//設置視頻縮放的模式。
setVolume(float leftVolume, float rightVolume)//設置播放器的音量。
setWakeMode(Context context, int mode)//為MediaPlayer設置低級電源管理行為。
  1. 播放控制函數
start()//開始或恢復播放。
stop()//停止播放。
pause()//暫停播放。
prepare()//準備播放(裝載音頻),調用此方法會使MediaPlayer進入Prepared狀態。
prepareAsync()//準備播放異步音頻。
release()//釋放媒體資源
reset()//重置MediaPlayer進入未初始化狀態。
seekTo(int msec)//指定的時間位置。
  1. 監聽事件函數
setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)//注冊一個回調函數,在網絡視頻流緩沖變化時調用。
setOnCompletionListener(MediaPlayer.OnCompletionListener listener)//為Media Player的播放完成事件綁定事件監聽器。
setOnErrorListener(MediaPlayer.OnErrorListener listener)//為MediaPlayer的播放錯誤事件綁定事件監聽器。
setOnPreparedListener(MediaPlayer.OnPreparedListener listener)//當MediaPlayer調用prepare()方法時觸發該監聽器。
setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener)//當MediaPlayer調用seek()方法時觸發該監聽器。
setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)//注冊一個用于監聽視頻大小改變的監聽器。
  1. 獲取參數函數
getCurrentPosition()//獲取當前播放的位置。
getDuration()//獲取音頻的時長。
getVideoHeight()//獲取視頻的高度。
getVideoWidth()//獲取視頻的寬度。
isLooping()//判斷MediaPlayer是否正在循環播放。
isPlaying()//判斷MediaPlayer是否正在播放。

三、AudioRecord

  1. AudioRecord 的工作流程
(1) 配置參數,初始化內部的音頻緩沖區
(2) 開始采集
(3) 需要一個線程,不斷地從 AudioRecord 的緩沖區將音頻數據“讀”出來,注意,這個過程一定要及時,否則就會出現“overrun”的錯誤,該錯誤在音頻開發中比較常見,意味著應用層沒有及時地“取走”音頻數據,導致內部的音頻緩沖區溢出。
(4) 停止采集,釋放資源
  1. AudioRecord 的參數配置
  • audioSource
    該參數指的是音頻采集的輸入源,可選的值以常量的形式定義在 MediaRecorder.AudioSource 類中,常用的值包括:DEFAULT(默認),VOICE_RECOGNITION(用于語音識別,等同于DEFAULT),MIC(由手機麥克風輸入),VOICE_COMMUNICATION(用于VoIP應用)等等。
  • sampleRateInHz
    采樣率,注意,目前44100Hz是唯一可以保證兼容所有Android手機的采樣率。
  • channelConfig
    通道數的配置,可選的值以常量的形式定義在 AudioFormat 類中,常用的是 CHANNEL_IN_MONO(單通道),CHANNEL_IN_STEREO(雙通道)。
  • audioFormat
    這個參數是用來配置“數據位寬”的,可選的值也是以常量的形式定義在 AudioFormat 類中,常用的是 ENCODING_PCM_16BIT(16bit),ENCODING_PCM_8BIT(8bit),注意,前者是可以保證兼容所有Android手機的。

四、AudioTrack

  1. ** AudioTrack 的工作流程**
(1) 配置參數,初始化內部的音頻播放緩沖區
(2) 開始播放
(3) 需要一個線程,不斷地向 AudioTrack 的緩沖區“寫入”音頻數據,注意,這個過程一定要及時,否則就會出現“underrun”的錯誤,該錯誤在音頻開發中比較常見,意味著應用層沒有及時地“送入”音頻數據,導致內部的音頻播放緩沖區為空。
(4) 停止播放,釋放資源
  1. ** AudioTrack 的參數配置**
  • streamType
    這個參數代表著當前應用使用的哪一種音頻管理策略,當系統有多個進程需要播放音頻時,這個管理策略會決定最終的展現效果,該參數的可選的值以常量的形式定義在 AudioManager 類中,主要包括:
STREAM_VOCIE_CALL:電話聲音
STREAM_SYSTEM:系統聲音
STREAM_RING:鈴聲
STREAM_MUSCI:音樂聲
STREAM_ALARM:警告聲
STREAM_NOTIFICATION:通知聲
  • sampleRateInHz
    采樣率,從AudioTrack源碼的“audioParamCheck”函數可以看到,這個采樣率的取值范圍必須在 4000Hz~192000Hz 之間。
  • mode
    AudioTrack 提供了兩種播放模式,一種是 static 方式,一種是 streaming 方式,前者需要一次性將所有的數據都寫入播放緩沖區,簡單高效,通常用于播放鈴聲、系統提醒的音頻片段; 后者則是按照一定的時間間隔不間斷地寫入音頻數據,理論上它可用于任何音頻播放的場景。
    可選的值以常量的形式定義在 AudioTrack 類中,一個是 MODE_STATIC,另一個是 MODE_STREAM,根據具體的應用傳入對應的值即可。

五、SoundPool

soundlPool 用于播放比較短的音頻片段,比如游戲聲音、按鍵聲、鈴聲片段等等,它可以同時播放多個音頻。

主要方法:

  1. 構造實例
    SoundPool(int maxStreams, int streamType, int srcQuality) 參數依次是:
    ①指定支持多少個聲音,SoundPool對象中允許同時存在的最大流的數量,該值太大就會報錯AudioFlinger could not create track, status: -12 ,就聽不到聲音
    ②指定聲音類型,流類型可以分為STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和STREAM_ALARM四種類型。在AudioManager中定義。
    ③指定聲音品質(采樣率變換質量),一般直接設置為0!
      在低版本中可以用上述構造方法,而API 21(Android 5.0)后這個構造方法就過時了! 而用到一個SoundPool.Builder的東東,我們要實例化SoundPool只需調用:
SoundPool.Builder spb = new SoundPool.Builder();
spb.setMaxStreams(10);
spb.setAudioAttributes(null);    //轉換音頻格式
SoundPool sp = spb.build();      //創建SoundPool對象
  1. 加載聲音資源文件
load(Context context, int resId, int priority) //從APK資源載入
load(String path, int priority)
load(FileDescriptor fd, long offset, long length, int priority)
load(AssetFileDescriptor afd, int priority)

參數介紹

context:上下文
resId:資源id,如從raw文件獲取填寫R.raw.xxx
priority:沒什么用的一個參數,建議設置為1,保持和未來的兼容性
path:文件路徑,文件的絕對路線,如存放在sd卡中的音頻
FileDescriptor:文件描述符
AssetFileDescriptor:從asset目錄讀取某個資源文件,context.getAssets().openFd("xxx"),xxx表示文件名

上述方法都會返回一個聲音的ID,Integer類型,我們可以通過建立一個Map<Integer,Integer> 來存儲和獲取聲音方法如下,

Map<Integer,Integer> map=new HashMap<Integer, Integer>();
map.put(1,soundPool.load(context.getAssets().openFd("FadeOut.ogg"),1));
  1. 播放音頻文件
    play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate),其返回值為一個int類型的數字
    參數依次是:
soundID:Load()返回的聲音ID號,以上可以通過map.get(1)獲取
leftVolume:左聲道音量設置  一般為0-1,默認填1
rightVolume:右聲道音量設置 一般為0-1,默認填1
priority:指定播放聲音的優先級,數值越高,優先級越大。默認填0
loop:指定是否循環:-1表示無限循環,0表示不循環,其他值表示要重復播放的次數
rate:指定播放速率:1.0的播放率可以使聲音按照其原始頻率,而2.0的播放速率,可以使聲音按照其 原始頻率的兩倍播放。如果為0.5的播放率,則播放速率是原始頻率的一半。播放速率的取值范圍是0.5至2.0。

如果SoundPool剛調完加載load函數之后,直接調用SoundPool的play函數可能出現error "sample 1 not READY",所以建議,調用加載資源函數load之后,實現資源加載結束的監聽函數,在這個監聽到資源加載結束之后,播放音頻文件。

soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                soundPool.play(map.get(1),1,1,0,0,1);
            }
        });
  1. 去除音頻或者停止播放重置資源
soundPool.pause(int streamID)  暫停指定播放流的音效
streamID:應通過play()返回
soundPool.resume(int streamID)  繼續播放指定播放流的音效
streamID:應通過play()返回
soundPool.stop(int streamID) 終止指定播放流的音效
streamID:應通過play()返回
soundPool.unload(int soundID) 卸載一個指定的音頻資源.
soundID:Load()返回的聲音ID號,以上可以通過map.get(1)獲取
 soundPool.release(); 釋放SoundPool中的所有音頻資源.

注意:

  1. play()函數傳遞的是一個load()返回的soundID——指向一個被記載的音頻資源 ,如果播放成功則返回一個非0的streamID——指向一個成功播放的流 ;同一個soundID 可以通過多次調用play()而獲得多個不同的streamID (只要不超出同時播放的最大數量);
  2. pause()、resume()和stop()是針對播放流操作的,傳遞的是play()返回的streamID ;
  3. play()中的priority參數,只在同時播放的流的數量超過了預先設定的最大數量是起作用,管理器將自動終止優先級低的播放流。如果存在多個同樣優先級的流,再進一步根據其創建事件來處理,新創建的流的年齡是最小的,將被終止;
  4. 無論如何,程序退出時,手動終止播放并釋放資源是必要的。
  5. 如果你音效多,也不要指望unload方法來清除掉一些音效后再load新的進去,雖然unload后音效卸載了,但是前面分給它在SoundPool里面的Id可沒有釋放掉,也就是說這個時候你load新的進去只會在后面繼續累加,然后累加多了就超過256了,然后就就聽不到聲音,然后就沒有然后了。要想徹底清掉前面的音效請使用release方法,它會連內存中占用的資源一起釋放掉。
  6. 其他還有點什么呢,load需要一點點時間,load后不要馬上unload,load ---play--unload的做法并不可取,不要load太大的音效,它只會申請1M的內存空間。SoundPool出錯后通常會看到return的值是0。

五、MediaRecorder 和 AudioRecord的選擇

Android SDK 提供了兩套音頻采集的API,分別是:MediaRecorder 和 AudioRecord,前者是一個更加上層一點的API,它可以直接把手機麥克風錄入的音頻數據進行編碼壓縮(如AMR、MP3等)并存成文件,而后者則更接近底層,能夠更加自由靈活地控制,可以得到原始的一幀幀PCM音頻數據。

如果想簡單地做一個錄音機,錄制成音頻文件,則推薦使用 MediaRecorder,而如果需要對音頻做進一步的算法處理、或者采用第三方的編碼庫進行壓縮、以及網絡傳輸等應用,則建議使用 AudioRecord,其實 MediaRecorder 底層也是調用了 AudioRecord 與 Android Framework 層的 AudioFlinger 進行交互的。

音頻的開發,更廣泛地應用不僅僅局限于本地錄音,因此,我們需要重點掌握如何利用更加底層的 AudioRecord API 來采集音頻數據(注意,使用它采集到的音頻數據是原始的PCM格式,想壓縮為mp3,aac等格式的話,還需要專門調用編碼器進行編碼)。

六、MediaPlayer,SoundPool和AudioTrack的選擇

MediaPlayer 更加適合在后臺長時間播放本地音樂文件或者在線的流式資源;
SoundPool 則適合播放比較短的音頻片段,比如游戲聲音、按鍵聲、鈴聲片段等等,它可以同時播放多個音頻;
而 AudioTrack 則更接近底層,提供了非常強大的控制能力,支持低延遲播放,適合流媒體和VoIP語音電話等場景。

七、播放視頻 VideoView

主要方法:

getBufferPercentage:得到緩沖的百分比 
getCurrentPosition:得到當前播放位置 
getDuration:得到視頻文件的時間 
resolveAdjustedSize:調整視頻顯示大小 
setMediaController:設置播放控制器模式(播放進度條) 
setOnCompletionListener:當視頻文件播放完時觸發事件 
setVideoPath:設置視頻源路徑 
setVideoURI:設置視頻源地址 

八、相機Camera

Camera回調事件
  1. android.hardware.Camera.AutoFocusCallback
    當自動對焦時候調用,該接口具有一個void onAutoFocus(boolean success,Camera camera)函數;
  2. android.hardware.Camera.ErrorCallback
    攝像頭出錯的時候調用,這個接口具有一個void onError(int error,Camera camera)函數;前者表示數據類型,取值是Camera類中的常量CAMERA_ERROR_UNKNOWN或者是 CAMERA_ERROR_SERVICE_DIED;
    前者是不明錯誤,后者是表示服務已經關閉,在這種情況下需要釋放當前的Camera對象,然后再初 始化一個。
  3. android.hardware.camera.PreviewCallback
    在圖像預覽時調用,這個接口有一個void onPreviewFrame(byte[] data,Camera camera);參數data為每幀圖像的數據流。我們可以根據實際需要來實現這個接口。
  4. android.hardware.Camera.ShutterCallback
    在圖像預覽的時候調用,這個接口具有一個void onShutter();
    可以在改函數中通知用戶快門已經關閉,例如播放一個聲音。
  5. android.hardware.Camera.PictureCallback
    當拍攝相片的時候調用,該接口具有一個void onPictureTaken(byte[] data,Camera camera)函數;參數和預覽的一樣。在android中主要有三個類實現了這個接口,分別是PostViewPictureCallback、 RawPictureCallback、JepgPictureCallback。我們可以根據需要定義自己需要的類。
  6. 還提供了放大縮小的監聽器android.hardware.Camera.OnZoomChangeListener
private final class ZoomListener implements android.hardware.Camera.OnZoomChangeListener {
public void onZoomChange(int value, boolean stopped, android.hardware.Camera camera) ;
Camera.Parameters 相機的屬性參數

通過Camera.open(int cameraId)啟動相機服務,然后通過Camera對象的getParameters()函數來得到一個android.hardware.Camera.Parameters 對象,Parameters提供了一些接口來設置Camera的屬性:

  1. setPictureFormat(int pixel_format)
    設置圖片的格式,其取值為ImageFormat.JPEG、ImageFormat.RGB_565或者ImageFormat.FLEX_RGB_888等格式。
  2. setPreviewFormat(int pixel_format)
    設置圖片的預覽格式,取值如上。
  3. setPictureSize(int width,int height)
    設置圖片的高度和寬度,單位為像素。
  4. setPreviewSize(int width,int height)
    設置預覽的高度和寬度,取值如上。
  5. setPreviewFrameRate(int fps)
    設置圖片預覽的幀速。
  6. setFocusMode(String value)
    設置聚焦模式,如Camera.Parameters.FOCUS_MODE_AUTO。
Camera類的方法

在設置好Camera的參數后,通過以下方法可執行相應操作。

  1. camera.startPreview()
    開始預覽圖像。
  2. camera.autoFocus(AutoFocusCallback cb)
    自動對焦。
  3. camera.takePicture(ShutterCallback shutter, PictureCallback raw, PictureCallback jpeg)
    執行拍照。
    注:takePicture方法要實現3個回調函數作為它的三個參數:Camera.ShutterCallback(快門回調接口),和兩個Camera.Picture.Callback(原生圖像數據接口和壓縮格式圖片數據接口)。
    需要許可
    <uses-permission android:name="android.permission.CAMERA" />
    若要將圖片存儲至sd卡中,則需要sd卡讀寫許可
  4. camera.stopPreview()
    停止預覽 。
  5. camera.release()
    釋放相機服務 。

九、鬧鐘設置AlarmManager

相關類:AlarmManager,它是專門用來設定在某個指定的時間去完成指定的事件。AlarmManager提供了訪問系統警報的服務,只要在程序中設置了警報服務,AlarmManager就會通過onReceive()方法去執行這些事件,就算系統處于待機狀態,同樣不會影響運行。可通過Context.getSystemService(ALARM_SERVICE)方法來獲得該服務。 
 方法說明: 
cancel:    取消AlarmManager服務 
set:    設置AlarmManager服務 
setInexactRepeating:設置不精確周期 
setRepeating:設置精確周期 
setTimeZone:設置時區 
 注:需創建一個BroadcastReceiver的子類,并覆蓋onReceive()方法 
 鈴聲設置 
 系統自帶的鈴聲都放在/system/medio/audio/文件夾中 
 鈴音類型: TYPE_RINGTONE(來電鈴音),TYPE_ALARM,TYPE_NOTIFICATION 
相關類:RingtoneManager 
方法介紹: 
getActualDefaultRingtoneUri:取得指定類型的鈴聲 
getCursor:返回所有可用鈴聲的游標 
getDefaultType:得到指定URI默認的鈴聲類型 
getRingtone 
 getRingtonePosition:得到鈴聲位置 
getRingtoneUri 
 getValidRingtoneUri:得到一個可用鈴聲的URI 
 isDefault:得到指定的Uri是否為默認的鈴聲 
setActualDefaultRingtoneUri:設置默認的鈴聲 

 獲取的Cursor共有4列,列名依次為:_id,title,”content://media/internal/audio/media”,title_key 
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容