gpt4 book ai didi

java - BLE 发送/接收;尝试从空对象引用上的字段 'android.bluetooth.BluetoothGattCallback BluetoothLeService.mGattCallback' 读取

转载 作者:太空宇宙 更新时间:2023-11-04 10:21:57 26 4
gpt4 key购买 nike

我对安卓不太了解。我正在尝试通过 BLE 发送数据。我的代码如下->。我从网上得到的 https://developer.android.com/guide/topics/connectivity/bluetooth-le#read

如何正确调用该方法-> mBluetoothService.mBluetoothGatt = device.connectGatt(cntxt, false, mBluetoothService.mGattCallback);这一行出现crash。

    public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.class.getSimpleName();

public BluetoothManager mBluetoothManager;
public BluetoothAdapter mBluetoothAdapter;
public String mBluetoothDeviceAddress;
public BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private final IBinder mBinder = new LocalBinder();

private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;

public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";

public final static UUID UUID_HEART_RATE_MEASUREMENT =
UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);

// Various callback methods defined by the BLE API.
public final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());

} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}

@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
for (BluetoothGattService gattService : gatt.getServices()) {
Log.i(TAG, "onServicesDiscovered: ---------------------");
Log.i(TAG, "onServicesDiscovered: service=" + gattService.getUuid());
for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());

if (characteristic.getUuid().toString().equals("0000ffe9-0000-1000-8000-00805f9b34fb")) {

Log.w(TAG, "onServicesDiscovered: found LED");

String originalString = "560D0F0600F0AA";

byte[] b = hexStringToByteArray(originalString);

characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
mBluetoothGatt.writeCharacteristic(characteristic);

Log.i(TAG, "onServicesDiscovered: , write bytes?! " + byteToHexStr(b));
}
}
}

broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);

} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}

@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
byte[] data = characteristic.getValue();
System.out.println("reading");
System.out.println(new String(data));
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
//...
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}

public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i + 1), 16));
}
return data;
}

public static String byteToHexStr(byte[] bytes) {
StringBuilder builder = new StringBuilder();
for (byte b: bytes) {
builder.append(String.format("%02x", b));
}
return builder.toString();
}


private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);

// This is special handling for the Heart Rate Measurement profile. Data
// parsing is carried out as per profile specifications.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d(TAG, "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d(TAG, "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
// For all other profiles, writes the data formatted in HEX.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
stringBuilder.toString());
}
}
sendBroadcast(intent);
}
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;/*return null;*/
}
//...
}

我从外部调用此类方法,如下所示->

    public class DeviceScanActivity extends AppCompatActivity/*ListActivity*/ {
//private LeDeviceListAdapter mLeDeviceListAdapter;
public BluetoothAdapter mBluetoothAdapter;
public /*final*/ BluetoothManager mBluetoothManager;
/*=(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);;*/
private BluetoothLeService mBluetoothService;//= new BluetoothLeService();
public Context cntxt;
ArrayList<ViewHolder> arrayOfUsers2 = new ArrayList<ViewHolder>();
private boolean mScanning;
private boolean mBounded;
private Handler mHandler;
ArrayList<String> mylist = new ArrayList<String>();
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 50000;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 456;

UsersAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//getActionBar().setTitle("abc");

mHandler = new Handler();
//this.requestPermissions(rqPerm,req);

requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
/*final BluetoothManager*/ mBluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (mBluetoothAdapter == null ) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
if( !mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(getIntent(), 1);
}
// Construct the data source

ArrayList<ViewHolder> arrayOfUsers = new ArrayList<ViewHolder>();

// Create the adapter to convert the array to views

adapter = new UsersAdapter(this, arrayOfUsers);
cntxt=this.getApplicationContext();
Intent i = new Intent(this, BluetoothLeService.class);
bindService(this.getIntent(), mConnection, BIND_AUTO_CREATE);; //if checked, start service
ListView listView = (ListView) findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
ViewHolder entry= (ViewHolder) parent.getAdapter().getItem(position);
String address = entry.deviceAddress;
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Toast.makeText(cntxt, address, Toast.LENGTH_SHORT).show();
//mBluetoothService.mBluetoothDeviceAddress=address;
//mBluetoothService.mBluetoothManager=mBluetoothManager;
mBluetoothService.mBluetoothAdapter = mBluetoothAdapter;
mBluetoothService.mBluetoothGatt = device.connectGatt(cntxt, false, mBluetoothService.mGattCallback);

//Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
}});
ViewHolder newUser2 = new ViewHolder("adtv2","vvg2");
adapter.add(newUser2);

}
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
//Toast.makeText(Client.this, "Service is disconnected", 1000).show();
mBounded = false;
mBluetoothService = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//Toast.makeText(Client.this, "Service is connected", 1000).show();
mBounded = true;
BluetoothLeService.LocalBinder mLocalBinder = (BluetoothLeService.LocalBinder)service;
mBluetoothService = mLocalBinder.getService();
}
};


private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
ViewHolder newUser2 = new ViewHolder("adtv2","vvg2");
adapter.add(newUser2);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);



Iterator<ViewHolder> it=arrayOfUsers2.iterator();
while(it.hasNext()) {
ViewHolder currentX = it.next();
adapter.add(currentX);
}
// Do something with the value

}
}, SCAN_PERIOD);

mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
//invalidateOptionsMenu();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, yay! Start the Bluetooth device scan.
scanLeDevice(true);
} else {
// Alert the user that this application requires the location permission to perform the scan.
}
}
}
}


// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {

@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//mLeDeviceListAdapter.addDevice(device);
//mLeDeviceListAdapter.notifyDataSetChanged();

//ViewHolder newUser = new ViewHolder("Nathan", "San Diego");
String deviceName=null, deviceAddress=null;
if(device!=null)
deviceName= device.getName();
if (!(deviceName != null && deviceName.length() > 0))
deviceName = "unknown device";
if(device!=null)
deviceAddress= device.getAddress();
ViewHolder newUser = new ViewHolder(deviceName, deviceAddress);
ViewHolder newUser2 = new ViewHolder("adtv","vvg");
if(!arrayOfUsers2.contains(newUser))
arrayOfUsers2.add(newUser);
//adapter.add(newUser);
}
});
}
};
public class UsersAdapter extends ArrayAdapter<ViewHolder> {


public UsersAdapter(Context context, ArrayList<ViewHolder> users) {

super(context, 0, users);

}



@Override

public View getView(int position, View convertView, ViewGroup parent) {

// Get the data item for this position

ViewHolder user = getItem(position);


// Check if an existing view is being reused, otherwise inflate the view

if (convertView == null) {

convertView = LayoutInflater.from(getContext()).inflate(R.layout.bt_details, parent, false);

}

// Lookup view for data population

TextView tvName = (TextView) convertView.findViewById(R.id.DeviceName);

TextView tvHome = (TextView) convertView.findViewById(R.id.DeviceAddress);

// Populate the data into the template view using the data object

tvName.setText(user.deviceName);

tvHome.setText(user.deviceAddress);

// Return the completed view to render on screen

return convertView;

}

}
public class ViewHolder {
String deviceName;
String deviceAddress;

public ViewHolder(String device, String __address) {
this.deviceName =device;
this.deviceAddress= __address;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ViewHolder a = (ViewHolder) o;
return Objects.equals(deviceAddress, a.deviceAddress);
}
}



}

我在列表中获取扫描设备结果。单击该列表中的任何元素时,我会调用 AdapterView.OnItemClickListener()。然后如何向设备发送消息。如何读取这些日志消息。如何知道代码是否已发送消息。如何在其他设备上接收消息。我已经完成了BLE扫描,工作正常。但这里没有添加代码。

日志猫报告如下

FATAL EXCEPTION: main
Process: com.example.root.securityalert, PID: 27945
java.lang.NullPointerException: Attempt to read from field 'android.bluetooth.BluetoothGattCallback com.example.root.securityalert.BluetoothLeService.mGattCallback' on a null object reference
at com.example.root.securityalert.DeviceScanActivity$1.onItemClick(DeviceScanActivity.java:115)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1156)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3147)
at android.widget.AbsListView$3.run(AbsListView.java:4062)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6165)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)

我也尝试过代码

    public class BluetoothSendRecv extends BluetoothGattCallback{

public BluetoothManager mBluetoothManager;
public BluetoothAdapter mBluetoothAdapter;
public String mBluetoothDeviceAddress;
public BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
// private final IBinder mBinder = new BluetoothLeService.LocalBinder();
public Context cntxt;
.......
UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);

// Various callback methods defined by the BLE API.
public final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());

} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}

@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
//broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
for (BluetoothGattService gattService : gatt.getServices()) {
Log.i(TAG, "onServicesDiscovered: ---------------------");
Log.i(TAG, "onServicesDiscovered: service=" + gattService.getUuid());
for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());

if (characteristic.getUuid().toString().equals("0000fee9-0000-1000-8000-00805f9b34fb"/*0000ffe9-0000-1000-8000-00805f9b34fb"*/)) {

Log.w(TAG, "onServicesDiscovered: found LED");

String originalString = "560D0F0600F0AA";

byte[] b = hexStringToByteArray(originalString);

characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
mBluetoothGatt.writeCharacteristic(characteristic);
//Toast.makeText(this., "R.string.error_bluetooth_not_supported", Toast.LENGTH_SHORT).show();
//finish()
System.out.println("Writing Mithun");
Toast.makeText(cntxt, originalString, Toast.LENGTH_SHORT).show();
Log.i(TAG, "onServicesDiscovered: , write bytes?! " + byteToHexStr(b));
}
}
}

broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);

} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}

@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
byte[] data = characteristic.getValue();
System.out.println("reading");
System.out.println(new String(data));
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
//...
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
//sendBroadcast(intent);
}

.....
}

Then logcat report is as follows aaaa

D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=CC:1E:39:39:62:1C
I/ContentValues: Connected to GATT server.
D/BluetoothGatt: discoverServices() - device: CC:1E:39:39:62:1C
I/ContentValues: Attempting to start service discovery:true
D/BluetoothGatt: onSearchComplete() = Device=CC:1E:39:39:62:1C Status=0
I/ContentValues: onServicesDiscovered: ---------------------
I/ContentValues: onServicesDiscovered: service=00001800-0000-1000-8000-00805f9b34fb
I/ContentValues: onServicesDiscovered: characteristic=00002a00-0000-1000-8000-00805f9b34fb


I think this condition is not fullfilled
if(characteristic.getUuid().toString().equals("0000fee9-0000-1000-8000-00805f9b34fb"/*0000ffe9-0000-1000-8000-00805f9b34fb"*/))

最佳答案

我认为你必须在尝试连接之前添加“Scan”方法。这是ble架构的规则。像这样:

 private void startScanning(final boolean enable, BluetoothAdapter mBluetoothAdapter) {
bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
List<ScanFilter> scanFilters = new ArrayList<>();
final ScanSettings settings = new ScanSettings.Builder().build();
ScanFilter scanFilter = new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(UUID_SERVICE)).build();
scanFilters.add(scanFilter);
bluetoothLeScanner.startScan(scanFilters, settings, scanCallback);

}

如果 Ble 设备已建立:

ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
bluetoothDevice = result.getDevice();
Log.d(TAG, "onScanResult: bluetoothDevice.getAddress());
mScanning = false;
String adress = bluetoothDevice.getAddress();
bluetoothLeScanner.stopScan(scanCallback);
connect(bluetoothDevice);

}

关于java - BLE 发送/接收;尝试从空对象引用上的字段 'android.bluetooth.BluetoothGattCallback BluetoothLeService.mGattCallback' 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51046091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com