我正在构建一个android应用程序来连接和读取基于arduino的可编程设备上的数据。我能够找到并连接到设备,但由于某种原因,无论我如何努力,onservicesdiscovered()回调函数都不会被调用。我已经试过等待600毫秒,直到发现,甚至1.5秒,我确保discoverservices()命令正在ui线程上运行,并多次重做蓝牙代码。以前我成功地做到了这一点,函数也会被调用,但我想把所有的蓝牙代码放在它自己单独的类文件中,以清理我的主活动文件,我这样做时没有创建备份,这就是我的问题开始的地方。于是我又试着在主文件中重做一次,但没有效果。
编辑:我发布的原始代码无论如何都不起作用,所以这是更新的代码,但有相同的错误。
这是我的代码(这是我的主要活动文件):
package com.example.androidrf;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.UUID;
import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
public class MainActivity extends AppCompatActivity {
public TabLayout tabLayout;
public ViewPager2 viewPager;
public TextView connectionWarning;
// Bluetooth Variables
BluetoothManager bluetoothManager;
BluetoothAdapter bluetoothAdapter;
private static final int REQUEST_ENABLE_BT = 1;
// UUID's
private String arduinoName;
private String serviceId;
private String ledCharacteristicId;
private String numberCharacteristicId;
private UUID serviceUUID;
private UUID ledCharUUID;
private UUID numCharUUID;
// Scan Settings
private ScanFilter scanFilter;
private ScanSettings scanSettings;
// GATT, Characteristics, and Services
private BluetoothGatt gatt;
private BluetoothGattService service;
private BluetoothGattCharacteristic ledChar;
private BluetoothGattCharacteristic numberChar;
// Scanning Related Code
private final BluetoothLeScanner bluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
private boolean mScanning;
private final Handler handler = new Handler();
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
private void scanDevices(boolean forceStop) {
if (forceStop) {
mScanning = false;
bluetoothLeScanner.stopScan(scanCallback);
}
}
private void scanDevices() {
if (!mScanning) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(() -> {
if (!mScanning) return;
mScanning = false;
bluetoothLeScanner.stopScan(scanCallback);
}, SCAN_PERIOD);
if (deviceFound) return;
mScanning = true;
bluetoothLeScanner.startScan(Collections.singletonList(scanFilter), scanSettings, scanCallback);
} else {
mScanning = false;
bluetoothLeScanner.stopScan(scanCallback);
}
}
// Scan Callback
private boolean deviceFound;
private final ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
if (deviceFound) {
bluetoothLeScanner.flushPendingScanResults(this);
if (mScanning) scanDevices(true);
return;
}
if (result.getScanRecord().getDeviceName().equals(arduinoName)) {
deviceFound = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> gatt = result.getDevice().connectGatt(getBaseContext(), false, gattCallback, TRANSPORT_LE), 600);
//gatt.connect();
}
}
};
// GATT Callback
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
Log.d("Gatt Services", "Status: " + status + ", newState: " + newState);
if (status == BluetoothGatt.GATT_SUCCESS) {
if (newState == BluetoothGatt.STATE_CONNECTED) {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
Log.d("Gatt Services", "Discovering Services");
runOnUiThread(gatt::discoverServices);
}, 600);
}
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.d("Gatt Characteristics", "Success");
if (status == BluetoothGatt.GATT_SUCCESS) {
ledChar = gatt.getService(serviceUUID).getCharacteristic(ledCharUUID);
numberChar = gatt.getService(serviceUUID).getCharacteristic(numCharUUID);
gatt.setCharacteristicNotification(numberChar, true);
}
}
// @Override
// public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// super.onCharacteristicRead(gatt, characteristic, status);
// }
//
// @Override
// public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// super.onCharacteristicWrite(gatt, characteristic, status);
// }
//
// @Override
// public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// super.onCharacteristicChanged(gatt, characteristic);
// }
//
// @Override
// public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
// super.onReadRemoteRssi(gatt, rssi, status);
// }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectionWarning = findViewById(R.id.warningLabel);
//Bluetooth ------------------------------------------------------------------------------------------
bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
arduinoName = getResources().getString(R.string.arduino_name);
serviceId = getResources().getString(R.string.service_id);
ledCharacteristicId = getResources().getString(R.string.led_char_id);
numberCharacteristicId = getResources().getString(R.string.num_char_id);
serviceUUID = UUID.fromString(serviceId);
ledCharUUID = UUID.fromString(ledCharacteristicId);
numCharUUID = UUID.fromString(numberCharacteristicId);
scanFilter = new ScanFilter.Builder().setDeviceName(arduinoName).build();
scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_BALANCED)
//.setCallbackType(ScanSettings.CALLBACK_TYPE_FIRST_MATCH)
.build();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
scanDevices();
//ViewPager ------------------------------------------------------------------------------------------
sectionsPagerAdapter SectionsPagerAdapter = new sectionsPagerAdapter(this);
viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(SectionsPagerAdapter);
// Tab Layout ----------------------------------------------------------------------------------------
tabLayout = findViewById(R.id.tabs);
new TabLayoutMediator(tabLayout, viewPager, true, true, (tab, position) -> {
String text = "";
switch(position) {
case 0:
text = getString(R.string.tab_text_1);
break;
case 1:
text = getString(R.string.tab_text_2);
break;
}
tab.setText(text);
}).attach();
}
private static class sectionsPagerAdapter extends FragmentStateAdapter {
public sectionsPagerAdapter(FragmentActivity fa) {
super(fa);
}
@NotNull
@Override
public Fragment createFragment(int position) {
Fragment fragment = null;
switch(position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new SettingsFragment();
break;
}
return fragment;
}
@Override
public int getItemCount() {
return 2;
}
}
@Override
public void onStop() {
super.onStop();
if (gatt == null) return;
gatt.close();
gatt = null;
}
}
2条答案
按热度按时间2jcobegt1#
为什么要确保discoverservices()方法在ui线程上运行?这是一个异步操作。试试新的线。
z3yyvxxp2#
我只需要把扫描延迟600毫秒。