Android Studio 蓝牙 示例代码(转)
原文:https://blog.csdn.net/qq_40511184/article/details/122698077
因为android studio升级,下面代码中的startactivityresult函数有变化 ,不能使用,需要更换为
public ActivityResultLauncher<Intent> register;
ActivityResultLauncher<Intent> startBlueTooth = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>()
- 首先在app/src/main/AndroidManifest.xml中添加权限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/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" /> <application android: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"> <activity android: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>
- Acitivity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android: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" /> <Button android: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.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_begin="205dp" /> <Button android: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" /> <Button android: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" /> <Button android: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" /> <Button android: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" /> <Button android: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" /> <ListView android: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" /> <TextView android: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>
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(){ @Override public 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() { @Override public 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("开始搜索"); } } }; @Override protected 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() { @Override public 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() { @Override public 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() { @Override public 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() { @Override public void onClick(View view) { turnONbt(); } }); // 通过id获取”关闭蓝牙“按钮 Button button_4 = (Button) findViewById(R.id.button8); // 绑定按钮点击事件处理函数 button_4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 获取蓝牙权限 getPermision(); // 关闭蓝牙 btController.turnOffBlueTooth(); } }); // 通过id获取”使蓝牙可见“按钮 Button button_5 = (Button) findViewById(R.id.button9); // 绑定按钮点击事件处理函数 button_5.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 蓝牙可见 BTVisible(); } }); // 通过id获取”搜索可见蓝牙“按钮 Button button_6 = (Button) findViewById(R.id.button10); // 绑定按钮点击事件处理函数 button_6.setOnClickListener(new View.OnClickListener() { @Override public 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() { @Override public 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(); } } }); } @Override protected 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="http://schemas.android.com/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(){ // 若支持蓝牙,则本地适配器不为null if(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(); } }
ListView的列表点击事件
- 添加点击监听
@Override protected void onCreate(Bundle savedInstanceState) { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public 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(); } }
活到老,学到老。