onServicesDiscovery()回调

krugob8w  于 2021-06-29  发布在  Java
关注(0)|答案(2)|浏览(279)

我正在构建一个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;
    }
}
2jcobegt

2jcobegt1#

为什么要确保discoverservices()方法在ui线程上运行?这是一个异步操作。试试新的线。

z3yyvxxp

z3yyvxxp2#

我只需要把扫描延迟600毫秒。

相关问题