Android 藍芽開發(九)A2DP準系統

來源:互聯網
上載者:User

標籤:dcl   ace   als   equal   app   交流   log   int   type   

轉載請註明出處: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

歡迎掃一掃關注我的公眾號,定期推送優質技術文章:

Android 藍芽開發(九)A2DP準系統

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.