Haben Sie eine Idee, was falsch ist?
BR,
Marcin
Hier ist mein Code. (unten gibt es ein Update)
Code: Select all
package com.example.edgetest1;
import static androidx.core.location.LocationManagerCompat.isLocationEnabled;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends Activity {
private BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScanner;
private ListView bleList;
private TextView pulse;
private BluetoothGatt bluetoothGatt;
private List bleDevices = new ArrayList();
private ArrayAdapter bleListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pulse = findViewById(R.id.pulse);
bleList = findViewById(R.id.bleList);
Button findBleButton = findViewById(R.id.findBle);
Button connectForceButton = findViewById(R.id.forceConnect);
Button connectButton = findViewById(R.id.connect);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bleListAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
bleList.setAdapter(bleListAdapter);
findBleButton.setOnClickListener(v -> startBleScan());
connectForceButton.setOnClickListener( v -> {
}
);
connectButton.setOnClickListener(v -> {
int position = bleList.getCheckedItemPosition();
if (position != ListView.INVALID_POSITION) {
BluetoothDevice device = bleDevices.get(position);
connectToDevice(device);
} else {
msg("Please select a device to connect");
}
});
}
private void startBleScan() {
if (bluetoothLeScanner != null) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
msg("No SCAN permission 1");
return;
}
bluetoothLeScanner.stopScan(scanCallback);
bleDevices.clear();
bleListAdapter.clear();
if (!bluetoothAdapter.isEnabled()) {
msg("Please enable Bluetooth");
return;
}
// Check if location services are enabled
if (!isLocationEnabled()) {
msg("Please enable location services");
return;
}
bluetoothLeScanner.startScan(scanCallback); // Start a new scan
msg("Starting scan...");
}
}
private boolean isLocationEnabled() {
/* Check if location services are enabled */
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
};
private final ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
msg("Have the results...");
BluetoothDevice device = result.getDevice();
if (!bleDevices.contains(device)) {
bleDevices.add(device);
if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
msg("No CONNECT permission 1");
return;
}
bleListAdapter.add(device.getName() + " (" + device.getAddress() + ")");
bleListAdapter.notifyDataSetChanged();
}
}
@Override
public void onBatchScanResults(List results) {
msg("Have the bath results...");
for (ScanResult result : results) {
onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result);
}
}
@Override
public void onScanFailed(int errorCode) {
msg("BLE scan failed with error code: " + errorCode);
}
};
private void connectToDevice(BluetoothDevice device) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
msg("No CONNECT permission 2");
return;
}
msg("Trying to connect");
bluetoothGatt = device.connectGatt(this, false, gattCallback);
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
msg("Connection state changed");
// Handle connection state changes
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
BluetoothGattService service = gatt.getService(UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb"));
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"));
if (ActivityCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
msg("No CONNECT permission 3");
return;
}
gatt.setCharacteristicNotification(characteristic, true);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
int value = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
runOnUiThread(() -> pulse.setText("Pulse: " + value));
}
};
public void msg(String message){
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
Code: Select all
Ich habe es irgendwie geschafft, noch einen Schritt weiter zu gehen. Jetzt scannt es die Geräte und versucht, eine Verbindung herzustellen, jedoch ohne Erfolg. Hier ist der Code (unterteilt in drei Klassen).
Code: Select all
package com.example.edgetest1;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends Activity {
public static final int REQUEST_LOCATION_PERMISSION = 100;
public BluetoothAdapter bluetoothAdapter;
private BluetoothLeScanner bluetoothLeScanner;
private ListView bleList;
public TextView pulse;
BluetoothGatt bluetoothGatt;
List bleDevices = new ArrayList();
ArrayAdapter bleListAdapter;
private long scanStart;
private Handler handler = new Handler();
private static final long SCAN_PERIOD = 10000; // 10 seconds
public void msg(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pulse = findViewById(R.id.pulse);
bleList = findViewById(R.id.bleList);
Button findBleButton = findViewById(R.id.findBle);
Button connectButton = findViewById(R.id.connect);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
bleListAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1);
bleList.setAdapter(bleListAdapter);
bleList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
msg("Selected: " + (position + 1) + " . Connecting");
BluetoothDevice device = bleDevices.get(position);
connectToDevice(device);
}
});
findBleButton.setOnClickListener(v -> startBleScan());
connectButton.setOnClickListener(v -> {
int position = bleList.getCheckedItemPosition();
if (position != ListView.INVALID_POSITION) {
BluetoothDevice device = bleDevices.get(position);
connectToDevice(device);
} else {
msg("Please select a device to connect");
}
});
}
public void bleDevicesAdd(BluetoothDevice device){
bleDevices.add(device);
}
public boolean bleDevicesContains(BluetoothDevice device){
return bleDevices.contains(device);
}
;
public void bleListAdapterAdd(String deviceInfo){
bleListAdapter.add(deviceInfo);
}
private void startBleScan() {
if (bluetoothLeScanner != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
return;
}
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
msg("No SCAN permission");
return;
}
bluetoothLeScanner.stopScan(scanCallback);
bleDevices.clear();
bleListAdapter.clear();
//backupBleDevList.clear();
if (!bluetoothAdapter.isEnabled()) {
msg("Please enable Bluetooth");
return;
}
if (!isLocationEnabled()) {
msg("Please enable location services");
return;
}
scanStart = System.currentTimeMillis() / 1000;
bluetoothLeScanner.startScan(scanCallback);
msg("Starting scan...");
handler.postDelayed(() -> {
bluetoothLeScanner.stopScan(scanCallback);
msg("End of scan");
}, SCAN_PERIOD);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startBleScan();
} else {
msg("Location permission is required for BLE scanning");
}
}
}
private boolean isLocationEnabled() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
private final ScanCallback scanCallback = new MyScanCallback(this, MainActivity.this);
private final BluetoothGattCallback gattCallback = new MyGattCallback(this, MainActivity.this);
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save Bluetooth devices
ArrayList deviceAddresses = new ArrayList();
for (BluetoothDevice device : bleDevices) {
deviceAddresses.add(device.getAddress());
}
outState.putStringArrayList("bleDevices", deviceAddresses);
msg("Backup: "+bleDevices.size());
// Save adapter data
ArrayList adapterData = new ArrayList();
for (int i = 0; i < bleListAdapter.getCount(); i++) {
adapterData.add(bleListAdapter.getItem(i));
}
outState.putStringArrayList("bleListAdapter", adapterData);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null) {
// Restore Bluetooth devices
ArrayList deviceAddresses = savedInstanceState.getStringArrayList("bleDevices");
if (deviceAddresses != null) {
bleDevices = new ArrayList();
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
for (String address : deviceAddresses) {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
bleDevices.add(device);
}
}
// Restore adapter data
ArrayList adapterData = savedInstanceState.getStringArrayList("bleListAdapter");
if (adapterData != null) {
bleListAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, adapterData);
}
msg("Restored "+ adapterData.size());
}
}
private void connectToDevice(BluetoothDevice device) {
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
msg("Bluetooth is not available or not enabled");
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, REQUEST_LOCATION_PERMISSION);
msg("No CONNECT permission 1");
return;
}
} else {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
msg("No LOCATION permission");
return;
}
}
msg("Trying to connect to device: " + device.getName());
bluetoothGatt = device.connectGatt(this, false, gattCallback);
if (bluetoothGatt == null) {
msg("Failed to connect to the device");
}
}
// @Override
// public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
// msg("Connection state changed: " + status + " -> " + newState);
// if (newState == BluetoothGatt.STATE_CONNECTED) {
// msg("Successfully connected to GATT server.");
// if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// return;
// }
// gatt.discoverServices();
// } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
// msg("Disconnected from GATT server.");
// } else if (status != BluetoothGatt.GATT_SUCCESS) {
// msg("Connection failed with status: " + status);
// }
// }
//
// @Override
// public void onServicesDiscovered(BluetoothGatt gatt, int status) {
// if (status == BluetoothGatt.GATT_SUCCESS) {
// msg("Services discovered successfully.");
// BluetoothGattService service = gatt.getService(UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb"));
// if (service != null) {
// BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"));
// if (characteristic != null) {
// if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// return;
// }
// gatt.setCharacteristicNotification(characteristic, true);
// }
// } else {
// msg("Heart Rate service not found.");
// }
// } else {
// msg("Service discovery failed with status: " + status);
// }
// }
//
// @Override
// public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// if (characteristic.getUuid().equals(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"))) {
// int heartRate = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
// runOnUiThread(() -> pulse.setText("Pulse: " + heartRate));
// }
// }
//
// @Override
// public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// if (status == BluetoothGatt.GATT_SUCCESS) {
//
// }
// }
};
Code: Select all
package com.example.edgetest1;
import android.Manifest;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.util.UUID;
public class MyGattCallback extends BluetoothGattCallback {
private final Context context;
private final MainActivity activity;
public MyGattCallback(Context context, MainActivity activity) {
this.activity = activity;
this.context = context;
}
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
msg("Connection state changed: " + status + " -> " + newState);
if (newState == BluetoothGatt.STATE_CONNECTED) {
msg("Successfully connected to GATT server.");
if (ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
msg("No CONNECT permission 3");
return;
}
gatt.discoverServices();
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
msg("Disconnected from GATT server.");
} else if (status != BluetoothGatt.GATT_SUCCESS) {
msg("Connection failed with status: " + status);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
msg("Services discovered successfully.");
BluetoothGattService service = gatt.getService(UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb"));
if (service != null) {
BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"));
if (characteristic != null) {
msg("Char is null");
if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
msg("No CONNECT permission 2");
return;
}
gatt.setCharacteristicNotification(characteristic, true);
}
} else {
msg("Heart Rate service not found.");
}
} else {
msg("Service discovery failed with status: " + status);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
if (characteristic.getUuid().equals(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"))) {
int heartRate = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0);
activity.runOnUiThread(() -> activity.pulse.setText("Pulse: " + heartRate));
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
msg("GATT_SUCCESS");
}
}
public void msg(String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
Code: Select all
package com.example.edgetest1;
import static com.example.edgetest1.MainActivity.REQUEST_LOCATION_PERMISSION;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.util.List;
import android.content.Context;
public class MyScanCallback extends ScanCallback {
private final Context context;
private final MainActivity activity;
public MyScanCallback(Context context, MainActivity activity) {
this.activity = activity;
this.context = context;
}
@Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
if (!activity.bleDevicesContains(device)) {
msg("Have new results");
//bleDevices.add(device);
activity.bleDevices.add(device);
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
String deviceInfo = device.getName() + " (" + device.getAddress() + ")";
//backupBleDevList.add(deviceInfo); // Add device info to backup list
//bleListAdapter.add(deviceInfo);
activity.bleListAdapter.add(deviceInfo);
//bleListAdapter.notifyDataSetChanged();
activity.bleListAdapter.notifyDataSetChanged();
}
}
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
msg("Connection state changed: " + status + " -> " + newState);
if (newState == BluetoothGatt.STATE_CONNECTED) {
msg("Successfully connected to GATT server.");
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
gatt.discoverServices(); // Discover services on the connected device
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
msg("Disconnected from GATT server.");
} else if (status != BluetoothGatt.GATT_SUCCESS) {
msg("Connection failed with status: " + status);
}
}
};
@Override
public void onBatchScanResults(List results) {
msg("Have the batch results...");
for (ScanResult result : results) {
onScanResult(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, result);
}
}
@Override
public void onScanFailed(int errorCode) {
msg("BLE scan failed with error code: " + errorCode);
}
private void connectToDevice(BluetoothDevice device) {
if (activity.bluetoothAdapter == null || activity.bluetoothAdapter.isEnabled()) {
msg("Bluetooth is not available or not enabled");
return;
}
// Check necessary permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{android.Manifest.permission.BLUETOOTH_CONNECT}, REQUEST_LOCATION_PERMISSION);
msg("No CONNECT permission");
return;
}
} else {
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_PERMISSION);
msg("No LOCATION permission");
return;
}
}
msg("Trying to connect to device: " + device.getName());
activity.bluetoothGatt = device.connectGatt(context, false, gattCallback);
if (activity.bluetoothGatt == null) {
msg("Failed to connect to the device");
//retryConnection(device);
}
}
public void msg(String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}