Android 蓝牙音箱开发

来源:互联网 发布:淘宝客微信发单软件 编辑:程序博客网 时间:2024/04/28 02:51
原址:http://blog.csdn.net/u012987546/article/details/52204542
项目下载地址:github

1.打开蓝牙:

      mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();      /**如果本地蓝牙没有开启,则开启*/      if (!mBluetoothAdapter.isEnabled()) {        // 我们通过startActivityForResult()方法发起的Intent将会在onActivityResult()回调方法中获取用户的选择,比如用户单击了Yes开启,        // 那么将会收到RESULT_OK的结果,        // 如果RESULT_CANCELED则代表用户不愿意开启蓝牙        Intent mIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);        startActivityForResult(mIntent, ENABLE_BLUE);       } else {           Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show();       }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

监听打开的结果:

    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == ENABLE_BLUE) {            if (resultCode == RESULT_OK) {                Toast.makeText(this, "蓝牙开启成功", Toast.LENGTH_SHORT).show();                getBondedDevices();            } else if (resultCode == RESULT_CANCELED) {                Toast.makeText(this, "蓝牙开始失败", Toast.LENGTH_SHORT).show();            }        } else {        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.关闭蓝牙:

     /**关闭蓝牙*/     if (mBluetoothAdapter.isEnabled()) {           mBluetoothAdapter.disable();     }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

3.设计蓝牙为可见:

     Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);     intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 180);//180可见时间     startActivity(intent);
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

4.收索蓝牙:

注册广播监听搜索的结果:

     /**注册搜索蓝牙receiver*/     mFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);     mFilter.addAction(BluetoothDevice.ACTION_FOUND);     mFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);     registerReceiver(mReceiver, mFilter);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

开始的搜索:

     // 如果正在搜索,就先取消搜索     if (mBluetoothAdapter.isDiscovering()) {         mBluetoothAdapter.cancelDiscovery();     }     // 开始搜索蓝牙设备,搜索到的蓝牙设备通过广播返回     mBluetoothAdapter.startDiscovery();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

监听搜索的结果:

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            /** 搜索到的蓝牙设备*/            if (action.equals(BluetoothDevice.ACTION_FOUND)) {                BluetoothDevice device = intent                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                // 搜索到的不是已经配对的蓝牙设备                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {                    BlueDevice blueDevice = new BlueDevice();                    blueDevice.setName(device.getName());                    blueDevice.setAddress(device.getAddress());                    blueDevice.setDevice(device);                    setDevices.add(blueDevice);                    blueAdapter.setSetDevices(setDevices);                    blueAdapter.notifyDataSetChanged();                    Log.d(MAINACTIVITY, "搜索结果......"+device.getName());                }                /**当绑定的状态改变时*/            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {                /**搜索完成*/            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {                setProgressBarIndeterminateVisibility(false);                Log.d(MAINACTIVITY, "搜索完成......");                hideProgressDailog();            }        }    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

5.配对蓝牙:

配对工具类

    public class BlueUtils {        public BlueUtils(BlueDevice blueDevice) {            this.blueDevice = blueDevice;        }        /**         * 配对         */        public void doPair() {                if(null == mOthHandler){                    HandlerThread handlerThread = new HandlerThread("other_thread");                    handlerThread.start();                    mOthHandler = new Handler(handlerThread.getLooper());                }                mOthHandler.post(new Runnable() {                    @Override                    public void run() {                        initSocket();   //取得socket                        try {                            socket.connect();   //请求配对        //                      mAdapterManager.updateDeviceAdapter();                        } catch (IOException e) {                            e.printStackTrace();                        }                    }                });        }        /**         * 取消蓝牙配对         * @param device         */        public static void unpairDevice(BluetoothDevice device) {            try {                Method m = device.getClass()                        .getMethod("removeBond", (Class[]) null);                m.invoke(device, (Object[]) null);            } catch (Exception e) {                Log.d("BlueUtils", e.getMessage());            }        }        /**         * 取得BluetoothSocket         */       private void initSocket() {            BluetoothSocket temp = null;            try {                Method m = blueDevice.getDevice().getClass().getMethod("createRfcommSocket", new Class[] {int.class});                temp = (BluetoothSocket) m.invoke(blueDevice.getDevice(), 1);                //怪异错误: 直接赋值给socket,对socket操作可能出现异常,  要通过中间变量temp赋值给socket            } catch (SecurityException e) {                e.printStackTrace();            } catch (NoSuchMethodException e) {                e.printStackTrace();            } catch (IllegalArgumentException e) {                e.printStackTrace();            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            }            socket = temp;        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

注册监听配对结果的广播(使用同上面的注册代码)

     /**注册搜索蓝牙receiver*/     mFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);     mFilter.addAction(BluetoothDevice.ACTION_FOUND);     mFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);     registerReceiver(mReceiver, mFilter);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

开始配对

    /**     * 开始配对蓝牙设备     *     * @param blueDevice     */    private void startPariBlue(BlueDevice blueDevice) {        BlueUtils blueUtils = new BlueUtils(blueDevice);        blueUtils.doPair();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

监听配对结果:(使用同上面的广播接收者)

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            String action = intent.getAction();            /** 搜索到的蓝牙设备*/            if (action.equals(BluetoothDevice.ACTION_FOUND)) {                .....                /**当绑定的状态改变时*/            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                switch (device.getBondState()) {                    case BluetoothDevice.BOND_BONDING:                        Log.d(MAINACTIVITY, "正在配对......");                        break;                    case BluetoothDevice.BOND_BONDED:                        Log.d(MAINACTIVITY, "完成配对");                        hideProgressDailog();                        /**开始连接*/                        contectBuleDevices();                        break;                    case BluetoothDevice.BOND_NONE:                        Log.d(MAINACTIVITY, "取消配对");                        Toast.makeText(MainActivity.this,"成功取消配对",Toast.LENGTH_SHORT).show();                        getBondedDevices();                        break;                    default:                        break;                }                /**搜索完成*/            } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {                ....            }        }    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

6.使用A2DP协议连接蓝牙设备:

连接设备

    /**     * 开始连接蓝牙设备     */    private void contectBuleDevices() {        /**使用A2DP协议连接设备*/        mBluetoothAdapter.getProfileProxy(this, mProfileServiceListener, BluetoothProfile.A2DP);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

监听连接的回调

    /**     * 连接蓝牙设备(通过监听蓝牙协议的服务,在连接服务的时候使用BluetoothA2dp协议)     */    private BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {        @Override        public void onServiceDisconnected(int profile) {        }        @Override        public void onServiceConnected(int profile, BluetoothProfile proxy) {            try {                if (profile == BluetoothProfile.HEADSET) {                    ....                } else if (profile == BluetoothProfile.A2DP) {                    /**使用A2DP的协议连接蓝牙设备(使用了反射技术调用连接的方法)*/                    a2dp = (BluetoothA2dp) proxy;                    if (a2dp.getConnectionState(currentBluetoothDevice) != BluetoothProfile.STATE_CONNECTED) {                        a2dp.getClass()                                .getMethod("connect", BluetoothDevice.class)                                .invoke(a2dp, currentBluetoothDevice);                        Toast.makeText(MainActivity.this,"请播放音乐",Toast.LENGTH_SHORT).show();                        getBondedDevices();                    }                }            } catch (Exception e) {                e.printStackTrace();            }        }    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

7.添加权限

    <uses-permission android:name="android.permission.BLUETOOTH" />    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  • 1
  • 2
  • 1
  • 2

8.打开乐库播放音乐

9.Android 6.0的系统需要动态添加权限才能搜索出蓝牙设备

Android 6.0的系统需要动态添加权限

    /**判断手机系统的版本*/    if (Build.VERSION.SDK_INT >= 6.0) {//Build.VERSION.SDK_INT >= Build.VERSION_CODES.M            if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){                /**动态添加权限:ACCESS_FINE_LOCATION*/                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},                        MY_PERMISSION_REQUEST_CONSTANT);            }        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

请求权限的回调

    /**请求权限的回调:这里判断权限是否添加成功*/     /**请求权限的回调:这里判断权限是否添加成功*/    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {        switch (requestCode) {            case MY_PERMISSION_REQUEST_CONSTANT: {                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {                    Log.i("main","添加权限成功");                }                return;            }        }    }
0 0