zoukankan      html  css  js  c++  java
  • Android学习笔记——Bluetooth的使用

    蓝牙应该是现在每一部智能手机的标配了。想当年在山寨机横行的年代里,蓝牙都可以做为一个卖点~~~

    废话不多说了,进入正题:

    使用蓝牙功能是需要权限的,关于蓝牙的权限也就两个:

    <uses-permission android:name=”android.permission.BLUETOOTH” />
    
    <uses-permission android:name=”android.permission.BLUETOOTH_ADMIN” />

    第一个是最基本的,打开蓝牙,请求连接,接受连接都需要这个。

    每二个从字面上看都觉得高级一点,它主要用于像建立搜索、对蓝牙进行设置这些操作。

    添加好权限之后就可以开始使用了

    Android系统为我们提供了一个功能极其强大的类用于进行蓝牙操作,这个类就是BluetoothAdapter。通过这个类的方法可以满足我们的大多数操作了。

    要获得这个类的对象我们可以直接调用它的一个静态方法getDefaultAdapter()。顺便看看它的源码是怎样的吧:

    public static synchronized BluetoothAdapter getDefaultAdapter() {
        if (sAdapter == null) {
            IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
            if (b != null) {
                IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
                sAdapter = new BluetoothAdapter(managerService);
            } else {
                Log.e(TAG, "Bluetooth binder is null");
            }
        }
        return sAdapter;
    }

    典型的单例模式:

    打开蓝牙

    首先要先确实您的设备是否有蓝牙,这个验证还是很有必要的,因为我们要考虑到我们的应用不一定就是给手机用的,也可能是平板之类的。

    private boolean isBluetoothAvaliable() {
        return BluetoothAdapter.getDefaultAdapter() != null;
    }

    我们一般打开蓝牙会使用到系统提供的一个Activity。这个Activity的action为:BluetoothAdapter.ACTION_REQUEST_ENABLE。

    然后我们要使用startActivityForResult()这个方法来启动它。

    这个Activity是有返回值的,如果用户选择的是打开,我们应该可以收到一个RESULT_OK

    如果用户选择的是取消,我们应该可以收到一个RESULT_CANCELED。

    比如像下面的这一段代码:

    public void openBluetooth() {
        Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBT, 1);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == RESULT_OK) {
                System.out.println("蓝牙已打开");
            } else if (resultCode == RESULT_CANCELED) {
                System.out.println("取消打开");
            }
        }
    }

    监听蓝牙状态的变化

    当蓝牙的状态发生改变时,系统是会发出一个为BluetoothAdapter.ACTION_STATE_CHANGED的广播。

    该广播携带两个参数,一个是BluetoothAdapter.EXTRA_PREVIOUS_STATE,表示之前的蓝牙状态。

    另一个是BluetoothAdapter.EXTRA_STATE,表示当前的蓝牙状态。而它们的值为以下四个:

    BluetoothAdapter.STATE_TURNING_ON;

    BluetoothAdapter.STATE_ON;

    BluetoothAdapter.STATE_TURNING_OFF;

    BluetoothAdapter.STATE_OFF;

    分别代表,打开中,已打开,关闭中,已关闭。

    private class BluetoothStateListener extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            String msg = null;
            switch (state) {
            case BluetoothAdapter.STATE_TURNING_ON:
                msg = "turning on";
                break;
            case BluetoothAdapter.STATE_ON:
                msg = "on";
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                msg = "turning off";
                break;
            case BluetoothAdapter.STATE_OFF:
                msg = "off";
                break;
            }
            System.out.println(msg);
        }
    }
    
    protected void onResume() {
        super.onResume();
        // 蓝牙开闭状态接收器
        listener = new BluetoothStateListener();
        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(listener, filter);
    }

    当然在程序中的某刻,我们可以调用BludetoothAdapter的getState()这个方法,该方法的返回值为上面的四个中的一个,不再赘述。

    查找蓝牙设备

    这个关于查找设备要分为两个部分,一个是已绑定的设备,另一个是搜索新的设备。

    对于已绑定的设备,我们可以直接通过BluetoothAdapter的getBondedDevices()这个方法来获得。

    该方法返回的是一个Set<BluetoothDevice>我们可以直接从人获得我们需要的信息:

    public void getBoundedDevices() {
        System.out.println("getPairedDevices");
        // 这个要在打开蓝牙的情况下才可以,不然为空集
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> devices = adapter.getBondedDevices();
        for (BluetoothDevice device : devices) {
            System.out.println(device.getName() + " : " + device.getAddress());
        }
    }

    另外就是查找新的设备了,这时我们要调用startDiscovery()方法,这个方法并不会在我们的程序中执行,它是系统进程来的,然后通过异步发送广播的方式来通知。

    所以我们还要注册一个广播接收器来接收系统的广播,这个广播的action为BluetoothDevice.ACTION_FOUND。

    它携带两个值,一个是BluetoothDevice.EXTRA_DEVICE另一个是BluetoothDevice.EXTRA_CLASS分别表示哪一个具体的设备和这个设备的类型。

    private class BluetoothDeviceScanListener extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // 这里可以把我们的将我们的设备添加到一个列表中
            System.out.println(device.getName() + " : " + device.getAddress());
        }
    }

    在官方的文档中一直强调,查找设备这个动作是会消耗大量的系统资源的,而且它会大大减少蓝牙的可用带宽,所以当我们找到了目标设备后,应该由我们主动调用cancelDiscovery()这个方法来取消搜索,而不应该期待默认的搜索时间到了,由系统来取消搜索。

    设置可被搜索

    蓝牙的默认设置是不允许被搜索到的,这一点有时候挺蛋疼的。

    所以我们自己通过编程来实现打开可被搜索的选择,使用是很装简单的,也是调用系统的一个Activity。这个activity的action是BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE它同样是有返回值的。并且,这个我们可以通过BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION这个参数来指定可被搜索的时间。

    public void discoverable() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        // 这个可以用来设置时间
        intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
        startActivityForResult(intent, 2);
    }

    这个Activity还同时具有打开蓝牙的功能,所以我们并不需要先打开蓝牙,再设置可被发现的时间,一次就可以搞定。

    最后,这个状态的改变系统也是会发出广播的,我们可以注册一个广播接收器来捕捉这个状态的变化,或是通过调用BluetoothAdapter的getScanMod()这个方法来确定,和之前是一样的。不再细说了。

    (未定待续)

  • 相关阅读:
    C# DataGridview转换为DataTable
    未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序
    ORM(Object Relational Mapping)框架
    C#开发小技巧
    Windows系统中Oracle11g R2 版本数据库卸载
    world特殊控制符输入
    Java中生成帮助文档
    Java类——JDBC链接、并操作MySQL数据库
    Java——实现对密码进行MD5加密
    HTTP协议详解
  • 原文地址:https://www.cnblogs.com/yjiyjige/p/3242329.html
Copyright © 2011-2022 走看看