Android 蓝牙音箱开发

Android 蓝牙音箱开发

项目下载地址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
监听打开的结果:

    @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
2.关闭蓝牙:

     /**关闭蓝牙*/
     if (mBluetoothAdapter.isEnabled()) {
           mBluetoothAdapter.disable();
     }
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
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
开始的搜索:

     // 如果正在搜索,就先取消搜索
     if (mBluetoothAdapter.isDiscovering()) {
         mBluetoothAdapter.cancelDiscovery();
     }
     // 开始搜索蓝牙设备,搜索到的蓝牙设备通过广播返回
     mBluetoothAdapter.startDiscovery();
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
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
注册监听配对结果的广播(使用同上面的注册代码)

     /**注册搜索蓝牙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
开始配对

    /**
     * 开始配对蓝牙设备
     *
     * @param blueDevice
     */
    private void startPariBlue(BlueDevice blueDevice) {
        BlueUtils blueUtils = new BlueUtils(blueDevice);
        blueUtils.doPair();
    }
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
6.使用A2DP协议连接蓝牙设备:

连接设备


    /**
     * 开始连接蓝牙设备
     */
    private void contectBuleDevices() {
        /**使用A2DP协议连接设备*/
        mBluetoothAdapter.getProfileProxy(this, mProfileServiceListener, BluetoothProfile.A2DP);
    }
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
7.添加权限

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
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
请求权限的回调

    /**请求权限的回调:这里判断权限是否添加成功*/
     /**请求权限的回调:这里判断权限是否添加成功*/
    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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值