问题描述
我正在开发一个应用,可以在谷歌地图中看到多部安卓手机。
用例:
到目前为止一切都很好
我想要的:
- 通过 BLE 将 Android 设备相互连接,以便可以读取 RSSI 值
在方法 onResume() 中开始扫描 BLE 设备。此处的扫描过滤器为 NULL,因此扫描所有设备。在 onScanResult() 方法中显示找到的设备。
这是我的问题: 它向我显示电视和任何其他 BLE 设备以及它们的 RSSI 值等,但不显示 Android 手机。
我在手机上启用了定位和蓝牙功能。
为了测试,我在手机上安装了“nrf connect”,但其他手机也没有被扫描
我认为我的设备支持蓝牙 BLE。它们是 Pixel 4a(5G)
更新
我添加了信标发射器。现在,当我在两个设备上运行代码时,nrfConnect 检测我的设备但是:
- nrF 连接器仅扫描我最初运行应用程序的第一个设备
- 当我调试第二部手机以检测第一部手机时,找不到第一部手机(但可以在 nrfconnector 上找到)
在android xml中我有以下权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.BLUetoOTH"/>
<uses-permission android:name="android.permission.BLUetoOTH_ADMIN"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"
tools:ignore="ProtectedPermissions" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
这是我的 Fragment 类 AnsichtFragment.java
public class AnsichtFragment extends Fragment {
private static final String TAG = "AnsichtFragment";
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
private final long MIN_TIME = 1000; //miliseconds
private final long MIN_disT = 5; // meters
Map<String,Marker> mNamedMarkers = new HashMap<String,Marker>();
private BluetoothLeScanner bluetoothLeScanner;
private boolean scanning;
private BluetoothDevice mDevice;
private List<ScanFilter> filters;
private ScanSettings settings;
private String deviceUUID;
private String leName;
private Handler handler;
//private LeDevicelistadapter leDevicelistadapter;
private BluetoothAdapter bluetoothAdapter;
private List<String> uuids;
private BluetoothGatt mGatt;
private MapView mMapView;
private GoogleMap googleMap;
private FusedLocationProviderClient fusedLocationClient;
private LocationListener locationListener;
private LocationManager locationManager;
private LocationRequest locationRequest;
private String uniqueID;
private DatabaseReference databaseReference;
private DatabaseReference refToParent;
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
// Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUetoOTH_LE)) {
Toast.makeText(this.getContext(),R.string.ble_not_supported,Toast.LENGTH_SHORT).show();
//finish();
}
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getActivity().getSystemService(Context.BLUetoOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
// Ensures Bluetooth is available on the device and it is enabled. If not,// displays a dialog requesting user permission to enable Bluetooth.
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
}
uuids = new ArrayList<>();
handler = new Handler(Looper.getMainLooper());//Handler();
leName = bluetoothAdapter.getName();
......
//initialize view
View rootView = inflater.inflate(R.layout.fragment_tab_ansicht,container,false);
......
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap mMap) {
....
if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && getActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Todo: Consider calling
// Activity#requestPermissions
// here to request the missing permissions,and then overriding
// public void onRequestPermissionsResult(int requestCode,String[] permissions,// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for Activity#requestPermissions for more details.
return;
}
try {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME,MIN_disT,locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,locationListener);
} catch (Exception e) {
e.printstacktrace();
}
}
});
return rootView;
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device,int RSSi,byte[] scanRecord) {
handler.post(new Runnable() {
@Override
public void run() {
//return remote bluetooth device
connectToDevice(device);
}
});
}
};
private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType,ScanResult result) {
Log.i("callbackType",String.valueOf(callbackType));
Log.i("name",String.valueOf(result));
String callBackDeviceName = result.getDevice().getName();
String deviceAddress = result.getDevice().getAddress();
//String RSSi = result.getRSSi;
if (callBackDeviceName != null){
if (callBackDeviceName.startsWith("Pi")){
Log.i("result","Device name: "+callBackDeviceName);
Log.i("result",result.toString());
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice);
}
}
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult – Results",sr.toString());
}
}
@Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed","Error Code: " + errorCode);
}
};
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
Log.d("connectToDevice","connecting to device: "+device.toString());
this.mDevice = device;
mGatt = device.connectGatt(this.getContext(),false,gattCallback);
scanLeDevice(false);// will stop after first device detection
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
Log.i("onConnectionStateChange","Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
Log.i("gattCallback","STATE_CONNECTED");
//update UI
Message msg = Message.obtain();
String deviceName = gatt.getDevice().getName();
msg.obj = deviceName;
msg.what = 0;
msg.setTarget(handler);
msg.sendToTarget();
gatt.discoverServices();
break;
case BluetoothProfile.STATE_disCONNECTED:
Log.e("gattCallback","STATE_disCONNECTED");
Log.i("gattCallback","reconnecting…");
BluetoothDevice mDevice = gatt.getDevice();
mGatt = null;
connectToDevice(mDevice);
break;
default:
Log.e("gattCallback","STATE_OTHER");
}
}
@Override
public void onServicesdiscovered(BluetoothGatt gatt,int status) {
mGatt = gatt;
List<BluetoothGattService> services = gatt.getServices();
Log.i("onServicesdiscovered",services.toString());
BluetoothGattCharacteristic therm_char = services.get(2).getcharacteristics().get(0);
for (BluetoothGattDescriptor descriptor : therm_char.getDescriptors()) {
descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
mGatt.writeDescriptor(descriptor);
}
//gatt.readCharacteristic(therm_char);
gatt.setCharacteristicNotification(therm_char,true);
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic
characteristic,int status) {
Log.i("onCharacteristicRead",characteristic.toString());
byte[] value=characteristic.getValue();
String v = new String(value);
Log.i("onCharacteristicRead","Value: " + v);
//gatt.disconnect();
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic
characteristic) {
float char_float_value = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT,1);
Log.i("onCharacteristicChanged",Float.toString(char_float_value));
String deviceName = gatt.getDevice().getName();
String value = null;
}
};
@SuppressLint("MissingPermission")
private void getCurrentLocationWithLatLong() {
.....
}
@Override
public void onResume() {
mMapView.onResume();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
} else {
if (Build.VERSION.SDK_INT >= 21) {
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
filters = new ArrayList<ScanFilter>();
}
scanLeDevice(true);
}
super.onResume();
}
@Override
public void onPause() {
super.onPause();
if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
scanLeDevice(false);
}
}
@Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
super.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
private MarkerOptions getMarkerOptions(String key) {
.....
}
private void scanLeDevice(final boolean enable) {
if (enable) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (Build.VERSION.SDK_INT < 21) {
bluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
bluetoothLeScanner.stopScan(mScanCallback);
}
}
},SCAN_PERIOD);
if (Build.VERSION.SDK_INT < 21) {
bluetoothAdapter.startLeScan(mLeScanCallback);
} else {
//bluetoothLeScanner.startScan(filters,settings,mScanCallback);
bluetoothLeScanner.startScan(mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
bluetoothAdapter.stopLeScan(mLeScanCallback);
} else {
bluetoothLeScanner.stopScan(mScanCallback);
}
}
}
private void readUUIDsFromFirebase() {
....
}
....
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)