zoukankan      html  css  js  c++  java
  • Android BLE 蓝牙编程(二)

    大家中秋快乐啊~~哈哈,今天继续工程项目吧!

    上篇我们已经实现了蓝牙设备的扫描,本篇我们来通过list展示扫描到的设备并

    实现点击连接。

    先贴出上篇的完整的MainActivity的方法:

    package com.wbnq.shouhuan;
    
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothManager;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private Button saomiao , duanzhen , changzhen , buting , tingxia;
        private TextView jibu , dianliang , lianjiezhuangtai;
    
        BluetoothAdapter bluetoothAdapter;
        List<BluetoothDevice> deviceList = new ArrayList<>();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initView();
    
            //蓝牙管理,这是系统服务可以通过getSystemService(BLUETOOTH_SERVICE)的方法获取实例
            BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
            //通过蓝牙管理实例获取适配器,然后通过扫描方法(scan)获取设备(device)
            bluetoothAdapter = bluetoothManager.getAdapter();
    
    
        }
    
        private void initView() {
            saomiao = (Button) findViewById(R.id.saomiao);
            duanzhen = (Button) findViewById(R.id.zhendong);
            changzhen = (Button) findViewById(R.id.changzhen);
            buting = (Button) findViewById(R.id.buting);
            tingxia = (Button) findViewById(R.id.tingxia);
    
            jibu = (TextView) findViewById(R.id.jibu);
            dianliang = (TextView) findViewById(R.id.dianliang);
            lianjiezhuangtai = (TextView) findViewById(R.id.lianjiezhuangtai);
    
            saomiao.setOnClickListener(this);
            duanzhen.setOnClickListener(this);
            changzhen.setOnClickListener(this);
            buting.setOnClickListener(this);
            tingxia.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.saomiao:
                    //开始扫描前开启蓝牙
                    Intent turn_on = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(turn_on, 0);
                    Toast.makeText(MainActivity.this, "蓝牙已经开启", Toast.LENGTH_SHORT).show();
    
                    Thread scanThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i("TAG", "run: saomiao ...");
                            saomiao();
                        }
                    });
                    scanThread.start();
    
                    break;
                case R.id.zhendong:
    
                    break;
                case R.id.changzhen:
    
                    break;
                case R.id.buting:
    
                    break;
                case R.id.tingxia:
    
                    break;
    
            }
        }
    
        public void saomiao(){
            deviceList.clear();
            bluetoothAdapter.startLeScan(callback);
        }
    
        //扫描回调
        public BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
                Log.i("TAG", "onLeScan: " + bluetoothDevice.getName() + "/t" + bluetoothDevice.getAddress() + "/t" + bluetoothDevice.getBondState());
    
                //重复过滤方法,列表中包含不该设备才加入列表中,并刷新列表
                if (!deviceList.contains(bluetoothDevice)) {
                    //将设备加入列表数据中
                    deviceList.add(bluetoothDevice);
                }
    
            }
        };
    }
    View Code

    这是上篇的,没有在log下看到扫描消息的小伙伴看看出啥问题了吧~~

    好了,第二篇正式开始。

    先贴出来MyAdapter的代码(这不是本节重点,请参阅前面关于adapter的写法)

    package com.wbnq.shouhuan;
    
    import android.bluetooth.BluetoothDevice;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import java.util.List;
    
    /**
     * Created by guwei on 16-9-2.
     */
    public class MyAdapter extends BaseAdapter{
    
        public List<BluetoothDevice> mlist;
        private LayoutInflater mInflater;
    
        public MyAdapter(Context context , List<BluetoothDevice> list){
            mlist = list;
            mInflater = LayoutInflater.from(context);
        }
    
        //获取传入的数组大小
        @Override
        public int getCount() {
            return mlist.size();
        }
    
        //获取第N条数据
        @Override
        public Object getItem(int i) {
            return mlist.get(i);
        }
    
        //获取item id
        @Override
        public long getItemId(int i) {
            return i;
        }
    
        //主要方法
        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder viewHolder = new ViewHolder();
            if(view == null){
                //首先为view绑定布局
                view = mInflater.inflate(R.layout.devices_item , null);
                viewHolder.name = (TextView) view.findViewById(R.id.bluetoothname);
                viewHolder.uuid = (TextView) view.findViewById(R.id.uuid);
                viewHolder.status = (TextView) view.findViewById(R.id.status);
    
                view.setTag(viewHolder);
            }else{
                viewHolder = (ViewHolder) view.getTag();
            }
            BluetoothDevice bd = mlist.get(i);
            viewHolder.name.setText(bd.getName());
            viewHolder.uuid.setText(bd.getAddress());
    
            //viewHolder.status.setText(R.string.noconnect);
            return view;
        }
    
        class ViewHolder{
            private TextView name , uuid , status;
        }
    }
    View Code

    item布局代码 devices_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/bluetoothicon"
            android:layout_width="37dp"
            android:layout_height="50dp"
            android:background="@mipmap/ic_bluetooth_black_36dp" />
    
        <TextView
            android:id="@+id/bluetoothname"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_toRightOf="@+id/bluetoothicon"
            android:text="name"
            android:textColor="#000000"
            android:textSize="19dp" />
    
        <TextView
            android:id="@+id/uuid"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/bluetoothname"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="5dp"
            android:layout_toRightOf="@id/bluetoothicon"
            android:text="uuid"
            android:textSize="15dp" />
    
        <TextView
            android:id="@+id/status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="5dp"
            android:layout_toRightOf="@id/bluetoothname"
            android:text=""
            android:textColor="#ff0000" />
    
    </RelativeLayout>
    View Code

    在布局文件中添加一下listview控件

    并且在MainActivity添加监听。

    然后在扫描回调中添加list.setAdapter(new MyAdapter(MainActivity.this , deviceList)); 

    就可以顺利的将得到的列表用list展示出来啦~~

    //扫描回调
        public BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
                Log.i("TAG", "onLeScan: " + bluetoothDevice.getName() + "/t" + bluetoothDevice.getAddress() + "/t" + bluetoothDevice.getBondState());
    
                //重复过滤方法,列表中包含不该设备才加入列表中,并刷新列表
                if (!deviceList.contains(bluetoothDevice)) {
                    //将设备加入列表数据中
                    deviceList.add(bluetoothDevice);
    
                    list.setAdapter(new MyAdapter(MainActivity.this , deviceList));
                }
    
            }
        };

    看下效果:点击扫描后

    想要连接设备就要在list的监听事件中添加下面的方法:

    这里的bluetoothdevice就是用来存放每个item的内容的

    上篇也说明了,想要连接设备就要使用bluetoothDevice的connectGatt方法:

    该方法包含三个参数:

    参数一 : context 上下文 这里传 MainActivity即可

    参数二: autoConnect 是否自动重连 一般填 false

    参数三: gattcallback 是BluetoothGattCallback回调,该方法由系统提供,我们只需要重写方法即可

    该方法的返回值为bluetoothGatt类型。

    //item 监听事件
            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    bluetoothDevice = deviceList.get(i);
                    //连接设备的方法,返回值为bluetoothgatt类型
                    bluetoothGatt = bluetoothDevice.connectGatt(MainActivity.this, false, gattcallback);
                    lianjiezhuangtai.setText("连接" + bluetoothDevice.getName() + "中...");
                }
            });

    重写gatt回调方法:

    BluetoothGattCallback

    private BluetoothGattCallback gattcallback = new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                super.onConnectionStateChange(gatt, status, newState);
            }
    
            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                super.onServicesDiscovered(gatt, status);
            }
    
            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicRead(gatt, characteristic, status);
            }
    
            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicWrite(gatt, characteristic, status);
            }
    
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicChanged(gatt, characteristic);
            }
    
            @Override
            public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                super.onDescriptorRead(gatt, descriptor, status);
            }
    
            @Override
            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                super.onDescriptorWrite(gatt, descriptor, status);
            }
    
            @Override
            public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
                super.onReliableWriteCompleted(gatt, status);
            }
    
            @Override
            public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
                super.onReadRemoteRssi(gatt, rssi, status);
            }
    
            @Override
            public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
                super.onMtuChanged(gatt, mtu, status);
            }
        } ;
    View Code

    我们这里主要用到

    onConnectionStateChange

    onServicesDiscovered

    onCharacteristicWrite

    首先通过onConnectionStateChange获取连接的状态:

    public void onConnectionStateChange(BluetoothGatt gatt, int status, final int newState) {
                super.onConnectionStateChange(gatt, status, newState);
    
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String status;
                        switch (newState) {
                            //已经连接
                            case BluetoothGatt.STATE_CONNECTED:
                                lianjiezhuangtai.setText("已连接");
    
                                //该方法用于获取设备的服务,寻找服务
                     //bluetoothGatt.discoverServices();
                                break;
                            //正在连接
                            case BluetoothGatt.STATE_CONNECTING:
                                lianjiezhuangtai.setText("正在连接");
                                break;
                            //连接断开
                            case BluetoothGatt.STATE_DISCONNECTED:
                                lianjiezhuangtai.setText("已断开");
                                break;
                            //正在断开
                            case BluetoothGatt.STATE_DISCONNECTING:
                                lianjiezhuangtai.setText("断开中");
                                break;
                        }
                        //pd.dismiss();
                    }
                });
            }

    参数中的 newstate就是连接的状态。

    连接状态一共分成四种:

    一: 已连接

    二: 正在连接

    三: 正在断开

    四: 已断开

    不过实际使用中正在连接和正在断开的状态并没有真正的返回给我们的程序,

    不过两个状态已经够我们使用了~

    连接状态通过连接状态的textview展示一下,我们现在快来看看效果吧~

    整体代码:

    MainActivity.class:

    package com.wbnq.shouhuan;
    
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothGatt;
    import android.bluetooth.BluetoothGattCallback;
    import android.bluetooth.BluetoothGattCharacteristic;
    import android.bluetooth.BluetoothGattDescriptor;
    import android.bluetooth.BluetoothManager;
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.Button;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private Button saomiao , duanzhen , changzhen , buting , tingxia;
        private TextView jibu , dianliang , lianjiezhuangtai;
        private ListView list;
    
        BluetoothAdapter bluetoothAdapter;
        BluetoothGatt bluetoothGatt;
        List<BluetoothDevice> deviceList = new ArrayList<>();
        BluetoothDevice bluetoothDevice;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initView();
    
            //蓝牙管理,这是系统服务可以通过getSystemService(BLUETOOTH_SERVICE)的方法获取实例
            BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
            //通过蓝牙管理实例获取适配器,然后通过扫描方法(scan)获取设备(device)
            bluetoothAdapter = bluetoothManager.getAdapter();
    
    
        }
    
        private void initView() {
            saomiao = (Button) findViewById(R.id.saomiao);
            duanzhen = (Button) findViewById(R.id.zhendong);
            changzhen = (Button) findViewById(R.id.changzhen);
            buting = (Button) findViewById(R.id.buting);
            tingxia = (Button) findViewById(R.id.tingxia);
            list = (ListView) findViewById(R.id.list);
    
            jibu = (TextView) findViewById(R.id.jibu);
            dianliang = (TextView) findViewById(R.id.dianliang);
            lianjiezhuangtai = (TextView) findViewById(R.id.lianjiezhuangtai);
    
            saomiao.setOnClickListener(this);
            duanzhen.setOnClickListener(this);
            changzhen.setOnClickListener(this);
            buting.setOnClickListener(this);
            tingxia.setOnClickListener(this);
    
            //item 监听事件
            list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    bluetoothDevice = deviceList.get(i);
                    //连接设备的方法,返回值为bluetoothgatt类型
                    bluetoothGatt = bluetoothDevice.connectGatt(MainActivity.this, false, gattcallback);
                    lianjiezhuangtai.setText("连接" + bluetoothDevice.getName() + "中...");
                }
            });
    
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.saomiao:
                    //开始扫描前开启蓝牙
                    Intent turn_on = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(turn_on, 0);
                    Toast.makeText(MainActivity.this, "蓝牙已经开启", Toast.LENGTH_SHORT).show();
    
                    Thread scanThread = new Thread(new Runnable() {
                        @Override
                        public void run() {
                            Log.i("TAG", "run: saomiao ...");
                            saomiao();
                        }
                    });
                    scanThread.start();
    
                    break;
                case R.id.zhendong:
    
                    break;
                case R.id.changzhen:
    
                    break;
                case R.id.buting:
    
                    break;
                case R.id.tingxia:
    
                    break;
                case R.id.list:
    
                    break;
    
            }
        }
    
        public void saomiao(){
            deviceList.clear();
            bluetoothAdapter.startLeScan(callback);
        }
    
        //扫描回调
        public BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
                Log.i("TAG", "onLeScan: " + bluetoothDevice.getName() + "/t" + bluetoothDevice.getAddress() + "/t" + bluetoothDevice.getBondState());
    
                //重复过滤方法,列表中包含不该设备才加入列表中,并刷新列表
                if (!deviceList.contains(bluetoothDevice)) {
                    //将设备加入列表数据中
                    deviceList.add(bluetoothDevice);
    
                    list.setAdapter(new MyAdapter(MainActivity.this , deviceList));
                }
    
            }
        };
    
        private BluetoothGattCallback gattcallback = new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, final int newState) {
                super.onConnectionStateChange(gatt, status, newState);
    
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        String status;
                        switch (newState) {
                            //已经连接
                            case BluetoothGatt.STATE_CONNECTED:
                                lianjiezhuangtai.setText("已连接");
    
                                //该方法用于获取设备的服务,寻找服务
                                bluetoothGatt.discoverServices();
                                break;
                            //正在连接
                            case BluetoothGatt.STATE_CONNECTING:
                                lianjiezhuangtai.setText("正在连接");
                                break;
                            //连接断开
                            case BluetoothGatt.STATE_DISCONNECTED:
                                lianjiezhuangtai.setText("已断开");
                                break;
                            //正在断开
                            case BluetoothGatt.STATE_DISCONNECTING:
                                lianjiezhuangtai.setText("断开中");
                                break;
                        }
                        //pd.dismiss();
                    }
                });
            }
    
            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                super.onServicesDiscovered(gatt, status);
            }
    
            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicRead(gatt, characteristic, status);
            }
    
            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                super.onCharacteristicWrite(gatt, characteristic, status);
            }
    
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicChanged(gatt, characteristic);
            }
    
            @Override
            public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                super.onDescriptorRead(gatt, descriptor, status);
            }
    
            @Override
            public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                super.onDescriptorWrite(gatt, descriptor, status);
            }
    
            @Override
            public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
                super.onReliableWriteCompleted(gatt, status);
            }
    
            @Override
            public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
                super.onReadRemoteRssi(gatt, rssi, status);
            }
    
            @Override
            public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
                super.onMtuChanged(gatt, mtu, status);
            }
        } ;
    }
    View Code

    实现效果:

    好啦!!我们功能已经实现了一大部分了呢!!

    下节我们就来获取手环中

    我走的步数 , 和电池的电量吧~~

    大家加油啦~~~

  • 相关阅读:
    【每日一具12】超级好用的录屏软件,赶紧收藏
    【每日一具12】超级好用的录屏软件,赶紧收藏
    python之K-邻近算法/kNN(附上注解代码)
    数据挖掘领域十大经典算法之—K-邻近算法/kNN(超详细附代码)
    【每日一具11】一款图片文件漂白软件
    python实现全北京的公交路线动图【一定收藏】
    【每日一具11】一款图片文件漂白软件
    一个典型的加了 SAP 注解的 OData 服务明细分析
    如何以 mock server 的方式本地启动 SAP UI5 应用,使它不连接服务器端 OData 服务
    深入掌握 SAP Fiori Elements 工作原理系列之二:如何给 Fiori Elements 应用添加自定义按钮
  • 原文地址:https://www.cnblogs.com/wobeinianqing/p/5879851.html
Copyright © 2011-2022 走看看