我目前正在开发一款小应用,以开始使用蓝牙Android API提供的服务。
编辑 - >回答:
问题似乎是由于特定的Nexus 5设备。好像他们的蓝牙接收器不能很好地工作。以下解决方案适用于其他设备
注:
我在这里阅读了文档:http://developer.android.com/guide/topics/connectivity/bluetooth.html 以及本教程的以下源代码http://www.londatiga.net/it/programming/android/how-to-programmatically-scan-or-discover-android-bluetooth-device/位于/ lorensiuswlt / AndroBluetooth下的github上
我已经完成了几乎所有感兴趣的功能(例如检查适配器是否存在,启用/禁用蓝牙,查询配对的divices,设置适配器可被发现)。
问题:
当我启动.onDiscovery()方法时,实际上没有找到设备,即使在我的Nexus 5上的设置/蓝牙中找到了设备。
以下是我的处理方式:
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
...
protected void onCreate(Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
}
过滤器运行良好尽可能尝试,即ACTION_STATE_CHANGED(启用蓝牙功能)和两个ACTION_DISCOVERY _ ***。
然后成功地调用以下方法:
public void onDiscovery(View view)
{
mBluetoothAdapter.startDiscovery();
}
然后我有我的蓝牙接收器:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON) {
showToast("ACTION_STATE_CHANGED: STATE_ON");
}
}
else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
mDeviceList = new ArrayList<>();
showToast("ACTION_DISCOVERY_STARTED");
mProgressDlg.show();
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action) && !bluetoothSwitchedOFF) {
mProgressDlg.dismiss();
showToast("ACTION_DISCOVERY_FINISHED");
Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);
newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
startActivity(newIntent);
}
else if (BluetoothDevice.ACTION_FOUND.equals(action)) {// When discovery finds a device
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
showToast("Device found = " + device.getName());
}
}
};
我没有在logcat上发现任何问题,在我做的测试中没有发现任何问题。唯一的问题是扫描结束时没有设备被发现,当时有许多可发现的设备可用。
我试图不要放太多代码以免泛滥主题。问我是否需要更多。
感谢您的阅读,并提前感谢您的答案。
答案 0 :(得分:68)
你在运行什么版本的Android?如果是Android 6.x,我相信您需要为清单添加ACCESS_COURSE_LOCATION
权限。例如:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
我有一个类似的问题,这为我解决了。
更新:在此处添加documentation direct from Google:
要通过蓝牙和Wi-Fi扫描访问附近外部设备的硬件标识符,您的应用现在必须具有
ACCESS_FINE_LOCATION
或ACCESS_COARSE_LOCATION
权限
答案 1 :(得分:56)
派对迟到了,但这对其他人来说可能会派上用场。
你需要做两件事
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
或<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
到您的AndroidManifest.xml
请确保您使用此类内容为Android 6.0设备请求运行时权限
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
在mBluetoothAdapter.startDiscovery();
如果您不执行第2步,则无法在使用Android&gt; = 6.0的设备上获取任何硬件标识符信息
<强> UPDATE /编辑:强>
将Android版本检查和警告对话框作为警告示例
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // Only ask for these permissions on runtime when running Android 6.0 or higher
switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
case PackageManager.PERMISSION_DENIED:
((TextView) new AlertDialog.Builder(this)
.setTitle("Runtime Permissions up ahead")
.setMessage(Html.fromHtml("<p>To find nearby bluetooth devices please click \"Allow\" on the runtime permissions popup.</p>" +
"<p>For more info see <a href=\"http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id\">here</a>.</p>"))
.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(DeviceListActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_ACCESS_COARSE_LOCATION);
}
}
})
.show()
.findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance()); // Make the link clickable. Needs to be called after show(), in order to generate hyperlinks
break;
case PackageManager.PERMISSION_GRANTED:
break;
}
}