Android 蓝牙连接之 A2dp

      A2DPProfile  定义了高质量音频数据传输的协议和过程,包括立体声和单声道数据的传输。这里的高质量音频指的是单声道(Mono)和立体声(Sterco)  的音频,主要区别于蓝牙  SCO  链路上传输的普通语音。A2DP  的典型应用是将音乐播放器的音频数据发送到耳机或音箱。


  由于蓝牙提供的带宽较窄,音频数据可能需要进行有效的压缩才能保证接收端的实时播放。


  目前  A2DP 只定义了点对点的音频传输,没有定义广播式的音频传输,可能是由于速率的原因。
  A2DP 建立在 AVDTP 传输协议的基础之上,AVDTP 规定了链接是如何建立的,连接建立好之后,音频数据经过压缩之后,便可以收发了。

       直接上代码的吧,有很详细的注释,各位看官应该看起来问题不大:

public class BluetoothChatA2dpService {

    private BluetoothA2dp mA2dp;
    private String TAG = "BluetoothChatA2dpService";
    private BluetoothDevice mConnectDevice;
    private BluetoothAdapter mBtAdapter;
    private static Context mContext;
    private static BluetoothChatA2dpService bluetoothA2dpChatService;
    private int callBackState = 0;

    public interface OnConnectionListener {

        void onConnectionStateChanged(
                BluetoothDevice bluetoothDevice, int state);
    }

    public interface OnBluetoothA2dpReadyListener {

        void onBluetoothA2dpReady();
    }

    private OnBluetoothA2dpReadyListener onBluetoothA2dpReadyListener;

    public void setOnBluetoothA2dpReadyListener(OnBluetoothA2dpReadyListener listener) {
        onBluetoothA2dpReadyListener = listener;
    }

    private OnConnectionListener onConnectionListener;

    public void setOnConnectionListener(OnConnectionListener listener) {
        onConnectionListener = listener;
    }

    private BluetoothChatA2dpService() {
        initReceiver();
        initBluetooth();

    }

    public int getBluetoothDeviceA2dpStatus(BluetoothDevice bluetoothDevice) {
        if (mA2dp == null) {
            return -2;
        }
        return mA2dp.getConnectionState(bluetoothDevice);
    }

    private void initBluetooth() {
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBtAdapter.isEnabled()) {
            return;
        }
        //获取A2DP代理对象
        mBtAdapter.getProfileProxy(mContext, mListener, BluetoothProfile.A2DP);
    }

    private void initReceiver() {
        //广播接收者监听状态
        IntentFilter filter = new IntentFilter(BluetoothA2dp.
                ACTION_CONNECTION_STATE_CHANGED);
        filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
        mContext.registerReceiver(mReceiver, filter);
    }

    public static BluetoothChatA2dpService getInstance(Context context) {
        if (context != null) {
            mContext = context.getApplicationContext();

            if (bluetoothA2dpChatService == null) {
                bluetoothA2dpChatService = new BluetoothChatA2dpService();
            }
        } else {

            throw new RuntimeException("The context is null!");
        }

        return bluetoothA2dpChatService;
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //A2DP连接状态改变
            if (action != null) {
                if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
                    int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, BluetoothA2dp.STATE_DISCONNECTED);
                    callBackA2dpConnectState(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);
                }
            }
        }
    };

    private int callBackA2dpConnectState(int state) {
        if (onConnectionListener != null) {
            if (mA2dp == null) {
                //获取A2DP代理对象
                mBtAdapter.getProfileProxy(mContext, mListener, BluetoothProfile.A2DP);
            }
            if (state == BluetoothA2dp.STATE_DISCONNECTED) {
                getDisconnectDevices();
                callBackState = ConnectionState.A2DP_DISCONNECTED;
            } else if (state == BluetoothA2dp.STATE_CONNECTING) {
                callBackState = ConnectionState.A2DP_CONNECTING;
            } else if (state == BluetoothA2dp.STATE_CONNECTED) {
                getConnectedDevices();
                callBackState = ConnectionState.A2DP_CONNECTED;
            } else {
                callBackState = state;

            }
            Log.i(TAG, "connect state=" + state);
            if (onConnectionListener != null) {
                onConnectionListener.onConnectionStateChanged(mConnectDevice, callBackState);
            }

        }
        return callBackState;
    }

    private void getConnectedDevices() {
        if (mA2dp != null && mA2dp.getConnectedDevices() != null && mA2dp.getConnectedDevices().size() > 0) {
            for (int i = 0; i < mA2dp.getConnectedDevices().size(); i++) {
                Log.i(TAG, "connect device=" + mA2dp.getConnectedDevices().get(i));
                mConnectDevice = mA2dp.getConnectedDevices().get(i);
            }
        }
    }

    private void getDisconnectDevices() {
        if (mA2dp != null && mA2dp.getConnectedDevices() != null && mA2dp.getConnectedDevices().size() > 0) {
            for (int i = 0; i < mA2dp.getConnectedDevices().size(); i++) {
                Log.i(TAG, "connect device=" + mA2dp.getConnectedDevices().get(i));
                mConnectDevice = mA2dp.getConnectedDevices().get(i);
                getA2dpConnectState();
            }
        }
    }

    private BluetoothProfile.ServiceListener mListener = new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceDisconnected(int profile) {
            Log.i(TAG, "onServiceDisconnected profile=" + profile);
            if (profile == BluetoothProfile.A2DP) {
                mA2dp = null;
            }
        }

        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            Log.i(TAG, "onServiceConnected profile=" + profile);
            if (profile == BluetoothProfile.A2DP) {
                mA2dp = (BluetoothA2dp) proxy; //转换
                if (onBluetoothA2dpReadyListener != null) {
                    onBluetoothA2dpReadyListener.onBluetoothA2dpReady();
                }
            }
        }
    };

    public BluetoothDevice getCurrentConnectedA2dpDevice() {
        return mConnectDevice;
    }


    public void connectA2dp(BluetoothDevice device) {
        Log.i(TAG, "connect to device :" + device);
        mConnectDevice = device;
        setPriority(device, 100); //设置priority
        try {
            //通过反射获取BluetoothA2dp中connect方法(hide的),进行连接。
            Method connectMethod = BluetoothA2dp.class.getMethod("connect",
                    BluetoothDevice.class);
            connectMethod.invoke(mA2dp, device);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void disConnectA2dp(BluetoothDevice device) {
        mConnectDevice = null;
        setPriority(device, 0);
        try {
            //通过反射获取BluetoothA2dp中connect方法(hide的),断开连接。
            Method connectMethod = BluetoothA2dp.class.getMethod("disconnect",
                    BluetoothDevice.class);
            connectMethod.invoke(mA2dp, device);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    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;
    }

    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();
        }
    }

    public boolean isA2dpConnect(){
        if(mA2dp != null && callBackState == ConnectionState.A2DP_CONNECTED){
            return true;
        }
        return false;
    }

    public boolean isNativeA2dpConnect(){
        LogManager.i(TAG, "isNativeA2dpConnect =  " + mBtAdapter.getProfileConnectionState(BluetoothProfile.A2DP));
        if(mA2dp!= null && mBtAdapter.getProfileConnectionState(BluetoothProfile.A2DP) == BluetoothA2dp.STATE_CONNECTED){
            return true;
        }
        return false;
    }

    public int getA2dpConnectState() {
        int a2dpState = 0;
        if (mBtAdapter.isEnabled()) {

            a2dpState = mBtAdapter.getProfileConnectionState(BluetoothProfile.A2DP); // 可操控蓝牙设备,如带播放暂停功能的蓝牙耳机
            LogManager.i(TAG, "getA2dpConnectState  当前a2dp状态为 =  " + a2dpState);
        } else {
            LogManager.e(TAG, "蓝牙未开启,查询蓝牙a2dp状态失败");
        }

        return callBackA2dpConnectState(a2dpState);
    }
}

使用:

BluetoothChatA2dpService.getInstance(this).connectA2dp(device)

最后祝大家国庆快乐!

猜你喜欢

转载自blog.csdn.net/SophieBryant/article/details/82909375