我对android和ble还不熟悉。我正在开发一个android应用程序。在应用程序中,我们正在检查电池百分比和两个设备之间的距离。我们需要捕获这些细节并保存到文件中。
目前我们可以做的任务,但只有几秒钟。几秒钟后,它失败并出现以下错误。也请找到下面的代码供您参考。
android版本:在三星a31上进行10次测试
错误:error:bta_gattc_utils.cc(434)]bta\u gattc\u mark\u bg\u conn找不到bd\u 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();
}
}
}
}
暂无答案!
目前还没有任何答案,快来回答吧!