Android Studio 之蓝牙串口通信(SPP)

打印 上一主题 下一主题

主题 513|帖子 513|积分 1549

撰写不易,记下条记,满是干货源码:

一、先创建一个空project



  • 选择Empty Activity,然后Next



  • 选择工程位置与项目名称,然后点Finsh即可


二、设计结构activity_main.xml(如下)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     tools:context=".MainActivity">
  8.     <TextView
  9.         android:id="@+id/text1"
  10.         android:layout_width="0dp"
  11.         android:layout_height="wrap_content"
  12.         android:textSize="20dp"
  13.         android:text="本地蓝牙设备:"
  14.         app:layout_constraintEnd_toStartOf="@+id/guideline2"
  15.         app:layout_constraintStart_toStartOf="parent"
  16.         app:layout_constraintTop_toTopOf="parent"
  17.         android:layout_marginTop="10dp"/>
  18.     <TextView
  19.         android:id="@+id/text2"
  20.         android:layout_width="0dp"
  21.         android:layout_height="wrap_content"
  22.         android:textSize="20dp"
  23.         android:text="设备名称"
  24.         app:layout_constraintEnd_toEndOf="parent"
  25.         app:layout_constraintStart_toStartOf="@+id/guideline2"
  26.         app:layout_constraintTop_toTopOf="parent"
  27.         android:layout_marginTop="10dp"/>
  28.     <androidx.constraintlayout.widget.Guideline
  29.         android:id="@+id/guideline2"
  30.         android:layout_width="wrap_content"
  31.         android:layout_height="wrap_content"
  32.         android:orientation="vertical"
  33.         app:layout_constraintGuide_begin="205dp"/>
  34.     <Button
  35.         android:id="@+id/button_open"
  36.         android:layout_width="0dp"
  37.         android:layout_height="wrap_content"
  38.         android:text="打开蓝牙"
  39.         android:textSize="20dp"
  40.         app:layout_constraintEnd_toStartOf="@id/guideline2"
  41.         app:layout_constraintStart_toStartOf="parent"
  42.         app:layout_constraintTop_toBottomOf="@id/text1" />
  43.     <Button
  44.         android:id="@+id/button_close"
  45.         android:layout_width="0dp"
  46.         android:layout_height="wrap_content"
  47.         android:text="关闭蓝牙"
  48.         android:textSize="20dp"
  49.         app:layout_constraintEnd_toEndOf="parent"
  50.         app:layout_constraintStart_toStartOf="@id/guideline2"
  51.         app:layout_constraintTop_toBottomOf="@id/text2"/>
  52.     <Button
  53.         android:id="@+id/button_search"
  54.         android:layout_width="0dp"
  55.         android:layout_height="wrap_content"
  56.         android:text="搜索蓝牙设备"
  57.         android:textSize="20dp"
  58.         app:layout_constraintEnd_toStartOf="@+id/guideline2"
  59.         app:layout_constraintStart_toStartOf="parent"
  60.         app:layout_constraintTop_toBottomOf="@+id/button_open" />
  61.     <Button
  62.         android:id="@+id/button_check"
  63.         android:layout_width="0dp"
  64.         android:layout_height="wrap_content"
  65.         android:text="已绑定设备"
  66.         android:textSize="20dp"
  67.         app:layout_constraintEnd_toEndOf="parent"
  68.         app:layout_constraintStart_toStartOf="@+id/guideline2"
  69.         app:layout_constraintTop_toBottomOf="@+id/button_close" />
  70.     <ListView
  71.         android:id="@+id/listview1"
  72.         android:layout_width="0dp"
  73.         android:layout_height="0dp"
  74.         app:layout_constraintBottom_toBottomOf="parent"
  75.         app:layout_constraintEnd_toEndOf="parent"
  76.         app:layout_constraintStart_toStartOf="parent"
  77.         app:layout_constraintTop_toBottomOf="@+id/textView" />
  78.     <TextView
  79.         android:id="@+id/textView"
  80.         android:layout_width="0dp"
  81.         android:layout_height="wrap_content"
  82.         android:background="#6D91AE"
  83.         android:gravity="center"
  84.         android:text="蓝牙列表"
  85.         android:textSize="25dp"
  86.         app:layout_constraintEnd_toEndOf="parent"
  87.         app:layout_constraintStart_toStartOf="parent"
  88.         app:layout_constraintTop_toBottomOf="@+id/button_search" />
  89. </androidx.constraintlayout.widget.ConstraintLayout>
复制代码

三、再新建一个Empty Activity,作为连接后跳转的界面(命名为send_and_receive或自界说命名)



四、设计结构activity_send_and_receive.xml(如下)

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     tools:context=".Send_and_receive">
  8.     <TextView
  9.         android:id="@+id/textView_ble"
  10.         android:layout_width="wrap_content"
  11.         android:layout_height="0dp"
  12.         android:gravity="fill_vertical"
  13.         android:text="蓝牙状态:"
  14.         android:textSize="20dp"
  15.         app:layout_constraintStart_toStartOf="parent"
  16.         app:layout_constraintTop_toTopOf="parent" />
  17.     <TextView
  18.         android:id="@+id/textView_ble_connect"
  19.         android:layout_width="wrap_content"
  20.         android:layout_height="0dp"
  21.         android:layout_marginStart="70dp"
  22.         android:gravity="fill_vertical"
  23.         android:text="已连接"
  24.         android:textColor="#3F51B5"
  25.         android:textSize="20dp"
  26.         app:layout_constraintStart_toEndOf="@+id/textView_ble"
  27.         app:layout_constraintTop_toTopOf="parent" />
  28.     <ListView
  29.         android:id="@+id/listView_receive"
  30.         android:layout_width="0dp"
  31.         android:layout_height="0dp"
  32.         app:layout_constraintBottom_toTopOf="@+id/textView_send"
  33.         app:layout_constraintEnd_toEndOf="parent"
  34.         app:layout_constraintHorizontal_bias="0.538"
  35.         app:layout_constraintStart_toStartOf="parent"
  36.         app:layout_constraintTop_toBottomOf="@+id/textView_receive" />
  37.     <TextView
  38.         android:id="@+id/textView_receive"
  39.         android:layout_width="0dp"
  40.         android:layout_height="wrap_content"
  41.         android:background="#6D91AE"
  42.         android:gravity="center"
  43.         android:text="接收区"
  44.         android:textSize="24sp"
  45.         app:layout_constraintEnd_toEndOf="parent"
  46.         app:layout_constraintStart_toStartOf="parent"
  47.         app:layout_constraintTop_toBottomOf="@+id/textView_ble" />
  48.     <TextView
  49.         android:id="@+id/textView_send"
  50.         android:layout_width="match_parent"
  51.         android:layout_height="wrap_content"
  52.         android:background="#6D91AE"
  53.         android:gravity="center"
  54.         android:text="发送区"
  55.         android:textSize="24sp"
  56.         app:layout_constraintBottom_toTopOf="@+id/editText_send"
  57.         app:layout_constraintEnd_toEndOf="parent"
  58.         app:layout_constraintHorizontal_bias="0.0"
  59.         app:layout_constraintStart_toStartOf="parent" />
  60.     <EditText
  61.         android:id="@+id/editText_send"
  62.         android:layout_width="0dp"
  63.         android:layout_height="50dp"
  64.         android:ems="10"
  65.         android:inputType="textPersonName"
  66.         app:layout_constraintBottom_toBottomOf="parent"
  67.         app:layout_constraintEnd_toStartOf="@+id/button_send"
  68.         app:layout_constraintStart_toStartOf="parent" />
  69.     <Button
  70.         android:id="@+id/button_send"
  71.         android:layout_width="100dp"
  72.         android:layout_height="50dp"
  73.         android:text="发送"
  74.         app:layout_constraintBottom_toBottomOf="parent"
  75.         app:layout_constraintEnd_toEndOf="parent"
  76.         app:layout_constraintTop_toTopOf="@+id/editText_send" />
  77. </androidx.constraintlayout.widget.ConstraintLayout>
复制代码

五、在res文件下新建一个文件命名为menu,而后在该文件下新建一个菜单栏menu1.xml



六、menu1.xml菜单设计

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3.     <item android:id="@+id/menu_button_connect" android:title="连接蓝牙设备"/>
  4.     <item android:id="@+id/menu_button_disconnect" android:title="断开蓝牙设备"/>
  5.     <item android:id="@+id/menu_button_return" android:title="返回上一页"/>
  6.     <item android:id="@+id/menu_button_clean" android:title="清除数据"/>
  7. </menu>
复制代码
七、AndroidMainfest.xml文件中添加权限申请(如下)

  1. <!-- 添加权限 -->
  2.     <!-- 允许应用程序使用本机设备的蓝牙功能 -->
  3.     <uses-permission android:name="android.permission.BLUETOOTH" /> <!-- 允许应用程序对蓝牙进行发现和配对,注:安装12新增的蓝牙权限 -->
  4.     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 定位权限,蓝牙搜索需要 -->
  5.     <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- 允许应用程序连接到蓝牙设备 -->
  6.     <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 允许应用程序启用蓝牙广播功能 -->
  7.     <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <!-- 应用程序需访问设备的精准地理位置 -->
  8.     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 应用程序需访问设备的粗略地理位置 -->
  9.     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
复制代码
八、新建一个蓝牙适配器类BluetoothController.java


代码如下:

  1. package com.example.ble_0426;
  2. import android.app.Activity;
  3. import android.bluetooth.BluetoothAdapter;
  4. import android.bluetooth.BluetoothDevice;
  5. import android.bluetooth.BluetoothSocket;
  6. import android.content.Intent;
  7. import android.util.Log;
  8. import java.lang.reflect.Method;
  9. import java.util.ArrayList;
  10. /**
  11. *蓝牙控制器
  12. */
  13. public class BluetoothController {
  14.     //成员变量
  15.     private BluetoothAdapter mAdapter;
  16.     private BluetoothSocket btSocket;
  17.     private String TAG = "";
  18.     String bluetoothName;
  19.     /**
  20.      * 构造函数
  21.      */
  22.     public BluetoothController()
  23.     {
  24.         //获取本地的蓝牙适配器
  25.         mAdapter =BluetoothAdapter.getDefaultAdapter();
  26.     }
  27.     /**
  28.      *获取本机蓝牙名称
  29.      */
  30.     public String getBluetoothName()
  31.     {
  32.         bluetoothName = mAdapter.getName();
  33.         return bluetoothName;
  34.     }
  35.     /**
  36.     * 打开蓝牙
  37.     */
  38.     public void turnOnBlueTooth(Activity activity, int requestCode)
  39.     {
  40.         if (!mAdapter.isEnabled())
  41.         {
  42.             Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  43.             activity.startActivityForResult(intent, requestCode);
  44.         }
  45.         else
  46.             return;
  47.     }
  48.     /**
  49.      * 关闭蓝牙
  50.      */
  51.     public void turnOffBlueTooth()
  52.     {
  53.         if (mAdapter.isEnabled())
  54.         {
  55.             mAdapter.disable();
  56.         }
  57.     }
  58.     /**
  59.      * 根据蓝牙地址找到相应的设备
  60.      */
  61.     public BluetoothDevice find_device(String addr)
  62.         {
  63.             return mAdapter.getRemoteDevice(addr);
  64.         }
  65.     /**
  66.      *停止搜索设备
  67.      */
  68.     public void cancelSearch()
  69.         {
  70.             mAdapter.cancelDiscovery();
  71.         }
  72.     /**
  73.      * 搜索蓝牙设备
  74.      */
  75.     public boolean searchBle()
  76.     {
  77.         assert (mAdapter !=null);
  78.         if (mAdapter.isDiscovering())
  79.         {
  80.             mAdapter.cancelDiscovery();
  81.             return false;
  82.         }
  83.         else {
  84.             return mAdapter.startDiscovery();
  85.         }
  86.     }
  87.     /**
  88.      * 查看已绑定的蓝牙设备
  89.      */
  90.     public ArrayList<BluetoothDevice> getBleDeviceList()
  91.     {
  92.         return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());
  93.     }
  94. }
复制代码
九、MainActivity.java代码如下:

  1. package com.example.ble_0426;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import androidx.core.app.ActivityCompat;
  4. import android.Manifest;
  5. import android.bluetooth.BluetoothAdapter;
  6. import android.bluetooth.BluetoothDevice;
  7. import android.content.BroadcastReceiver;
  8. import android.content.Context;
  9. import android.content.Intent;
  10. import android.content.IntentFilter;
  11. import android.os.Build;
  12. import android.os.Bundle;
  13. import android.view.View;
  14. import android.widget.AdapterView;
  15. import android.widget.ArrayAdapter;
  16. import android.widget.Button;
  17. import android.widget.ListView;
  18. import android.widget.TextView;
  19. import android.widget.Toast;
  20. import java.util.ArrayList;
  21. public class MainActivity extends AppCompatActivity {
  22.     //蓝牙权限列表
  23.     public ArrayList<String> requestList = new ArrayList<>();
  24.     //常量
  25.     private static final int REQ_PERMISSION_CODE = 1;
  26.     //实例化蓝牙控制器
  27.     public BluetoothController btController = new BluetoothController();
  28.     //弹窗
  29.     private Toast mToast;
  30.     //定义一个列表,存蓝牙设备地址,用于显示
  31.     public ArrayList<String> deviceName = new ArrayList<>();
  32.     //定义一个列表,存储蓝牙设备的地址
  33.     public ArrayList<String> arrayList = new ArrayList<>();
  34.     //定义一个适配器,用于刷新列表更新
  35.     public ArrayAdapter adapter1;
  36.     //搜索蓝牙广播
  37.     private IntentFilter foundFilter;
  38.     /**
  39.      * 搜索蓝牙广播,将搜索到的蓝牙名称和地址添加到列表上
  40.      */
  41.     private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {
  42.         @Override
  43.         public void onReceive(Context context, Intent intent) {
  44.             String action = intent.getAction();
  45.             if (BluetoothDevice.ACTION_FOUND.equals(action))
  46.             {
  47.                 String label;
  48.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  49.                 if (device.getBondState() == 12)
  50.                 {
  51.                     label = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
  52.                 }
  53.                 else if (device.getBondState() == 10)
  54.                 {
  55.                     label = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
  56.                 }
  57.                 else
  58.                 {
  59.                     label = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";
  60.                 }
  61.                 if (!deviceName.contains(label))
  62.                 {
  63.                     deviceName.add(label);      //将搜索到的设备添加到列表上
  64.                     arrayList.add(device.getAddress());     //将搜索到的蓝牙地址添加到列表上
  65.                     adapter1.notifyDataSetChanged();        //更新
  66.                 }
  67.             }
  68.             else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
  69.             {
  70.                 showToast("搜索结束");
  71.                 unregisterReceiver(this);
  72.             }
  73.             else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action))
  74.             {
  75.                 showToast("开始搜索");
  76.             }
  77.         }
  78.     };
  79.     @Override
  80.     protected void onCreate(Bundle savedInstanceState) {
  81.         super.onCreate(savedInstanceState);
  82.         setContentView(R.layout.activity_main);
  83.         //显示本机蓝牙名称
  84.         TextView textView_name = (TextView) findViewById(R.id.text2);
  85.         textView_name.setText(btController.getBluetoothName());
  86.         //蓝牙状态改变信息
  87.         IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
  88.         //搜索蓝牙广播
  89.         foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  90.         foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
  91.         foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  92.         //实例化ArrayAdapter
  93.         adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,deviceName);
  94.         //通过id获取ListView组件
  95.         ListView listView = (ListView) findViewById(R.id.listview1);
  96.         //添加到LisView组件中
  97.         listView.setAdapter(adapter1);
  98.         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  99.             @Override
  100.             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
  101.                 CharSequence content = ((TextView) view).getText();
  102.                 String con = content.toString();
  103.                 String[] conArray = con.split("\n");
  104.                 String rightStr = conArray[1].substring(5,conArray[1].length());
  105.                 BluetoothDevice device = btController.find_device(rightStr);
  106.                 if (device.getBondState() == 10)
  107.                 {
  108.                     btController.cancelSearch();
  109.                     String label = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";
  110.                     deviceName.remove(label);
  111.                     device.createBond();
  112.                     label = "设备名:" + device.getName() +"\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
  113.                     deviceName.add(label);
  114.                     adapter1.notifyDataSetChanged();
  115.                     showToast("配对:"+device.getName());
  116.                 }
  117.                 else
  118.                 {
  119.                     btController.cancelSearch();
  120.                     String label = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";
  121.                     if (deviceName.contains(label))
  122.                     {
  123.                         Intent intent = new Intent(MainActivity.this,Send_and_receive.class);
  124.                         Bundle bundle = new Bundle();
  125.                         bundle.putString("deviceAddr", device.getAddress());
  126.                         intent.putExtras(bundle);
  127.                         startActivity(intent);
  128.                         finish();
  129.                     }
  130.                 }
  131.             }
  132.         });
  133.         //自动打开蓝牙
  134.         openBle();
  135.         /**
  136.          * 手动打开蓝牙
  137.          */
  138.         //通过id获取“打开蓝牙”按钮
  139.         Button button_open = (Button) findViewById(R.id.button_open);
  140.         //绑定按钮点击事件处理函数
  141.         button_open.setOnClickListener(new View.OnClickListener() {
  142.             @Override
  143.             public void onClick(View v) {
  144.                 openBle();
  145.             }
  146.         });
  147.         /**
  148.          * 关闭蓝牙
  149.          */
  150.         //通过id获取“关闭蓝牙”按钮
  151.         Button button_close = (Button) findViewById(R.id.button_close);
  152.         //绑定按钮点击事件处理函数
  153.         button_close.setOnClickListener(new View.OnClickListener() {
  154.             @Override
  155.             public void onClick(View v) {
  156.                 closeBle();
  157.             }
  158.         });
  159.         /**
  160.          * 搜索蓝牙设备
  161.          */
  162.         //通过id获取”搜索蓝牙设备“按钮
  163.         Button button_search = (Button) findViewById(R.id.button_search);
  164.         //绑定按钮点击事件处理函数
  165.         button_search.setOnClickListener(new View.OnClickListener() {
  166.             @Override
  167.             public void onClick(View v) {
  168.                 getPermision();     //获取蓝牙权限
  169.                 registerReceiver(bluetoothReceiver,foundFilter);     //注册广播
  170.                 //初始化各个列表
  171.                 arrayList.clear();
  172.                 deviceName.clear();
  173.                 adapter1.notifyDataSetChanged();    //更新
  174.                 btController.searchBle();
  175.             }
  176.         });
  177.         /**
  178.          * 查看已绑定设备
  179.          */
  180.         //通过id获取”已绑定设备“按钮
  181.         Button button_check = (Button) findViewById(R.id.button_check);
  182.         //绑定按钮点击事件处理函数
  183.         button_check.setOnClickListener(new View.OnClickListener() {
  184.             @Override
  185.             public void onClick(View v) {
  186.                 getPermision();     //获取蓝牙权限
  187.                 //初始化各个列表
  188.                 arrayList.clear();
  189.                 deviceName.clear();
  190.                 adapter1.notifyDataSetChanged();    //更新
  191.                 //获取已绑定的蓝牙设备
  192.                 ArrayList<BluetoothDevice> bluetoothDevices = btController.getBleDeviceList();
  193.                 //更新列表
  194.                 for (int i = 0; i < bluetoothDevices.size(); i++)
  195.                 {
  196.                     BluetoothDevice device = bluetoothDevices.get(i);
  197.                     arrayList.add(device.getAddress());
  198.                     if (device.getBondState() == 12) {
  199.                         deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n");
  200.                     } else if (device.getBondState() == 10) {
  201.                         deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n");
  202.                     } else {
  203.                         deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n");
  204.                     }
  205.                     adapter1.notifyDataSetChanged();
  206.                 }
  207.             }
  208.         });
  209.     }
  210.     /**
  211.      * 打开蓝牙
  212.      */
  213.     public void openBle()
  214.     {
  215.         getPermision();     //蓝牙权限
  216.         btController.turnOnBlueTooth(this,1);
  217.     }
  218.     /**
  219.      * 关闭蓝牙
  220.      */
  221.     public void closeBle()
  222.     {
  223.         getPermision();     //蓝牙权限
  224.         btController.turnOffBlueTooth();
  225.     }
  226.     /**
  227.      * 动态申请权限
  228.      */
  229.     public void getPermision()
  230.     {
  231.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
  232.         {
  233.             requestList.add(Manifest.permission.BLUETOOTH);
  234.             requestList.add(Manifest.permission.BLUETOOTH_SCAN);
  235.             requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
  236.             requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
  237.             requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
  238.             requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
  239.         }
  240.         if(requestList.size() != 0)
  241.         {
  242.             ActivityCompat.requestPermissions(this,requestList.toArray(new String[0]),REQ_PERMISSION_CODE);
  243.         }
  244.     }
  245.     /**
  246.      * 弹窗
  247.      */
  248.     public void showToast(String text)
  249.     {
  250.         if (mToast == null)
  251.         {
  252.             //初始化
  253.             mToast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
  254.         }
  255.         else
  256.         {
  257.             //修改显示文本
  258.             mToast.setText(text);
  259.         }
  260.         //显示
  261.         mToast.show();
  262.     }
  263. }
复制代码
十、Send_and receive.java代码如下:

  1. package com.example.ble_0426;
  2. import androidx.annotation.NonNull;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import androidx.core.app.ActivityCompat;
  5. import android.Manifest;
  6. import android.bluetooth.BluetoothDevice;
  7. import android.bluetooth.BluetoothSocket;
  8. import android.content.Intent;
  9. import android.os.Build;
  10. import android.os.Bundle;
  11. import android.os.Handler;
  12. import android.os.Looper;
  13. import android.os.Message;
  14. import android.util.Log;
  15. import android.view.Menu;
  16. import android.view.MenuItem;
  17. import android.view.View;
  18. import android.widget.ArrayAdapter;
  19. import android.widget.Button;
  20. import android.widget.EditText;
  21. import android.widget.ListAdapter;
  22. import android.widget.ListView;
  23. import android.widget.TextView;
  24. import android.widget.Toast;
  25. import java.io.IOException;
  26. import java.io.InputStream;
  27. import java.io.OutputStream;
  28. import java.nio.charset.StandardCharsets;
  29. import java.util.ArrayList;
  30. import java.util.UUID;
  31. public class Send_and_receive extends AppCompatActivity {
  32.     //蓝牙权限列表
  33.     public ArrayList<String> requestList = new ArrayList<>();
  34.     //常量
  35.     private static final int REQ_PERMISSION_CODE = 1;
  36.     //弹窗
  37.     private Toast mToast;
  38.     //蓝牙服务
  39.     private BluetoothSocket bluetoothSocket;
  40.     //实例化BleConnect
  41.     private BleConnect bleConnect = new BleConnect();
  42.     //实例化蓝牙适配器类
  43.     public BluetoothController mController = new BluetoothController();
  44.     //文本输入框
  45.     public EditText editText;
  46.     //接收区
  47.     public ListView listView;
  48.     //蓝牙状态文本显示
  49.     public TextView text;
  50.     //消息列表
  51.     public ArrayList<String> listMessage = new ArrayList<>();
  52.     //定义适配器
  53.     public ArrayAdapter adapter1;
  54.     //活动间消息传递
  55.     public Handler mHandler;
  56.     //读取数据线程
  57.     public readMessage readmessage = new readMessage();
  58.     private Bundle bundle;
  59.     public Button button_send;
  60.     public Menu button_return;
  61.     @Override
  62.     protected void onCreate(Bundle savedInstanceState) {
  63.         super.onCreate(savedInstanceState);
  64.         setContentView(R.layout.activity_send_and_receive);
  65.         //获取intent
  66.         Intent intent = getIntent();
  67.         //获取intent传来的数据
  68.         bundle = intent.getExtras();
  69.         //连接服务
  70.         bleConnect.connectDevice(mController.find_device(bundle.getString("deviceAddr")));
  71.         //线程服务开始
  72.         bleConnect.start();
  73.         //文本输入框
  74.         editText = (EditText) findViewById(R.id.editText_send);
  75.         //接收区
  76.         listView = (ListView) findViewById(R.id.listView_receive);
  77.         //设置返回界面
  78.         button_return = (Menu) findViewById(R.id.menu_button_return);
  79.         //蓝牙状态文本显示
  80.         text = (TextView) findViewById(R.id.textView_ble_connect);
  81.         //实例化ArrayAdapter
  82.         adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,listMessage);
  83.         //设置listView
  84.         listView.setAdapter(adapter1);
  85.         // 实例化Handler
  86.         mHandler = new Handler(Looper.myLooper()) {
  87.             @Override
  88.             public void handleMessage(@NonNull Message msg) {
  89.                 super.handleMessage(msg);
  90.                 switch (msg.what) {
  91.                     case 1:
  92.                         String s = msg.obj.toString();
  93.                         listMessage.add("接收数据:" + s);
  94.                         adapter1.notifyDataSetChanged();
  95.                         break;
  96.                 }
  97.             }
  98.         };
  99.         /**
  100.          * 发送按钮
  101.          */
  102.         //通过id获取“发送”按钮
  103.         button_send = (Button) findViewById(R.id.button_send);
  104.         //绑定按钮点击事件处理函数
  105.         button_send.setOnClickListener(new View.OnClickListener() {
  106.             @Override
  107.             public void onClick(View v) {
  108.                 String message = editText.getText().toString();
  109.                 if (message.length() != 0)
  110.                 {
  111.                     sendMessage(message);
  112.                     listMessage.add("发送数据:" + message + "\n");
  113.                     adapter1.notifyDataSetChanged();
  114.                 }
  115.             }
  116.         });
  117.     }
  118.     /**
  119.      * 读取数据
  120.      */
  121.     private class readMessage extends Thread
  122.     {
  123.         private static final String TAG = "";
  124.         public void run()
  125.         {
  126.             super.run();
  127.             byte[] buffer = new byte[1024];
  128.             int bytes;
  129.             InputStream inputStream = null;
  130.             try {
  131.                 inputStream = bluetoothSocket.getInputStream();
  132.             }
  133.             catch (IOException e1)
  134.             {
  135.                 e1.printStackTrace();
  136.             }
  137.             while (true)
  138.             {
  139.                 try {
  140.                     if ((bytes = inputStream.read(buffer)) > 0)
  141.                     {
  142.                         byte[] buf_data = new byte[bytes];
  143.                         for (int i = 0; i < bytes; i++)
  144.                         {
  145.                             buf_data[i] = buffer[i];
  146.                         }
  147.                         String text = new String(buf_data, 0, bytes, "utf-8");        //接收的值inputstream 为 text
  148.                         Message message = Message.obtain();
  149.                         message.what = 1;
  150.                         message.obj = text;
  151.                         mHandler.sendMessage(message);
  152.                         if (text.equalsIgnoreCase("o"))
  153.                         {
  154.                             //o表示opend
  155.                             showToast("open");
  156.                         }
  157.                         else if (text.equalsIgnoreCase("c"))
  158.                         {
  159.                             //c表示close
  160.                             showToast("close");
  161.                         }
  162.                     }
  163.                 }
  164.                 catch (IOException e)
  165.                 {
  166.                     try {
  167.                         inputStream.close();
  168.                     }
  169.                     catch (IOException e1)
  170.                     {
  171.                         e1.printStackTrace();
  172.                     }
  173.                     break;
  174.                 }
  175.             }
  176.         }
  177.     }
  178.     /**
  179.      * 发送数据
  180.      */
  181.     public void sendMessage(String label)
  182.     {
  183.         getPermision();     //获取权限
  184.         if (bluetoothSocket == null)
  185.         {
  186.             showToast("没有连接");
  187.             return;
  188.         }
  189.         try
  190.         {
  191.             OutputStream os = bluetoothSocket.getOutputStream();
  192.             os.write(label.getBytes());     //发送出去的值为:label
  193.         }
  194.         catch (IOException e)
  195.         {
  196.             e.printStackTrace();
  197.         }
  198.     }
  199.     /**
  200.      * 连接蓝牙
  201.      */
  202.     private class BleConnect extends Thread
  203.     {
  204.         private void connectDevice(BluetoothDevice device)
  205.         {
  206.             try
  207.             {
  208.                 getPermision();
  209.                 bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));        //蓝牙串口服务UUID(SPP)
  210.                 bluetoothSocket.connect();
  211.                 readmessage.start();
  212.                 showToast("蓝牙连接成功");
  213.             }
  214.             catch (IOException e)
  215.             {
  216.                 e.printStackTrace();
  217.                 showToast("蓝牙连接失败");
  218.             }
  219.         }
  220.     }
  221.     /**
  222.      * 断开蓝牙
  223.      */
  224.     public void disConnect()
  225.     {
  226.         try {
  227.             bluetoothSocket.close();
  228.             bluetoothSocket = null;
  229.             button_send.setEnabled(false);
  230.             showToast("蓝牙断开");
  231.             text.setText("已断开");
  232.         }
  233.         catch (IOException e)
  234.         {
  235.             e.printStackTrace();
  236.         }
  237.     }
  238.     /**
  239.      *菜单栏
  240.      */
  241.     public boolean onCreateOptionsMenu(Menu menu)
  242.     {
  243.         getMenuInflater().inflate(R.menu.menu1,menu);
  244.         return true;
  245.     }
  246.     public boolean onOptionsItemSelected(MenuItem item)
  247.     {
  248.         switch (item.getItemId())
  249.         {
  250.             case R.id.menu_button_connect:      //连接蓝牙,还未写
  251.                 break;
  252.             case R.id.menu_button_disconnect:   //断开蓝牙
  253.                 getPermision();
  254.                 disConnect();
  255.                 break;
  256.             case R.id.menu_button_return:       //返回上一页
  257.                 Intent intent = new Intent(Send_and_receive.this,MainActivity.class);
  258.                 startActivity(intent);
  259.                 break;
  260.             case R.id.menu_button_clean:       //清除数据
  261.                 adapter1.clear();
  262.                 break;
  263.             default:
  264.         }
  265.         return true;
  266.     }
  267.     /**
  268.      * 动态申请权限
  269.      */
  270.     public void getPermision()
  271.     {
  272.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
  273.         {
  274.             requestList.add(Manifest.permission.BLUETOOTH);
  275.             requestList.add(Manifest.permission.BLUETOOTH_SCAN);
  276.             requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
  277.             requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
  278.             requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
  279.             requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
  280.         }
  281.         if(requestList.size() != 0)
  282.         {
  283.             ActivityCompat.requestPermissions(this,requestList.toArray(new String[0]),REQ_PERMISSION_CODE);
  284.         }
  285.     }
  286.     /**
  287.      * 弹窗
  288.      */
  289.     public void showToast(String text)
  290.     {
  291.         if (mToast == null)
  292.         {
  293.             //初始化
  294.             mToast = Toast.makeText(this,text,Toast.LENGTH_SHORT);
  295.         }
  296.         else
  297.         {
  298.             //修改显示文本
  299.             mToast.setText(text);
  300.         }
  301.         //显示
  302.         mToast.show();
  303.     }
  304. }
复制代码
注:若上方代码有不理解的可一起在评论区讨论
效果运行如下
     蓝牙串口通信
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表