I'm trying to program an App to establish a basic communication over BLE between an Android Phone and an RFDuino. The RFDuino is just advertising and can be detected by the "BLE Scanner" App.
Below is the draft code for the activity, that is supposed to detect BLE devices.
The problem is, that no devices are detected. The Debug Log shows, that the method "onLeScan" is not even called once...
I'm running out of Ideas and would be thankful for every hint :-)
package de.tuhh.et5.serialcommunicator;
import (...)
public class BLEActivity extends AppCompatActivity {
private static final long SCAN_PERIOD = 10000;
private int REQUEST_ENABLE_BT = 1;
public final static String TAG = "BLE_Activity"; // Tag for the LOG
private BluetoothAdapter ble_adapter;
private boolean scanning;
private Handler ble_handler;
private BLE_DeviceListAdapter BLE_DeviceListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
d("on Create");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ble);
TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
tabHost.setup();
TabHost.TabSpec t1=tabHost.newTabSpec("Tab1");
t1.setContent(R.id.tab1_layout);
t1.setIndicator("Devices");
tabHost.addTab(t1);
BLE_DeviceListAdapter = new BLE_DeviceListAdapter();
ListView ble_list = (ListView)findViewById(R.id.BLE_DeviceListView);
ble_list.setAdapter(BLE_DeviceListAdapter);
ble_handler = new Handler();
// get a bluetooth adapter from the bluetooth manager
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
ble_adapter = bluetoothManager.getAdapter();
// Check if BLE is supported by the Android device
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
// Enable bluetooth
if (ble_adapter == null || !ble_adapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
// menu stuff
@Override
public boolean onCreateOptionsMenu(Menu menu) {
d("menu inflates");
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ble_menu, menu);
if (scanning) {
menu.findItem(R.id.scanning_start).setVisible(false);
} else {
menu.findItem(R.id.scanning_start).setVisible(true);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.scanning_start:
d("scan pressed");
BLE_DeviceListAdapter.clear();
ble_scan(true);
break;
}
return true;
}
private void ble_scan(final boolean en){
d("Scan start");
// stopLeScan and startLeScan are deprecated since Android 5.0, but still work.
// to offer a compatibility down to Android 4.3 the old methods are used
if (en){
ble_handler.postDelayed(new Runnable() {
@Override
public void run() {
d("scan timer finished");
scanning = false;
ble_adapter.stopLeScan(ble_callback);
invalidateOptionsMenu();
}
},SCAN_PERIOD);
scanning = true;
ble_adapter.startLeScan(ble_callback);
}else{
scanning = false;
ble_adapter.stopLeScan(ble_callback);
}
invalidateOptionsMenu();
}
private BluetoothAdapter.LeScanCallback ble_callback = new BluetoothAdapter.LeScanCallback(){
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord){
d("onLeScan");
runOnUiThread(new Runnable(){
@Override
public void run(){
BLE_DeviceListAdapter.addDevice(device);
BLE_DeviceListAdapter.notifyDataSetChanged();
}
});
}
};
// This class lists the elements in an ble device entry as defined in "ble_device_entry.cml"
// It is needed in the BLE_DeviceListAdapter class
private class ViewHolder {
TextView name;
TextView device_id;
TextView device_adress;
}
// #####################################################
// private Class BLE_DeviceListAdapter
//
// Adapter to handle found BLE Devices
// #####################################################
private class BLE_DeviceListAdapter extends BaseAdapter{
private ArrayList<BluetoothDevice> ble_devices; // holds found devices
private LayoutInflater ble_inflater; // layout inflater
public BLE_DeviceListAdapter(){
super();
// Init
ble_devices = new ArrayList<>();
ble_inflater = BLEActivity.this.getLayoutInflater();
}
// method to add a device
public void addDevice(BluetoothDevice ble_device){
// device is added, if it is not already in the list
if (!ble_devices.contains(ble_device)){
ble_devices.add(ble_device);
}
}
// Mandatory, returns device at position ...
@Override
public BluetoothDevice getItem(int position){
return ble_devices.get(position);
}
// clear list..
public void clear(){
ble_devices.clear();
}
// Mandatory: Not needed, therefore just a dummy
@Override
public long getItemId(int i) {
return i;
}
// Mandatory: returns size of list
@Override
public int getCount() {
return ble_devices.size();
}
// Mandatory: creates and returns view with a device entry
@Override
public View getView(int i, View view, ViewGroup viewGroup ){
ViewHolder viewHolder; // create view holder
// if the view does not already exist:
if (view == null){
view = ble_inflater.inflate(R.layout.ble_device_entry, null);// inflate view
viewHolder = new ViewHolder(); // create a ViewHolder
// Connenct the ViewHolder elements to layout elements
viewHolder.name = (TextView)findViewById(R.id.BLE_sName);
viewHolder.device_adress = (TextView)findViewById(R.id.BLE_sAdress);
viewHolder.device_id = (TextView)findViewById(R.id.BLE_sID);
view.setTag(viewHolder); // Add the ViewHolder as a Tag to the view
}else{
// if the view already exists
viewHolder = (ViewHolder) view.getTag(); // get Tag from view to populate ViewHolder
}
// get BLE Device
Log.d("test", "hier so....");
BluetoothDevice device = ble_devices.get(i);
// get device name
final String deviceName = device.getName();
// assign device name to ViewHolder Object
if (deviceName != null && deviceName.length() > 0){
viewHolder.device_id.setText(deviceName);
}else viewHolder.device_id.setText(R.string.unknown_ble_device);
// assign more values
viewHolder.device_adress.setText(device.getAddress());
viewHolder.name.setText(R.string.unknown_ble_device);
d("before return view");
return view;
}
}
// #####################################################
// End Adapter
// #####################################################
public void d(Object msg) {
Log.d(TAG, ">==< " + msg.toString() + " >==<");
}
public void e(Object msg) {
Log.e(TAG, ">==< " + msg.toString() + " >==<");
}
}