Android Studio开发蓝牙应用(一)
环境
window 11安卓12HC-06蓝牙模块创建空project
选择Empty Activity,后点击Next
可修改项目名,自定义,后点击Finish即可。
首先设计布局,布局文件位于app/src/main/res/layout下
直接使用约束布局方式,这种方式布局代码大部分可自动生成,方便
项目实现的功能 查看手机是否支持蓝牙查看当前蓝牙状态蓝牙开关使蓝牙可见搜索可见蓝牙查看已绑定的设备Acitivity_main.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/button3"android:layout_width="0dp"android:layout_height="wrap_content"android:text="是否支持蓝牙"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button4"android:layout_width="0dp"android:layout_height="wrap_content"android:text="当前蓝牙状态"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline2"app:layout_constraintTop_toTopOf="parent" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_begin="205dp" /><Buttonandroid:id="@+id/button7"android:layout_width="0dp"android:layout_height="wrap_content"android:text="打开蓝牙"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button3" /><Buttonandroid:id="@+id/button8"android:layout_width="0dp"android:layout_height="wrap_content"android:text="关闭蓝牙"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline2"app:layout_constraintTop_toBottomOf="@+id/button4" /><Buttonandroid:id="@+id/button9"android:layout_width="0dp"android:layout_height="wrap_content"android:text="使蓝牙可见"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button7" /><Buttonandroid:id="@+id/button10"android:layout_width="0dp"android:layout_height="wrap_content"android:text="搜索可见蓝牙"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button9" /><Buttonandroid:id="@+id/button11"android:layout_width="0dp"android:layout_height="wrap_content"android:text="查看已绑定蓝牙"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="@+id/guideline2"app:layout_constraintTop_toBottomOf="@+id/button9" /><ListViewandroid:id="@+id/listview1"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/textView" /><TextViewandroid:id="@+id/textView"android:layout_width="0dp"android:layout_height="wrap_content"android:background="#00BCD4"android:gravity="center"android:text="蓝牙列表"android:textSize="24sp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/button10" /></androidx.constraintlayout.widget.ConstraintLayout>
蓝牙权限问题
首先在app/src/main/AndroidManifest.xml中添加权限安卓12对蓝牙权限做了改动,且需要动态获取权限
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="/apk/res/android"package="com.example.btapp"><!-- 先前的蓝牙权限需求--><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><!-- 安卓12新增的蓝牙权限--><uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /><uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /><uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- 定位权限, 蓝牙搜索需要--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.BTapp"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
在MainActivity.java中实现动态申请权限,在执行蓝牙相关函数时执行getPermission函数
public class MainActivity extends AppCompatActivity {private static final int REQ_PERMISSION_CODE = 1;// 蓝牙权限列表public ArrayList<String> requestList = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}/*** 动态申请权限*/public void getPermision(){if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){requestList.add(Manifest.permission.BLUETOOTH_SCAN);requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);requestList.add(Manifest.permission.BLUETOOTH_CONNECT);requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);requestList.add(Manifest.permission.BLUETOOTH);}if(requestList.size() != 0){ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);}}}
实机测试
实机测试时若提示安装包异常,则在项目的gradle.properties后添加
android.injected.testOnly=false
功能实现
在app/src/main/java/com.example.btapp内新建蓝牙控制器类BlueToothController.java获取蓝牙适配器类BlueToothAdpterpublic class BlueToothController {// 成员变量private BluetoothAdapter mAdapter;/*** 构造函数*/public BlueToothController(){// 获取本地的蓝牙适配器mAdapter = BluetoothAdapter.getDefaultAdapter();}
查看是否支持蓝牙
public boolean isSupportBlueTooth(){// 若支持蓝牙,则本地适配器不为nullif(mAdapter != null){return true;}// 否则不支持else{return false;}}
在MainActivity.java中绑定对应功能
package com.example.btapp;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {private static final int REQ_PERMISSION_CODE = 1;// 实例化蓝牙控制器public BlueToothController btController = new BlueToothController();// 实例化蓝牙控制器public BlueToothController btController = new BlueToothController();// 弹窗private Toast mToast;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 通过id获取“是否支持蓝牙”按钮Button button_1 = (Button) findViewById(R.id.button3);// 绑定按钮点击事件处理函数button_1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 判断是否支持蓝牙boolean ret = btController.isSupportBlueTooth();// 弹窗显示结果showToast("是否支持蓝牙" + ret);}});}/*** 动态申请权限*/public void getPermision(){if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){requestList.add(Manifest.permission.BLUETOOTH_SCAN);requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);requestList.add(Manifest.permission.BLUETOOTH_CONNECT);requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);requestList.add(Manifest.permission.BLUETOOTH);}if(requestList.size() != 0){ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);}}/*** Toast弹窗显示* @param text 显示文本*/public void showToast(String text){// 若Toast控件未初始化if( mToast == null){// 则初始化mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);}// 否则else{// 修改显示文本mToast.setText(text);}// 显示mToast.show();}}
判断当前蓝牙状态
/*** 判断当前蓝牙状态* @return true为打开,false为关闭*/public boolean getBlueToothStatus(){// 断言,为了避免mAdapter为null导致return出错assert (mAdapter != null);// 蓝牙状态return mAdapter.isEnabled();}
绑定功能
// 通过id获取“当前蓝牙状态”按钮Button button_2 = (Button) findViewById(R.id.button4);// 绑定按钮点击事件处理函数button_2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 判断当前蓝牙状态boolean ret = btController.getBlueToothStatus();// 弹窗显示结果showToast("当前蓝牙状态:" + ret);}});
打开蓝牙
/*** 打开蓝牙*/public boolean turnOnBlueTooth(Activity activity, int requestCode){if(!mAdapter.isEnabled()) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);activity.startActivityForResult(intent, requestCode);}}
在MainActivity.java中绑定函数
// 蓝牙状态改变广播private BroadcastReceiver receiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent) {int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);switch (state){case BluetoothAdapter.STATE_OFF:showToast("STATE_OFF");break;case BluetoothAdapter.STATE_ON:showToast("STATE_ON");break;case BluetoothAdapter.STATE_TURNING_OFF:showToast("STATE_TURNING_OFF");break;case BluetoothAdapter.STATE_TURNING_ON:showToast("STATE_TURNING_ON");break;default:showToast("UnKnow STATE");unregisterReceiver(this);break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);// 注册广播registerReceiver(receiver, filter);// 通过id获取"打开蓝牙"按钮Button button_3 = (Button) findViewById(R.id.button7);// 绑定按钮点击事件处理函数button_3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {turnOnbt();}});}/*** 打开蓝牙*/public void turnONbt(){// 获取蓝牙权限getPermision();// 打开蓝牙btController.turnOnBlueTooth(this, 1);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){super.onActivityResult(requestCode, resultCode, data);if(resultCode == RESULT_OK){showToast("open successfully");}else{showToast("open unsuccessfully");}}
关闭蓝牙
/*** 关闭蓝牙* @return*/public void turnOffBlueTooth() {if(mAdapter.isEnabled()) {mAdapter.disable();}}
在MainActivity,java绑定功能
// 通过id获取”关闭蓝牙“按钮Button button_4 = (Button) findViewById(R.id.button8);// 绑定按钮点击事件处理函数button_4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 关闭蓝牙btController.turnOffBlueTooth();}});
使蓝牙可见
/*** 打开蓝牙可见性* @param context*/public void enableVisibly(Context context){Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);context.startActivity(discoverableIntent);}
在MainActivity.java中绑定函数
@Overrideprotected void onCreate(Bundle savedInstanceState) {// 通过id获取”使蓝牙可见“按钮Button button_5 = (Button) findViewById(R.id.button9);// 绑定按钮点击事件处理函数button_5.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 蓝牙可见BTVisible();}});}/*** 设置蓝牙可见*/public void BTVisible(){// 获取蓝牙权限getPermision();// 打开蓝牙可见btController.enableVisibly(this);}
搜索可见蓝牙
/*** 查找设备*/public boolean findDevice(){assert(mAdapter!=null);if(mAdapter.isDiscovering()){mAdapter.cancelDiscovery();return false;}else {return mAdapter.startDiscovery();}}
在MainActivity.java绑定函数
// 搜索蓝牙广播private IntentFilter foundFilter;//public ArrayAdapter adapter1;//定义一个列表,存蓝牙设备的地址。public ArrayList<String> arrayList=new ArrayList<>();//定义一个列表,存蓝牙设备地址,用于显示。public ArrayList<String> deviceName=new ArrayList<>();// 搜索蓝牙广播private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {String s;BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if (device.getBondState() == 12) {s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";}else if (device.getBondState() == 10){s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";}else{s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";}if (!deviceName.contains(s)) {deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。adapter1.notifyDataSetChanged();//更新}}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){showToast("搜索结束");unregisterReceiver(this);}else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){showToast("开始搜索");}};@Overrideprotected void onCreate(Bundle savedInstanceState) {// 通过id获取”搜索可见蓝牙“按钮Button button_6 = (Button) findViewById(R.id.button10);// 绑定按钮点击事件处理函数button_6.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 注册广播registerReceiver(bluetoothReceiver, foundFilter);// 初始化各列表arrayList.clear();deviceName.clear();adapter1.notifyDataSetChanged();// 开始搜索btController.findDevice();}});//搜索蓝牙的广播foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);// 获取ListView组件ListView listView = (ListView) findViewById(R.id.listview1);// 实例化ArrayAdapter对象adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);// 添加到ListView组件中listView.setAdapter(adapter1);}
查看已绑定的设备
/*** 获取绑定设备* @return*/public ArrayList<BluetoothDevice> getBondedDeviceList(){return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());}
绑定功能
// 通过id获取”查看已绑定蓝牙“按钮Button button_7 = (Button) findViewById(R.id.button11);// 绑定按钮点击事件处理函数button_7.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 初始化各列表deviceName.clear();arrayList.clear();adapter1.notifyDataSetChanged();// 获取已绑定蓝牙ArrayList<BluetoothDevice> bluetoothDevices = btController.getBondedDeviceList();// 更新列表for (int i = 0; i < bluetoothDevices.size(); i++){BluetoothDevice device = bluetoothDevices.get(i);arrayList.add(device.getAddress());if (device.getBondState() == 12) {deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n");}else if (device.getBondState() == 10){deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n");}else{deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n");}adapter1.notifyDataSetChanged();}}});
ListView的列表点击事件
添加点击监听@Overrideprotected void onCreate(Bundle savedInstanceState) {listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {CharSequence content = ((TextView) view).getText();String con = content.toString();String[] conArray = con.split("\n");String rightStr = conArray[1].substring(5, conArray[1].length());BluetoothDevice device = btController.find_device(rightStr);if (device.getBondState() == 10) {btController.cancelSearch();String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";deviceName.remove(s);device.createBond();s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";deviceName.add(s);adapter1.notifyDataSetChanged();showToast("配对:" + device.getName());}else{btController.cancelSearch();String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";if(deviceName.contains(s2)) {unpairDevice(device);deviceName.remove(s2);s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";deviceName.add(s2);adapter1.notifyDataSetChanged();showToast("取消配对:" + device.getName());}}}});}/*** 尝试取消配对* @param device*/private void unpairDevice(BluetoothDevice device) {try {Method m = device.getClass().getMethod("removeBond", (Class[]) null);m.invoke(device, (Object[]) null);} catch (Exception e) {e.printStackTrace();}}
MainActivity.java
package com.example.btapp;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import android.Manifest;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.os.Build;import android.os.Bundle;import android.util.Log;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 java.lang.reflect.Method;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {// 常量private static final int REQ_PERMISSION_CODE = 1;// 实例化蓝牙控制器public BlueToothController btController = new BlueToothController();// 弹窗private Toast mToast;// 蓝牙权限列表public ArrayList<String> requestList = new ArrayList<>();// 搜索蓝牙广播private IntentFilter foundFilter;//public ArrayAdapter adapter1;//定义一个列表,存蓝牙设备的地址。public ArrayList<String> arrayList=new ArrayList<>();//定义一个列表,存蓝牙设备地址,用于显示。public ArrayList<String> deviceName=new ArrayList<>();// 蓝牙状态改变广播private BroadcastReceiver receiver = new BroadcastReceiver(){@Overridepublic void onReceive(Context context, Intent intent) {int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);switch (state){case BluetoothAdapter.STATE_OFF:showToast("STATE_OFF");break;case BluetoothAdapter.STATE_ON:showToast("STATE_ON");break;case BluetoothAdapter.STATE_TURNING_OFF:showToast("STATE_TURNING_OFF");break;case BluetoothAdapter.STATE_TURNING_ON:showToast("STATE_TURNING_ON");break;default:showToast("UnKnow STATE");unregisterReceiver(this);break;}}};// 搜索蓝牙广播private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {String s;BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);if (device.getBondState() == 12) {s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";}else if (device.getBondState() == 10){s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";}else{s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n";}if (!deviceName.contains(s)) {deviceName.add(s);//将搜索到的蓝牙名称和地址添加到列表。arrayList.add(device.getAddress());//将搜索到的蓝牙地址添加到列表。adapter1.notifyDataSetChanged();//更新}}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){showToast("搜索结束");unregisterReceiver(this);}else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){showToast("开始搜索");}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 蓝牙状态改变信息IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);// 注册广播registerReceiver(receiver, filter);//搜索蓝牙的广播foundFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);foundFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);// 获取ListView组件ListView listView = (ListView) findViewById(R.id.listview1);// 实例化ArrayAdapter对象adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, deviceName);// 添加到ListView组件中listView.setAdapter(adapter1);listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {CharSequence content = ((TextView) view).getText();String con = content.toString();String[] conArray = con.split("\n");String rightStr = conArray[1].substring(5, conArray[1].length());BluetoothDevice device = btController.find_device(rightStr);if (device.getBondState() == 10) {btController.cancelSearch();String s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" + "\n";deviceName.remove(s);device.createBond();s = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";deviceName.add(s);adapter1.notifyDataSetChanged();showToast("配对:" + device.getName());}else{btController.cancelSearch();String s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n";if(deviceName.contains(s2)) {unpairDevice(device);deviceName.remove(s2);s2 = "设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n";deviceName.add(s2);adapter1.notifyDataSetChanged();showToast("取消配对:" + device.getName());}}}});// 通过id获取“是否支持蓝牙”按钮Button button_1 = (Button) findViewById(R.id.button3);// 绑定按钮点击事件处理函数button_1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 判断是否支持蓝牙boolean ret = btController.isSupportBlueTooth();// 弹窗显示结果showToast("是否支持蓝牙" + ret);}});// 通过id获取“当前蓝牙状态”按钮Button button_2 = (Button) findViewById(R.id.button4);// 绑定按钮点击事件处理函数button_2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 判断当前蓝牙状态boolean ret = btController.getBlueToothStatus();// 弹窗显示结果showToast("当前蓝牙状态:" + ret);}});// 通过id获取"打开蓝牙"按钮Button button_3 = (Button) findViewById(R.id.button7);// 绑定按钮点击事件处理函数button_3.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {turnONbt();}});// 通过id获取”关闭蓝牙“按钮Button button_4 = (Button) findViewById(R.id.button8);// 绑定按钮点击事件处理函数button_4.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 关闭蓝牙btController.turnOffBlueTooth();}});// 通过id获取”使蓝牙可见“按钮Button button_5 = (Button) findViewById(R.id.button9);// 绑定按钮点击事件处理函数button_5.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 蓝牙可见BTVisible();}});// 通过id获取”搜索可见蓝牙“按钮Button button_6 = (Button) findViewById(R.id.button10);// 绑定按钮点击事件处理函数button_6.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 注册广播registerReceiver(bluetoothReceiver, foundFilter);// 初始化各列表arrayList.clear();deviceName.clear();adapter1.notifyDataSetChanged();// 开始搜索btController.findDevice();}});// 通过id获取”查看已绑定蓝牙“按钮Button button_7 = (Button) findViewById(R.id.button11);// 绑定按钮点击事件处理函数button_7.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 获取蓝牙权限getPermision();// 初始化各列表deviceName.clear();arrayList.clear();adapter1.notifyDataSetChanged();// 获取已绑定蓝牙ArrayList<BluetoothDevice> bluetoothDevices = btController.getBondedDeviceList();// 更新列表for (int i = 0; i < bluetoothDevices.size(); i++){BluetoothDevice device = bluetoothDevices.get(i);arrayList.add(device.getAddress());if (device.getBondState() == 12) {deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:已配对" + "\n");}else if (device.getBondState() == 10){deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未配对" +"\n");}else{deviceName.add("设备名:" + device.getName() + "\n" + "设备地址:" + device.getAddress() + "\n" + "连接状态:未知" + "\n");}adapter1.notifyDataSetChanged();}}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){super.onActivityResult(requestCode, resultCode, data);if(resultCode == RESULT_OK){showToast("open successfully");}else{showToast("open unsuccessfully");}}/*** 尝试取消配对* @param device*/private void unpairDevice(BluetoothDevice device) {try {Method m = device.getClass().getMethod("removeBond", (Class[]) null);m.invoke(device, (Object[]) null);} catch (Exception e) {e.printStackTrace();}}/*** 打开蓝牙*/public void turnONbt(){// 获取蓝牙权限getPermision();// 打开蓝牙btController.turnOnBlueTooth(this,1);}/*** 设置蓝牙可见*/public void BTVisible(){// 获取蓝牙权限getPermision();// 打开蓝牙可见btController.enableVisibly(this);}/*** 动态申请权限*/public void getPermision(){if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){requestList.add(Manifest.permission.BLUETOOTH_SCAN);requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);requestList.add(Manifest.permission.BLUETOOTH_CONNECT);requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);requestList.add(Manifest.permission.BLUETOOTH);}if(requestList.size() != 0){ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), REQ_PERMISSION_CODE);}}/*** Toast弹窗显示* @param text 显示文本*/public void showToast(String text){// 若Toast控件未初始化if( mToast == null){// 则初始化mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);}// 否则else{// 修改显示文本mToast.setText(text);}// 显示mToast.show();}}
list_item.xml
<?xml version="1.0" encoding="UTF-8"?><TextView xmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:textSize="18sp"></TextView>
BlueToothController.java
package com.example.btapp;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothSocket;import android.content.Context;import android.content.Intent;import android.util.Log;import android.widget.Toast;import java.lang.reflect.Method;import java.util.ArrayList;/*** 蓝牙适配器*/public class BlueToothController {// 成员变量private BluetoothSocket btSocket;private BluetoothAdapter mAdapter;private String TAG = "";public static final int RECV_VIEW = 0;public static final int NOTICE_VIEW = 1;/*** 构造函数*/public BlueToothController(){// 获取本地的蓝牙适配器mAdapter = BluetoothAdapter.getDefaultAdapter();}/*** 是否支持蓝牙* @return true支持,false不支持*/public boolean isSupportBlueTooth(){// 若支持蓝牙,则本地适配器不为nullif(mAdapter != null){return true;}// 否则不支持else{return false;}}/*** 判断当前蓝牙状态* @return true为打开,false为关闭*/public boolean getBlueToothStatus(){// 断言?为了避免mAdapter为null导致return出错assert (mAdapter != null);// 蓝牙状态return mAdapter.isEnabled();}/*** 打开蓝牙*/public void turnOnBlueTooth(Activity activity, int requestCode){if(!mAdapter.isEnabled()) {Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);activity.startActivityForResult(intent, requestCode);}}/*** 关闭蓝牙* @return*/public void turnOffBlueTooth() {if(mAdapter.isEnabled()) {mAdapter.disable();}}/*** 打开蓝牙可见性* @param context*/public void enableVisibly(Context context){Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);context.startActivity(discoverableIntent);}/*** 查找设备*/public boolean findDevice(){assert(mAdapter!=null);if(mAdapter.isDiscovering()){mAdapter.cancelDiscovery();return false;}else {return mAdapter.startDiscovery();}}/*** 获取绑定设备* @return*/public ArrayList<BluetoothDevice> getBondedDeviceList(){return new ArrayList<BluetoothDevice>(mAdapter.getBondedDevices());}/*** 根据蓝牙地址找到相应的设备* @param addr* @return*/public BluetoothDevice find_device(String addr){return mAdapter.getRemoteDevice(addr);}/*** 连接设备*/public void connect_init(BluetoothDevice device){mAdapter.cancelDiscovery();try{Method clientMethod = device.getClass().getMethod("createRfcommSocketToServiceRecord", new Class[]{int.class});btSocket = (BluetoothSocket)clientMethod.invoke(device, 1);connect(btSocket);}catch (Exception e){e.printStackTrace();}}public void connect(final BluetoothSocket btSocket){try {if (btSocket.isConnected()){Log.e(TAG, "connect: 已经连接");return;}btSocket.connect();if (btSocket.isConnected()){Log.e(TAG, "connect: 连接成功");}else{Log.e(TAG, "connect: 连接失败");btSocket.close();}}catch (Exception e){e.printStackTrace();}}public void cancelSearch() {mAdapter.cancelDiscovery();}}