轉載請註明出處:http://blog.csdn.net/vnanyesheshou/article/details/71713786
本文已授權微信公眾號 fanfan程序媛 獨家發布 掃一掃文章底部的二維碼或在微信搜索 fanfan程序媛 即可關註
本文主要是android做為Audio Source端,A2DP的基本操作:包括連接、斷開連接、設置優先級、獲取優先級、獲取A2DP連接狀態、獲取A2DP連接的設備列表等功能。
1 簡介 |
A2DP全名是Advanced Audio Distribution Profile,高質量音頻數據傳輸的協議,其定義裏了傳送單聲道或立體聲等高質量音頻(區別於藍牙SCO鏈路上傳輸的普通語音)信息的協議和過程。A2DP的典型應用是將音樂播放器的音頻數據發送到耳機或音箱。
A2DP定義了兩種角色:
Audio Source(音頻源) 音頻的輸入端對音頻數據進行編碼,發送到Sink端。
Audio Sink(音頻接收器) 接收到音頻數據後,進行解碼操作還原出音頻。
2 A2DP profile |
要想操作A2DP相關,首先要獲取A2DP代理對象,獲取代理對象的方法比較簡單,如下:
mBtAdapter = BluetoothAdapter.getDefaultAdapter(); if(!mBtAdapter.isEnabled()){ //彈出對話框提示用戶是後打開 Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enabler, 1); } //獲取A2DP代理對象 mBtAdapter.getProfileProxy(mContext, mListener, BluetoothProfile.A2DP);
getProfileProxy並不會直接返回A2DP代理對象,而是通過mListener中回調獲取。
private ServiceListener mListener = new ServiceListener() { @Override public void onServiceDisconnected(int profile) { if(profile == BluetoothProfile.A2DP){ mA2dp = null; } } @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { if(profile == BluetoothProfile.A2DP){ mA2dp = (BluetoothA2dp) proxy; //轉換 } } };
成功會回調mListener中的onServiceConnected函數,判斷proflie是否為BluetoothProfile.A2DP,轉換為BluetoothA2dp對象。通過代理對象即可進行A2DP的相關操作了。
3 A2DP操作 |
A2DP連接首先需要與藍牙耳機進行配對,如何配對這裏就不細說了。
我這裏是連接到之前配對過的一個設備。設備名稱為:
private final String BT_NAME = "QCY-QY7";
獲取該設備,首先獲取配對的藍牙設備,然後遍歷這些藍牙設備,找出藍牙名稱符合條件的設備,就是要操作的設備,
//獲取配對的藍牙設備 Set<BluetoothDevice> bondDevice = mBtAdapter.getBondedDevices(); for(BluetoothDevice device:bondDevice){ //獲取指定名稱的設備 if(BT_NAME.equals(device.getName())){ mConnectDevice = device; } }
mConnectDevice為要操作的設備。
1 A2DP連接
private void connectA2dp(BluetoothDevice device){ setPriority(mConnectDevice, 100); //設置priority try { //通過反射獲取BluetoothA2dp中connect方法(hide的),進行連接。 Method connectMethod =BluetoothA2dp.class.getMethod("connect", BluetoothDevice.class); connectMethod.invoke(mA2dp, device); } catch (Exception e) { e.printStackTrace(); } }
BluetoothA2dp中的connect方法是hide的,不能直接訪問,需要通過反射的機制獲取該方法進行連接。連接成功後手機可以播放音樂,聲音就會從藍牙耳機出來。
2 斷開連接
private void disConnectA2dp(BluetoothDevice device){ setPriority(mConnectDevice, 0); try { //通過反射獲取BluetoothA2dp中connect方法(hide的),斷開連接。 Method connectMethod =BluetoothA2dp.class.getMethod("disconnect", BluetoothDevice.class); connectMethod.invoke(mA2dp, device); } catch (Exception e) { e.printStackTrace(); } }
BluetoothA2dp中的disconnect方法也是hide的,與connect類似。
3 設置優先級
變量 | 值 |
---|---|
PRIORITY_OFF | 0 |
PRIORITY_ON | 100 |
PRIORITY_AUTO_CONNECT | 1000 |
PRIORITY_UNDEFINED | -1 |
設置優先級是必要的,否則可能導致連接或斷開連接失敗等問題。
public void setPriority(BluetoothDevice device, int priority) { if (mA2dp == null) return; try {//通過反射獲取BluetoothA2dp中setPriority方法(hide的),設置優先級 Method connectMethod =BluetoothA2dp.class.getMethod("setPriority", BluetoothDevice.class,int.class); connectMethod.invoke(mA2dp, device, priority); } catch (Exception e) { e.printStackTrace(); } }
4 獲取優先級
public int getPriority(BluetoothDevice device) { int priority = 0; if (mA2dp == null) return priority; try {//通過反射獲取BluetoothA2dp中getPriority方法(hide的),獲取優先級 Method connectMethod =BluetoothA2dp.class.getMethod("getPriority", BluetoothDevice.class); priority = (Integer) connectMethod.invoke(mA2dp, device); } catch (Exception e) { e.printStackTrace(); } return priority; }
5 獲取與某設備A2DP連接狀態
mA2dp.getConnectionState(device);
6 獲取連接設備列表
//返回值類型List<BluetoothDevice>
mA2dp.getConnectedDevices();
7 A2DP是否正在發送音頻流
//返回值類型boolean,表示設備是否在通過A2DP發送音頻流。
mA2dp.isA2dpPlaying(device);
4 狀態監聽 |
通過廣播接收者監聽A2DP連接狀態的改變,A2DP播放狀態的改變。
private void initReceiver(){ //註冊廣播接收者監聽狀態改變 IntentFilter filter = new IntentFilter(BluetoothA2dp. ACTION_CONNECTION_STATE_CHANGED); filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED); registerReceiver(mReceiver, filter); }
廣播接收者,通過intent獲取狀態值。
private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i(TAG,"onReceive action="+action); //A2DP連接狀態改變 if(action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)){ int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED); Log.i(TAG,"connect state="+state); }else if(action.equals(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED)){ //A2DP播放狀態改變 int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_NOT_PLAYING); Log.i(TAG,"play state="+state); } } };
有問題歡迎交流指正。
連接小demo:http://download.csdn.net/detail/vnanyesheshou/9841491
歡迎掃一掃關註我的微信公眾號,定期推送優質技術文章:
Tags: Android 音樂播放器 profile 二維碼 對話框
文章來源: