[英]Android bluetooth scan periodic advertising
我是 Android 開發和藍牙的新手,所以如果我的問題聽起來很愚蠢,請原諒我,我正在使用他們的 nrf connect sdk 2.0.0 示例藍牙定期廣告在 Nordic 52840 上工作,我想掃描我的北歐設備並接收廣告數據使用 android 手機 Android 10.0,我可以使用我的代碼找到其他設備,例如一些筆記本電腦、三星電視等,但找不到我需要的北歐設備。
package com.example.ble_scanner;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.Tag;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MyActivity";
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothLeScanner mBluetoothLeScanner = null;
public ArrayList<BluetoothDevice> mBTdevice=new ArrayList<>();
public DeviceListAdapter mDeviceListAdapter;
ListView lvNewDevice;
public static final int REQUEST_BT_PERMISSIONS = 0;
public static final int REQUEST_BT_ENABLE = 1;
private boolean mScanning = false;
private Handler mHandler = null;
private Button btnScan = null;
private final BroadcastReceiver mBroadcastreceiver1=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action =intent.getAction();
if(action.equals(mBluetoothAdapter.ACTION_STATE_CHANGED)){
final int state=intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,mBluetoothAdapter.ERROR);
switch (state){
case BluetoothAdapter.STATE_OFF:
Log.d(TAG,"STATE OFF");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.d(TAG,"TURNNING OFF");
break;
case BluetoothAdapter.STATE_ON:
Log.d(TAG,"STATE ON");
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.d(TAG,"TURNNING ON");
break;
}
}
}
};
private final BroadcastReceiver mBroadcastreceiver2=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action =intent.getAction();
if(action.equals(mBluetoothAdapter.ACTION_SCAN_MODE_CHANGED)){
final int state=intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,mBluetoothAdapter.ERROR);
switch (state){
case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
Log.d(TAG,"DISCOVERABLE");
break;
case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
Log.d(TAG,"Discoverability Disable,Able to receive connection");
break;
case BluetoothAdapter.SCAN_MODE_NONE:
Log.d(TAG,"Discoverability Disable,unable to receive connection");
break;
case BluetoothAdapter.STATE_CONNECTING:
Log.d(TAG,"Connecting...");
break;
case BluetoothAdapter.STATE_CONNECTED:
Log.d(TAG,"Connected");
break;
}
}
}
};
private final BroadcastReceiver mBroadcastreceiver3=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action =intent.getAction();
Log.d(TAG,"onReceive:ACTION FOUND");
if(action.equals(BluetoothDevice.ACTION_FOUND)){
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mBTdevice.add(device);
Log.d(TAG,"onReceive: "+device.getName()+" : "+device.getAddress());
mDeviceListAdapter=new DeviceListAdapter(context,R.layout.device_adapter_view,mBTdevice);
lvNewDevice.setAdapter(mDeviceListAdapter);
}
}
};
@Override
protected void onDestroy() {
Log.d(TAG,"onDestroy called");
super.onDestroy();
unregisterReceiver(mBroadcastreceiver1);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvNewDevice=(ListView)findViewById(R.id.lvNewDevice);
mBTdevice=new ArrayList<>();
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
Button Btbtn=(Button) findViewById(R.id.button);
Btbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG,"enable disable button");
enabledisableBT();
}
});
Button discover=(Button)findViewById(R.id.button3);
discover.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
discoverenabledisable();
}
});
Button scan=(Button)findViewById(R.id.button4);
scan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scanBTDevice();
}
});
}
public void enabledisableBT(){
if(mBluetoothAdapter==null){
Log.d(TAG,"Does not have BT function");
}
if(!mBluetoothAdapter.isEnabled()){
Intent enableBTIntent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBTIntent);
IntentFilter BTIntent=new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastreceiver1,BTIntent);
}
if(mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.disable();
IntentFilter BTIntent=new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBroadcastreceiver1,BTIntent);
}
}
public void discoverenabledisable(){
Log.d(TAG,"make device discoverable for 300 second");
Intent discoverableIntent= new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
startActivity(discoverableIntent);
IntentFilter intentFilter=new IntentFilter(mBluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mBroadcastreceiver2,intentFilter);
}
public void scanBTDevice(){
Log.d(TAG,"Scan device");
if(mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
Log.d(TAG,"cancel scan");
checkBTPermission();
mBluetoothAdapter.startDiscovery();
IntentFilter discoveryDeviceIntent =new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastreceiver3,discoveryDeviceIntent);
}
if(!mBluetoothAdapter.isDiscovering()){
checkBTPermission();
mBluetoothAdapter.startDiscovery();
IntentFilter discoveryDeviceIntent =new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastreceiver3,discoveryDeviceIntent);
}
}
private void checkBTPermission(){
if(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP){
int pc=this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
pc+=this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if(pc!=0){
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},1001);
}else {
Log.d(TAG,"checkBT permission");
}
}
}
您的代碼當前正在搜索經典藍牙設備,但您的 nRF52840 正在使用藍牙低功耗 (BLE)。 這些都是藍牙標准的一部分,但不兼容。 請閱讀BLE 概述以及 Android 開發者文檔的查找 BLE 設備頁面。
對於許多開發人員來說,BLE 可能很難處理,並且有很多在線指南可以幫助您比 Android 文檔更進一步。 我個人使用 Martijn van Welie 的制作 Android BLE 工作指南取得了成功。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.