首页 > 解决方案 > Android 应用程序中的 BLE 错误:错误:bta_gattc_utils.cc(434)] bta_gattc_mark_bg_conn 无法找到 bg 连接掩码

问题描述

我是 android 和 BLE 的新手。我正在开发 BLE android 应用程序。在应用程序中,我们正在检查 2 个设备之间的电池百分比和距离。我们需要捕获这些详细信息并将其保存到文件中。

目前我们能够完成这项任务,但只有几秒钟。几秒钟后,它失败并出现以下错误。也请找到下面的代码供您参考。

Android 版本 : 10 三星 A31 测试

错误:错误:bta_gattc_utils.cc(434)] bta_gattc_mark_bg_conn 无法找到 bd_addr=a4:c1:38:a2:c1:f9 的 bg 连接掩码

Code : 
**MainActivity.java**
package com.renesas.socialband;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.gson.Gson;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity implements devicedata, SettingFragment.OnHeadlineSelectedListener,
        DataDisplayFragment.onDisplayFragmentPause {

    private static final int REQUEST_ENABLE_BT = 1;
    public static final int BLE_INIT_CMD = 7;
    public static final int BLE_INIT_IND = 8;
    public static final int BLE_INIT_COMPLETE = 9;
    public static final int BLE_NULL = 10;
    public static final int BLE_SCAN_CMD = 2;
    private static final int BLE_SCANNING = 11;
    public static final int BLE_SCAN_DEV_IND = 3;
    public static final int BLE_SCAN_COMPLETE_IND = 4;
    public static final int BLE_SCAN_CANCEL_CMD = 5;
    private static final int BLE_SCAN_CANCEL_IND = 6;
    public static final int BLE_CONNECT_CMD = 12;
    public static final int BLE_CONNECTING = 17;
    public static final int BLE_CONNECTED = 22;
    public static final int BLE_CONNECTION_SUCCESS = 13;
    public static final int BLE_DISCONNECT_CMD = 20;
    public static final int BLE_DISCONNECTING = 28;
    public static final int BLE_DISCONNECTED = 18;
    public static final int BLE_NOTIFICATION_DISTANCE_DATA = 14;
    public static final int BLE_NOTIFICATION_DEVICE_INFORMATION = 15;
    public static final int BLE_WRITE_DEVICE_CONFIG_DATA = 16;


    private BluetoothLeScanner bluetoothLeScanner;
    private int myBleState = BLE_NULL;
    private String mydeviceSettings;
    BluetoothGatt gatt;
    List<BluetoothGattService> mygattservices;
    myBluetoothhandler p;
    BluetoothAdapter bluetoothAdapter;
    BluetoothDevice connectedDevice;
    private Boolean SettingFragmentDisplayed = false;
    @Override
    public void onArticleSelected( String config ) {
        Log.e("BLE", "Receiving settings data = " + config);
        myBleDispatcher(BLE_WRITE_DEVICE_CONFIG_DATA, null, config);
    }

    @Override
    public void onmyDisplayFragmentPause() {
        Log.e("BLE", "DisplayFragment paused");
    }

    public static class myBluetoothMessage {
        int state;
        int command;
        String mydata;
        String myAddress;
        ArrayList<BluetoothDevice> mDevices;
        BluetoothDevice device;
    }
    //  private ScanCallback leScanCallback;

    private AppBarConfiguration mAppBarConfiguration;
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager layoutManager;
    private ProgressBar simpleProgressBar;
    private MenuItem mySettings;
    private MenuItem myDevice;

    private ArrayList<BluetoothDevice> mDevices = new ArrayList<>();
    private static final int BLUETOOTH_PERMISSION_CODE = 100;
    private BluetoothGatt mBluetoothGatt;
    Gson gson;

    static String BATTERY_SERVICE_UUID = "0000180f-0000-1000-8000-00805f9b34fb";
    static String BATTERY_LEVEL_UUID = "00002a19-0000-1000-8000-00805f9b34fb";
    static String CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID = "00002902-0000-1000-8000-00805f9b34fb";

    // fragment handling
    DataDisplayFragment firstFragment;
    SettingFragment mySettingFragment;
        
    @Override
    protected void onCreate( Bundle savedInstanceState ) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.findViewById(R.id.action_settings);
        setSupportActionBar(toolbar);
        final FloatingActionButton fab = findViewById(R.id.fab);
        simpleProgressBar = (ProgressBar) findViewById(R.id.progressBar); // initiate the progress bar
        simpleProgressBar.setVisibility(View.GONE);
        SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(getString(R.string.connectedDevice), Context.MODE_PRIVATE);
        String mTest = sharedPreferences.getString(getString(R.string.connectedDevice), null);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick( View view ) {
                if((connectedDevice != null) && (myBleState != BLE_CONNECTING))
                {
                    Log.e("BLE","Reconnecting to device");
                    myBleState = BLE_CONNECTING;
                    myBleDispatcher(BLE_CONNECT_CMD, connectedDevice, null);
                    return;
                }
                if (myBleState == BLE_INIT_COMPLETE) {
                    myBleState = BLE_SCANNING;
                    mDevices.clear();
                    mAdapter.notifyDataSetChanged();
                    simpleProgressBar.setVisibility(View.VISIBLE);
                    myBleDispatcher(BLE_SCAN_CMD, null, null);
                    Toast.makeText(MainActivity.this, "Scanning bluetooth devices",
                            Toast.LENGTH_LONG).show();
                } else if (myBleState == BLE_SCANNING) {
                    myBleDispatcher(BLE_SCAN_CANCEL_CMD, null, null);
                    simpleProgressBar.setVisibility(View.GONE);
                    myBleState = BLE_INIT_COMPLETE;
                    Toast.makeText(MainActivity.this, "Scanning cancelled",
                            Toast.LENGTH_LONG).show();
                }else if (myBleState == BLE_CONNECTING) {
                    myBleDispatcher(BLE_CONNECT_CMD, connectedDevice, null);
                }
            }
        });


        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);

                    mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
                .build();

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        recyclerView = (RecyclerView) findViewById(R.id.myRecyclerView);
        recyclerView.setHasFixedSize(true);
        // use a linear layout manager
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        // specify an adapter (see also next example)
        mAdapter = new myAdapter(mDevices, this);
        recyclerView.setAdapter(mAdapter);

        firstFragment = new DataDisplayFragment();
        mySettingFragment = new SettingFragment();


        if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            
        } else {
            
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, BLUETOOTH_PERMISSION_CODE);
            
        }

       
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }
       
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();

        if (mTest != null)
            connectedDevice = bluetoothAdapter.getRemoteDevice(mTest);

        BleUiHandler myUihandler = new BleUiHandler();
        p = new myBluetoothhandler(this, myUihandler, bluetoothAdapter);
        new Thread(p).start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

       
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
          
        myBleDispatcher(BLE_INIT_CMD, null, null);

    }
     
            BluetoothGattCallback gattCallback =
            new BluetoothGattCallback() {
                @Override
                public void onConnectionStateChange( BluetoothGatt gatt, int status,
                                                     int newState ) {

                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        Log.e("BLE", "Connected to GATT server.");
                        Log.e("BLE", "Attempting to start service discovery:");
                        gatt.discoverServices();

                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                       Log.e("BLE", "Disconnected from GATT server.");

                    }
                }

                ;

                @Override
                public void onServicesDiscovered( BluetoothGatt gatt, int status ) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        // broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                        Log.e("BLE", "onServicesDiscovered Success received: " + status);
                        mygattservices = gatt.getServices();
                        BluetoothGattService batteryService = gatt.getService(UUID.fromString(BATTERY_SERVICE_UUID));
                        if (batteryService == null) {
                            Log.e("BLE", "Battery service not found!");

                        } else
                            Log.e("BLE", "Battery service found!");

                        BluetoothGattCharacteristic batteryLevel = batteryService.getCharacteristic(UUID.fromString(BATTERY_LEVEL_UUID));
                        if (batteryLevel == null) {
                            Log.e("BLE", "Battery characteristic not found!");
                            return;
                        } else {
                            Log.e("BLE", "Battery characteristic found!");
                            Log.e("BLE", String.valueOf(gatt.readCharacteristic(batteryLevel)));
                            //  setCharacteristicNotification(gatt,batteryLevel,true);
                        }
                    } else {
                        Log.e("BLE", "onServicesDiscovered received: " + status);
                    }
                }

                @Override
               
                public void onCharacteristicRead( BluetoothGatt gatt,
                                                  BluetoothGattCharacteristic characteristic,
                                                  int status ) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        Log.e("BLE", "onCharacteristicRead: " + status);
                        Log.e("BLE", "onCharacteristicRead: " + status);
                        
                    }
                }

                @Override
                public void onDescriptorWrite( BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status ) {

                    Log.e("BLE", "Write Descriptor Status = " + status);
                }

                @Override
                    public void onCharacteristicChanged( BluetoothGatt gatt,
                                                     BluetoothGattCharacteristic characteristic ) {
                    Log.e("BLE", "FINALLY SOMETHING CHANGED ");
                    int flag = characteristic.getProperties();
                    int format = -1;
                    if ((flag & 0x01) != 0) {
                        format = BluetoothGattCharacteristic.FORMAT_UINT16;
                        Log.e("BLE", " format UINT16.");
                    } else {
                        format = BluetoothGattCharacteristic.FORMAT_UINT8;
                        Log.e("BLE", " format UINT8.");
                    }
                    final int heartRate = characteristic.getIntValue(format, 0);
                    Log.e("BLE", String.format("FINALLY SOMETHING CHANGED %x", heartRate));
                    }    
            };


    @Override
    public void onClick( BluetoothDevice mDevice ) {
        Log.e("BLE", "OOPS FINALLY");
        if (firstFragment.isAdded())
            return;
        getSupportFragmentManager().beginTransaction()
                .add(R.id.listcontainer, firstFragment).addToBackStack("devicedetails").commit();
        connectedDevice = mDevice;
        myBleState = BLE_CONNECTING;
        myBleDispatcher(BLE_CONNECT_CMD, mDevice, null);
    }

    public boolean setCharacteristicNotification( BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic characteristic, boolean enable ) {
        boolean setstate;
        byte[] value = new byte[0];
        bluetoothGatt.setCharacteristicNotification(characteristic, enable);
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID));
        int properties = characteristic.getProperties();
        if ((properties & 0x00000010) > 0) {
            value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
        } else if ((properties & 0x00000020) > 0) {
            value = BluetoothGattDescriptor.ENABLE_INDICATION_VALUE;
        }
        descriptor.setValue(value);
        setstate = bluetoothGatt.writeDescriptor(descriptor); //descriptor write operation successfully started?
        Log.e("BLE", "SET STATE" + setstate);
        return setstate;
    }

    @Override
    public boolean onOptionsItemSelected( MenuItem item ) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                Log.e("SETTING", "SELECTED");
                if (mySettingFragment.isAdded())
                    return true;
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.listcontainer, mySettingFragment).addToBackStack("settings").commit();
                SettingFragmentDisplayed = true;
                return true;
            case R.id.action_delete:
                SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(getString(R.string.connectedDevice), Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sharedPref.edit();
                editor.clear();
                editor.commit();
                getSupportFragmentManager().popBackStack();
                if((myBleState == BLE_CONNECTING) || (myBleState == BLE_CONNECTED) ) {
                    myBleDispatcher(BLE_DISCONNECT_CMD, connectedDevice, null);
                    myBleState = BLE_DISCONNECTING;
                }
                  return true;

            default:
                return super.onOptionsItemSelected(item);

        }
    }

    public class BleUiHandler extends Handler {
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void handleMessage( Message msg ) {
            //  Log.e("BLE","Received UI Event");
            myBluetoothMessage myUiMessage = (myBluetoothMessage) msg.obj;
            switch (myUiMessage.command) {
                case BLE_INIT_IND:
                    myBleState = BLE_INIT_COMPLETE;
                    if (connectedDevice != null) {
                        getSupportFragmentManager().beginTransaction()
                                .add(R.id.listcontainer, firstFragment).addToBackStack("devicedetails").commit();
                        myBleState = BLE_CONNECTING;
                        //      mySettings.setEnabled(true);
                        simpleProgressBar.setVisibility(View.VISIBLE);
                        myBleDispatcher(BLE_CONNECT_CMD, connectedDevice, null);
                    }
                    break;
                case BLE_SCAN_DEV_IND:
                    mDevices.add(myUiMessage.device);
                    mAdapter.notifyDataSetChanged();
                    break;
                case BLE_SCAN_COMPLETE_IND:
                    Log.e("BLE", "BLE_SCAN_COMPLETE_IND");
                    simpleProgressBar.setVisibility(View.GONE);
                    myBleState = BLE_INIT_COMPLETE;
                    break;
                case BLE_CONNECTION_SUCCESS:
                    Log.e("BLE", "BLE connection success storing device");
                    if(myBleState == BLE_DISCONNECTING)
                    {
                        myBleDispatcher(BLE_DISCONNECT_CMD, connectedDevice, null);
                        return;
                    }
                    myBleState= BLE_CONNECTED;
                    if(connectedDevice != null) {
                        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(getString(R.string.connectedDevice), Context.MODE_PRIVATE);
                        SharedPreferences.Editor editor = sharedPref.edit();
                        editor.putString(getString(R.string.connectedDevice), connectedDevice.getAddress());
                        editor.apply();
                    }
                    //    mySettings.setEnabled(true);
                    //   firstFragment.onDataChage("32,32.33");

                    break;
                case BLE_DISCONNECTED:
                    // Toast.makeText(getApplicationContext(),"DISCONNECTED",Toast.LENGTH_LONG);
                    if(connectedDevice != null)
                    {
                        return;
                    }
                    myBleState= BLE_INIT_COMPLETE;
                    getSupportFragmentManager().popBackStack();
                    //firstFragment.ongattDisconnected();
                    connectedDevice = null;

                    break;
                case BLE_NOTIFICATION_DEVICE_INFORMATION:
                    mydeviceSettings = myUiMessage.mydata;
                    mySettingFragment.fragmentInitData(mydeviceSettings);
                    break;
                case BLE_NOTIFICATION_DISTANCE_DATA:
                    try {
                        firstFragment.onDataChage(myUiMessage.mydata);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }

    }


     
**DataDisplayFragment.java**

package com.renesas.socialband;

import android.os.Build;
import android.os.Bundle;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.material.snackbar.Snackbar;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link DataDisplayFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class DataDisplayFragment extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private View myFragView;
    ProgressBar PB;
    onDisplayFragmentPause myFragmentcallBack;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    public String FILE_NAME = "socialbandlogs.txt";

    public DataDisplayFragment() {
        // Required empty public constructor
    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    public void  FileLoggermessage(View v, String aLogMessage) throws IOException {
        Log.e("FileLogger","Inside File Logger");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        Log.e("FileLogger", String.valueOf(now));
        String Final_Message= now + " : " + aLogMessage + "\n";
        FileOutputStream fos = null;
        try {
            // Context context = null;
            fos = v.getContext().openFileOutput(FILE_NAME, Context.MODE_APPEND);
            fos.write(Final_Message.getBytes() );
            //Toast.makeText(this, "Saved to " + getFilesDir() + "/" + FILE_NAME, Toast.LENGTH_LONG).show();
            //  Toast.makeText(this, now + ": Saved to \" + getFilesDir() + \"/\" + FILE_NAME",Toast.LENGTH_LONG).show();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    

标签: javaandroidandroid-studioandroid-fragmentsandroid-bluetooth

解决方案


推荐阅读