zoukankan      html  css  js  c++  java
  • Android连接蓝牙耳机播放音乐

    参考:

    Android实现主动连接蓝牙耳机

    具体实现:

        private static final String TAG = "BluetoothA2DPTest";
        private BroadcastReceiver mBroadcastReceiver;
        private BluetoothA2dp mBluetoothA2dp;
        private BluetoothAdapter mBluetoothAdapter;
        private String DEVICE_NAME = "KUWO_K1";
        private BluetoothDevice mBluetoothDevice;
        private MediaPlayer mMediaPlayer;
    
        private void initParameters(){
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if(mBluetoothAdapter == null){
                Log.e(TAG,"have no bluetooth adapter.");
                return;
            }
    
            if(!mBluetoothAdapter.isEnabled()){
                mBluetoothAdapter.enable();
            }else{
                //开始搜索附近蓝牙
                startDiscovery();
                //绑定BluetoothA2DP,获得service
                getBluetoothA2DP();
            }
    
            //监听广播
            mBroadcastReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    BluetoothDevice device;
                    switch (intent.getAction()) {
                        case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
                            //<editor-fold>
                            switch (intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1)) {
                                case BluetoothA2dp.STATE_CONNECTING:
                                    device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                    Log.i(TAG, "device: " + device.getName() +" connecting");
                                    break;
                                case BluetoothA2dp.STATE_CONNECTED:
                                    device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                    Log.i(TAG, "device: " + device.getName() +" connected");
                                    //连接成功,开始播放
                                    startPlay();
                                    break;
                                case BluetoothA2dp.STATE_DISCONNECTING:
                                    device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                    Log.i(TAG, "device: " + device.getName() +" disconnecting");
                                    break;
                                case BluetoothA2dp.STATE_DISCONNECTED:
                                    device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                                    Log.i(TAG, "device: " + device.getName() +" disconnected");
    //                                setResultPASS();
                                    break;
                                default:
                                    break;
                            }
                            //</editor-fold>
                            break;
                        case BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED:
                            //<editor-fold>
                            int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
                            switch (state) {
                                case BluetoothA2dp.STATE_PLAYING:
                                    Log.i(TAG, "state: playing.");
                                    break;
                                case BluetoothA2dp.STATE_NOT_PLAYING:
                                    Log.i(TAG, "state: not playing");
                                    break;
                                default:
                                    Log.i(TAG, "state: unkown");
                                    break;
                            }
                            //</editor-fold>
                            break;
                        case BluetoothDevice.ACTION_FOUND:
                            //<editor-fold>
                            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            int deviceClassType = device.getBluetoothClass().getDeviceClass();
                            //找到指定的蓝牙设备
                            if ((deviceClassType == BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET
                                    || deviceClassType == BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES)
                                    && device.getName().equals(DEVICE_NAME)) {
                                Log.i(TAG, "Found device:" + device.getName());
                                mBluetoothDevice = device;
                                //start bond,开始配对
                                createBond();
                            }
                            //</editor-fold>
                            break;
                        case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                            //<editor-fold>
                            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,BluetoothDevice.BOND_NONE);
                            device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                            switch (bondState){
                                case BluetoothDevice.BOND_BONDED:  //配对成功
                                    Log.i(TAG,"Device:"+device.getName()+" bonded.");
                                    mBluetoothAdapter.cancelDiscovery();  //取消搜索
                                    connect();  //连接蓝牙设备
                                    break;
                                case BluetoothDevice.BOND_BONDING:
                                    Log.i(TAG,"Device:"+device.getName()+" bonding.");
                                    break;
                                case BluetoothDevice.BOND_NONE:
                                    Log.i(TAG,"Device:"+device.getName()+" not bonded.");
                                    //不知道是蓝牙耳机的关系还是什么原因,经常配对不成功
                                    //配对不成功的话,重新尝试配对
                                    createBond();
                                    break;
                                default:
                                    break;
    
                            }
    
                            //</editor-fold>
                            break;
                        case BluetoothAdapter.ACTION_STATE_CHANGED:
                            //<editor-fold>
                            state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                            switch (state) {
                                case BluetoothAdapter.STATE_TURNING_ON:
                                   Log.i(TAG, "BluetoothAdapter is turning on.");
                                    break;
                                case BluetoothAdapter.STATE_ON:
                                    Log.i(TAG, "BluetoothAdapter is on.");
                                    //蓝牙已打开,开始搜索并连接service
                                    startDiscovery();
                                    getBluetoothA2DP();
                                    break;
                                case BluetoothAdapter.STATE_TURNING_OFF:
                                   Log.i(TAG, "BluetoothAdapter is turning off.");
                                    break;
                                case BluetoothAdapter.STATE_OFF:
                                   Log.i(TAG, "BluetoothAdapter is off.");
                                    break;
                            }
                            //</editor-fold>
                            break;
                        default:
                            break;
                    }
                }
            };
            IntentFilter filter = new IntentFilter();
            filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
            filter.addAction(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
            filter.addAction(BluetoothDevice.ACTION_FOUND);
            filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
            registerReceiver(mBroadcastReceiver, filter);
        }
    
    private void startDiscovery(){
           Log.i(TAG,"mBluetoothAdapter startDiscovery.");
            if(mBluetoothAdapter!=null && mBluetoothAdapter.isEnabled() && !mBluetoothAdapter.isDiscovering()){
                mBluetoothAdapter.startDiscovery();
            }
        }
    
        private void getBluetoothA2DP(){
            Log.i(TAG,"getBluetoothA2DP");
            if(mBluetoothAdapter == null){
                return;
            }
    
            if(mBluetoothA2dp != null){
                return;
            }
    
            mBluetoothAdapter.getProfileProxy(this, new BluetoothProfile.ServiceListener() {
                @Override
                public void onServiceConnected(int profile, BluetoothProfile proxy) {
                    if(profile == BluetoothProfile.A2DP){
                        //Service连接成功,获得BluetoothA2DP
                        mBluetoothA2dp = (BluetoothA2dp)proxy;
                    }
                }
    
                @Override
                public void onServiceDisconnected(int profile) {
    
                }
            },BluetoothProfile.A2DP);
        }
    
        private void createBond() {
            Log.i(TAG, "createBond");
            mBluetoothDevice.createBond();
        }
    
        //connect和disconnect都是hide方法,普通应用只能通过反射机制来调用该方法
        private void connect(){
            Log.i(TAG,"connect");
            if(mBluetoothA2dp == null){
                return;
            }
            if(mBluetoothDevice == null){
                return;
            }
    
            try {
                Method connect = mBluetoothA2dp.getClass().getDeclaredMethod("connect", BluetoothDevice.class);
                connect.setAccessible(true);
                connect.invoke(mBluetoothA2dp,mBluetoothDevice);
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                Log.e(TAG,"connect exception:"+e);
                e.printStackTrace();
            }
        }
    
        private void startPlay(){
            Log.i(TAG, "startPlay");
            AudioManager mAudioManager= (AudioManager)getSystemService(AUDIO_SERVICE);
            if(mAudioManager!=null){
                int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
                mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,maxVolume,0);
            }
            
            Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+ R.raw.speaker_test);
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.reset();
            try {
                mMediaPlayer.setDataSource(this,uri);
                mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        //播放完成,可以考虑断开连接
                        disconnect();
                    }
                });
                mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        Log.e(TAG, "Playback error.");
                        return false;
                    }
                });
                mMediaPlayer.prepare();
                mMediaPlayer.start();
            } catch(IllegalStateException|IOException e) {
                Log.e(TAG, "Exception: prepare or start mediaplayer");
                setResultFAIL();
            }
        }
    
        //程序退出前,要release播放器
        private void stopPlay(){
            Log.i(TAG,"stopPlay");
            if(mMediaPlayer!=null){
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    
        private void disconnect(){
            Log.i(TAG,"disconnect");
            if(mBluetoothA2dp == null){
                return;
            }
            if(mBluetoothDevice == null){
                return;
            }
    
            try {
                Method disconnect = mBluetoothA2dp.getClass().getDeclaredMethod("disconnect", BluetoothDevice.class);
                disconnect.setAccessible(true);
                disconnect.invoke(mBluetoothA2dp,mBluetoothDevice);
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                Log.e(TAG,"connect exception:"+e);
                e.printStackTrace();
            }
        }
    
        //取消配对
        private void unPairAllDevices(){
            Log.i(TAG,"unPairAllDevices");
            for(BluetoothDevice device:mBluetoothAdapter.getBondedDevices()){
                try {
                    Method removeBond = device.getClass().getDeclaredMethod("removeBond");
                    removeBond.invoke(device);
                } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    
        //注意,在程序退出之前(OnDestroy),需要断开蓝牙相关的Service
        //否则,程序会报异常:service leaks
        private void disableAdapter(){
            Log.i(TAG,"disableAdapter");
            if(mBluetoothAdapter == null){
                return;
            }
    
            if(mBluetoothAdapter.isDiscovering()){
                mBluetoothAdapter.cancelDiscovery();
            }
    
           //关闭ProfileProxy,也就是断开service连接
            mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP,mBluetoothA2dp);
            if(mBluetoothAdapter.isEnabled()){
                boolean ret = mBluetoothAdapter.disable();
                Log.i(TAG,"disable adapter:"+ret);
            }
        }
  • 相关阅读:
    #333 Div2 Problem B Approximating a Constant Range(尺取法)
    苦逼的单身狗(玄乎的尺取大法)
    欧拉项目第四题之三位数之积数的最大回数
    欧拉项目第三题之最大质数因子
    关于尺取法的认识与简单例题
    codeforces 980B Marlin
    康托展开和逆康托展开
    Chrome控制台中Network的Preview与Response区别
    配置Express中间件
    Express中间件简介
  • 原文地址:https://www.cnblogs.com/tt2015-sz/p/5616607.html
Copyright © 2011-2022 走看看