Android Studio(Java)蓝牙扫描器开发求助:获取设备硬件信息
Android蓝牙设备扫描应用开发指导
我有一项作业要求使用Android Studio开发一款移动应用,需实现扫描附近蓝牙设备,并在扫描完成后获取设备的硬件名称、型号及厂商名称。参考资料自行实现后未能成功,使用Java开发,附上我的代码求指导:
我的Java类代码
package com.example.bluetoothvulnerabilityscanner; import androidx.appcompat.app.AppCompatActivity; import android.Manifest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Build; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; import androidx.core.app.ActivityCompat; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.Intent; import android.view.View; import android.widget.Button; import java.util.ArrayList; import java.util.Set; public class ScanAroundDevices extends AppCompatActivity { BluetoothAdapter bluetoothAdapter; ArrayAdapter<String> arrayAdapter; ArrayList<String> arrayList; ListView listView; // 修正:原变量名11为Java非法标识符 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scan_around_devices); bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); listView = findViewById(R.id.listView); arrayList = new ArrayList<>(); arrayAdapter = new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, arrayList); listView.setAdapter(arrayAdapter); findPairedDevices(); } private void findPairedDevices() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 100); return; } Set<BluetoothDevice> bluetoothSet = bluetoothAdapter.getBondedDevices(); if (bluetoothSet.size() > 0) { arrayList.clear(); for (BluetoothDevice device : bluetoothSet) { arrayList.add("已配对:" + device.getName() + "\n地址:" + device.getAddress()); } arrayAdapter.notifyDataSetChanged(); } } public void discoverDevices(View v) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN}, 101); return; } } arrayList.clear(); bluetoothAdapter.startDiscovery(); Toast.makeText(this, "开始扫描蓝牙设备", Toast.LENGTH_SHORT).show(); } BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (ActivityCompat.checkSelfPermission(ScanAroundDevices.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) { return; } // 扫描到的基础信息,型号/厂商需连接后获取 String deviceInfo = "名称:" + (device.getName() != null ? device.getName() : "未知设备") + "\n地址:" + device.getAddress(); if (!arrayList.contains(deviceInfo)) { arrayList.add(deviceInfo); arrayAdapter.notifyDataSetChanged(); } } } }; @Override protected void onStart() { super.onStart(); IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(broadcastReceiver, intentFilter); // 修正:广播注册参数错误 } @Override protected void onStop() { super.onStop(); unregisterReceiver(broadcastReceiver); // 补充:避免内存泄漏 } public void on(View v) { if (bluetoothAdapter == null) { Toast.makeText(getApplicationContext(), "设备不支持蓝牙", Toast.LENGTH_SHORT).show(); return; } if (!bluetoothAdapter.isEnabled()) { // 修正:判断条件逻辑错误 Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(i, 1); } else { Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) { if (resultCode == RESULT_OK) { Toast.makeText(getApplicationContext(), "蓝牙已开启", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(getApplicationContext(), "用户拒绝开启蓝牙", Toast.LENGTH_SHORT).show(); } } else if (requestCode == 2) { if (resultCode == RESULT_OK) { Toast.makeText(getApplicationContext(), "蓝牙已关闭", Toast.LENGTH_SHORT).show(); } } } public void off(View v) { if (bluetoothAdapter == null) { Toast.makeText(getApplicationContext(), "设备不支持蓝牙", Toast.LENGTH_SHORT).show(); return; } if (bluetoothAdapter.isEnabled()) { Intent i = new Intent(BluetoothAdapter.ACTION_REQUEST_DISABLE); // 修正:关闭蓝牙的Intent错误 startActivityForResult(i, 2); } else { Toast.makeText(this, "蓝牙已关闭", Toast.LENGTH_SHORT).show(); } } }
我的XML布局代码
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ScanAroundDevices"> <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginTop="25dp" android:onClick="on" android:text="开启蓝牙"/> <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignTop="@+id/btn1" android:onClick="off" android:text="关闭蓝牙"/> <Button android:id="@+id/btn_scan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btn1" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:onClick="discoverDevices" android:text="扫描设备"/> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/btn_scan" android:layout_marginTop="20dp"/> </RelativeLayout>
关键修复与说明
- 变量命名修正:将非法的
11变量名改为listView,符合Java语法规范 - 广播注册修正:修复
onStart()中广播注册的参数错误,补充onStop()注销广播避免内存泄漏 - 蓝牙开关逻辑修正:
- 开启蓝牙时,仅在蓝牙未开启时发起请求,避免重复操作
- 关闭蓝牙使用正确的
ACTION_REQUEST_DISABLEIntent,并用startActivityForResult处理用户操作结果
- 权限处理:
- Android 12及以上添加
BLUETOOTH_SCAN权限,动态申请扫描权限 - 修正BroadcastReceiver中的权限检查上下文,使用Activity实例而非内部类的
this
- Android 12及以上添加
- 布局补充:添加扫描按钮和ListView,实现扫描触发和结果展示
- 设备信息说明:扫描阶段仅能获取设备名称、MAC地址;型号及厂商信息需要与设备建立GATT连接后,通过
BluetoothGattCharacteristic读取(不同设备支持的属性存在差异)
清单文件需添加的权限
在AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/> <uses-feature android:name="android.hardware.bluetooth" android:required="true"/>
内容的提问来源于stack exchange,提问作者JustAnAmateurCoder
相关产品推荐
相关产品推荐

