栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ESP32S蓝牙06

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ESP32S蓝牙06

ESP32S蓝牙06

前一篇的经典蓝牙代码编程仅仅是开胃小菜,我们的重点是BLE低功耗蓝牙。我们先来完成BLE的第一个小任务:搜索BLE蓝牙设备。

我们开始先上代码吧:这个是程序的代码 MainActivity. java

package com.example.bluetooth;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.Manifest;

import android.annotation.SuppressLint;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothGatt;

import android.bluetooth.BluetoothGattCallback;

import android.bluetooth.BluetoothGattCharacteristic;

import android.bluetooth.BluetoothManager;

import android.bluetooth.le.BluetoothLeScanner;

import android.bluetooth.le.ScanCallback;

import android.bluetooth.le.ScanResult;

import android.content.Context;

import android.content.Intent;

import android.os.Build;

import android.telecom.Connection;

import android.text.TextUtils;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

import android.widget.ListAdapter;

import java.util.ArrayList;

import java.util.List;

@SuppressLint("NewApi")

public class MainActivity extends AppCompatActivity {

    private Button scan_button ;

    private TextView showresult;

    private Button connect_button;

    private BluetoothAdapter bleadapter;

    private BluetoothGatt bluetoothGatt;

    private BluetoothLeScanner blescanner;

    private ScanCallback scanCallback;

    private BluetoothDevice bledevice;

    private boolean  isfindmyudevice=false;

    private String device_name;

    private String device_adress;

    private List mDeviceList;

    private ArrayList list;

    private ArrayAdapter adapter;

    private ListView mListView;

   

    private boolean mScanning = false;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

     

       

        showresult = (TextView) findViewById(R.id.txt_msg);

        scan_button = (Button) findViewById(R.id.btn_scan);

        connect_button = (Button) findViewById(R.id.btn_connect);

        mListView = (ListView) findViewById(R.id.listView1);

       

        //初始化ble设配器

        BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

        bleadapter = manager.getAdapter();

        //判断蓝牙是否开启,若是关闭则请求打开蓝牙

        if (bleadapter == null || !bleadapter.isEnabled()) {

            //方式一:请求打开蓝牙

            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

            startActivityForResult(intent, 1);

        }

       

        //搜索按钮

        scan_button.setonClickListener(new View.onClickListener() {

        @Override

            public void onClick(View v) {

             showresult.setText("star scan");

             //初始化列表变量,一个用于存储自定义类,一个用于存储字符串

             mDeviceList=new ArrayList();

             list = new ArrayList();

             //把扫描过程放进一个线程里面进行

             new Thread(new Runnable() {

                    @Override

                    public void run() {

                       //如果发现一个BLE设备,就会执行一次callback回调函数

                       bleadapter.startLeScan(callback);

                        try {

                            Thread.sleep(4000);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                        bleadapter.stopLeScan(callback);

                      showresult.setText("stop scan");

                    }

                }).start();

        }

        });

       

        connect_button.setonClickListener(new View.onClickListener() {

        @Override

            public void onClick(View v) {

            

        }

        });

       

        //当用户点击选择列表框的时候

        mListView.setonItemClickListener(new AdapterView.onItemClickListener() {

        BluetoothDevice mDevice;

            @Override

            public void onItemClick(AdapterView parent, View view, int position, long id) {

            //获取用户选中的蓝牙设备的MAC字符串,并从MAC获得设备对象

            device_adress=mDeviceList.get(position).getMac();

            bledevice = bleadapter.getRemoteDevice(device_adress);

            showresult.setText("selected: " + device_adress);

           

            }

          });

    }

   

    //这个是扫描的回调函数,每当扫描到一个BLE设备时,就会运行一次这个函数

    public BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {

    @Override

        public void onLeScan(final BluetoothDevice bluetoothDevice, int i, byte[] bytes) {

        

         if (bluetoothDevice != null){

             //这里给大家另外两种显示扫描结果的方法,可以用消息框或标签来显示

             //Toast.makeText(MainActivity.this, bluetoothDevice.getName(), Toast.LENGTH_SHORT).show();

             //showresult.append(bleDevice.getName() + "   " + bleDevice.getMac() + "n");

           

            

             BLEDevice bleDevice = new BLEDevice(bluetoothDevice.getName(),bluetoothDevice.getAddress());

                if(!mDeviceList.contains(bleDevice)){

                  //存入自定义类BLEDevice的集合中

                  mDeviceList.add(bleDevice);

                  //存入字符串集合中,并显示在列表框中

                  list.add(bleDevice.getName() + "   " + bleDevice.getMac());

                  adapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, list);

                  mListView.setAdapter(adapter);

                  

                }

         }

        }

    };

   

    //这个是自定义类,用于保存搜索到的BLE设备的名字和MAC地址

    public class BLEDevice {

    private String name;

    private String mac;

    public BLEDevice(String name, String mac) {

        this.name = name;

        this.mac = mac;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getMac() {

        return mac;

    }

    public void setMac(String mac) {

        this.mac = mac;

    }

    @Override

    public boolean equals(Object o) {

        return !TextUtils.isEmpty(this.mac) &&!TextUtils.isEmpty(((BLEDevice)o).mac)

                    &&this.mac.equals(((BLEDevice) o).getMac());

     }

    }

   

}

这个是程序的主界面: activity_main.xml

"http://schemas.android.com/apk/res/android"

   xmlns:tools="http://schemas.android.com/tools"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:orientation="vertical"

   android:paddingBottom="@dimen/activity_vertical_margin"

   android:paddingLeft="@dimen/activity_horizontal_margin"

   android:paddingRight="@dimen/activity_horizontal_margin"

   android:paddingTop="@dimen/activity_vertical_margin"

   tools:context=".MainActivity" >

  

      android:id="@+id/listView1"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:visibility="visible" />

   

  

  

      android:id="@+id/btn_scan"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:text="扫描蓝牙" />

  

  

      android:id="@+id/btn_connect"

      android:layout_width="wrap_content"

      android:layout_height="wrap_content"

      android:text="连接蓝牙" />

  

  

      android:id="@+id/txt_msg"

      android:layout_width="match_parent"

      android:layout_height="wrap_content" />

这个是权限申请,在 AndroidManifest.xml中,注意安卓的版本号,需要的版本号要17以上,也就是Android 4.3 以上的版本,才能有BLE的功能。

        android:minSdkVersion="11"

        android:targetSdkVersion="21" />

   

   

    "android.permission.BLUETOOTH" />

    "android.permission.BLUETOOTH_ADMIN" />

    "android.hardware.location.gps" />

   

    "android.permission.ACCESS_FINE_LOCATION"/>

"android.permission.ACCESS_COARSE_LOCATION"/>

这个程序是扫描BLE蓝牙设备,并把搜索到的蓝牙设备显示在上方的列表框中,我们点击一下列表中的蓝牙设备,在下方的标签中会显示我们所选择的蓝牙设备。

需要注意的是,我们这次搜索的是BLE蓝牙,也就是只有广播的是BLE蓝牙服务的设备才能被搜索出来。(以为这个ESP32S模块在《ESP32S蓝牙04》这篇文章的时候,已经被设计成了BLE蓝牙服务器小车),所以模块广播的是BLE的服务信号,所以被这个程序搜索并显示在了列表框中。  但是我的另外一部手机呢?虽然也打开了蓝牙信号,虽然蓝牙信号也能被搜索到,也能被配对,但是那部手机默认广播的是传统的蓝牙服务信号,所以就不会被搜索出来了。

我们还是来看看BLE蓝牙编程的机制吧,主要是靠“线程 + 回调”来实现的。

new Thread(new Runnable() {

     @Override

     public void run() {

         //如果发现一个BLE设备,就会执行一次callback回调函数

         bleadapter.startLeScan(callback);

         try {

             Thread.sleep(4000);

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

         bleadapter.stopLeScan(callback);

         showresult.setText("stop scan");

     }

}).start();

这个其实是线程的运行控制,和我们之前在经典蓝牙的线程中不一样,就是加入了一个回调的机制。也就是在这个搜索线程中,蓝牙适配器开始搜索,每当搜索到一个BLE设备时,就会触发一次callback的回调函数,在这个回调函数中,我们队搜索到的设备进行一些处理。如果搜索中又发现了第二个BLE蓝牙设备,这个触发函数callback会再一次被执行一次。

而这种回调机制,其实在APPInventor中也是有的,其实我们今天写的这个BLE蓝牙搜索的代码程序,就是完成APPInventor中的“开始扫描”和“当找到设备”这两个模块。这两个模块的启动其实是不一样的,“调用低功耗蓝牙. 开始扫描”这个积木模块是因为用户按动了按钮,所以才启动的;而“当低功耗蓝牙. 找到设备”是线程控制启动的,当搜索线程在运行的过程中,发现了一个BLE蓝牙设备,这个程序就会被执行一次,这个就是“回调”,或者我们也可以理解成“侦听”事件。

   

    就为了用代码的方式实现这两个积木模块,花费了我好多的世间和精力在摸索。但是努力也是值得的,因为我们毕竟掌握了代码层的控制,这样我们就能有更广阔的施展空间了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777974.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号