Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android如何判斷當前手機是否正在播放音樂,並獲取到正在播放的音樂的信息

Android如何判斷當前手機是否正在播放音樂,並獲取到正在播放的音樂的信息

編輯:關於Android編程

我想實現如下的場景,判斷當前Android手機上是否正在播放音樂,如果是,通過某個特定的手勢, 或者點擊某個按鍵,將當前我正在聽的音樂共享出去。 第一步,就是判斷當前是否有音樂正在播放。 最開始我想得有點復雜,以為要深入framework或更下層去做手腳才行,找了一下資料,發現AudioManager對外暴露了接口。 [java]   /** Checks whether any music is active. */   isMusicActive()   通過這個接口就可以判斷當前系統是否有音樂在播放了。   還有一個問題,如果我想在音樂一開始就已經播放的時候,就知道這個事件,以便進行特殊的處理。 再進一步看一下 AudioManager 的源碼,發現其中有如下方法: [java]      /**       *  Request audio focus.       *  Send a request to obtain the audio focus       *  @param l the listener to be notified of audio focus changes       *  @param streamType the main audio stream type affected by the focus request       *  @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request       *      is temporary, and focus will be abandonned shortly. Examples of transient requests are       *      for the playback of driving directions, or notifications sounds.       *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for       *      the previous focus owner to keep playing if it ducks its audio output.       *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such       *      as the playback of a song or a video.       *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}       */       public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint)     從字面意思來看:請求音頻焦點,再看這個函數的返回值: [java]      /**       * A failed focus change request.       */       public static final int AUDIOFOCUS_REQUEST_FAILED = 0;             /**       * A successful focus change request.       */       public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;     這個函數可能對我有幫助,進一步查一下Google官方的幫助:http://developer.android.com/training/managing-audio/audio-focus.html Managing Audio Focus With multiple apps potentially playing audio it's important to think about how they should interact. To avoid every music app playing at the same time, Android uses audio focus to moderate audio playback—only apps that hold the audio focus should play audio. Before your app starts playing audio it should request—and receive—the audio focus.  Likewise, it should know how to listen for a loss of audio focus and respond appropriately when that happens.   簡單地翻譯一下: 管理音頻焦點 多個應用都在播放音頻的可能性,所以考慮應用間如何交互非常重要。為避免每個音樂應用同時播放,Android使用音頻焦點來協調音頻的播放----只有獲取到音頻焦點的應用可以播放音頻。 在你的應用開始播放音頻之前,它應該先請求--並接收音頻焦點。同樣,它也應該知道當監聽到失去音頻焦點後如何合理地進行響應。   沿著這個路應該是對的,寫了下面的測試代碼進行驗證。這個主要是Service的實現,你還需要實現一個Activity去啟動Service、結束Service: [java]   package com.example.servicetest;      import android.app.Service;   import android.content.Context;   import android.content.Intent;   import android.media.AudioManager;   import android.media.AudioManager.OnAudioFocusChangeListener;   import android.media.MediaPlayer;   import android.os.IBinder;   import android.util.Log;   import android.widget.Toast;      public class MainService extends Service   {       private static final String TAG = "MainService";              private MediaPlayer player;              private AudioManager mAm;              private MyOnAudioFocusChangeListener mListener;                 @Override       public void onCreate()       {           Log.i(TAG, "onCreate");                      player = MediaPlayer.create(this, R.raw.test);  // 在res目錄下新建raw目錄,復制一個test.mp3文件到此目錄下。           player.setLooping(false);                      mAm = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);           mListener = new MyOnAudioFocusChangeListener();       }                 @Override       public IBinder onBind(Intent intent)       {           return null;       }                 @Override       public void onStart(Intent intent, int startid)       {           Toast.makeText(this, "My Service Start", Toast.LENGTH_LONG).show();           Log.i(TAG, "onStart");                      // Request audio focus for playback           int result = mAm.requestAudioFocus(mListener,                   AudioManager.STREAM_MUSIC,                   AudioManager.AUDIOFOCUS_GAIN);                      if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED)           {               Log.i(TAG, "requestAudioFocus successfully.");                              // Start playback.               player.start();           }           else           {               Log.e(TAG, "requestAudioFocus failed.");           }       }                 @Override       public void onDestroy()       {           Toast.makeText(this, "My Service Stoped", Toast.LENGTH_LONG).show();           Log.i(TAG, "onDestroy");           player.stop();                      mAm.abandonAudioFocus(mListener);       }                 private class MyOnAudioFocusChangeListener implements               OnAudioFocusChangeListener       {           @Override           public void onAudioFocusChange(int focusChange)           {               Log.i(TAG, "focusChange=" + focusChange);           }       }   }     和 天天動聽 結合起來測試,先打開天天動聽播放音樂,再啟動這個Service,發現天天動聽自動暫停,再停止這個Service,天天動聽又開始播放了。 反過來,我先啟動這個Service,再播放、暫停天天動聽,“Log.i(TAG, "focusChange=" + focusChange);” 這個確實有輸出日志。   主流的音樂播放器,都遵循此規則的,所以通過使用Android的這個機制,我們就可以監控音樂的播放了。   還有一個問題,如何知道當前播放的音樂信息呢?兩個思路: 1、通過在後台自動截取音頻流的輸出,通過服務器進行聽歌識曲; 2、通過在SystemUI中攔截主流音樂播放器的通知;   第1個思路,從原理上是可行的,但是實現起來難度比較大,而且嚴重依賴網絡; 還是先來分析一下第2個思路。 先找主流的Android音樂播放器來做個簡單地測試,比如:天天動聽、QQ音樂、酷狗音樂、酷我音樂、百度音樂等,在播放過程中,都會向狀態欄中發一個Notification消息,其中已經包含歌曲信息。那我只需要做一個特殊的攔截並進行包名匹配,就可以獲取正在播放的音樂了。   具體思路如下: 1、實現一個服務,這個服務在Android手機啟動時,自動運行起來,通過 AudioManager.requestAudioFocus() 獲取音頻焦點,但什麼事都不干,只為有其它音樂播放器開始運行時,得到一個通知消息; 2、修改SystemUI,當主流音樂播放器發Notification到狀態欄時,從中獲取到音樂信息; 3、步驟1的Listener就可以集成到SystemUI中,這樣當音樂焦點被其它音樂播放器搶走後,再結合最近收到的Notification通知,這樣更准確一些;  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved