Bluetooth develop:sometimes the bluetoothadapter cannot find the device - android

I'm working at BLE develop and there is my problem.
Sometimes my bluetoothadapter cannot find the device when I used method bluetoothAdapter.startLeScan(callback).
And when adapter cannot found device,I just restart bluetoothadapter(meant:turn off the bluetoothadapter then turn on).
And then the callback will return the device instead null.
I have search much about BLE develop ,but it seems like nobody found this problem.
This is my 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() {
synchronized (m_LeDevices) {
if (m_device_mac != null && m_device_mac.equals(device.getAddress().replace(":", ""))) {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
forwardToMain();
}
}, DELAY_FORWARD_TIME);
}
}
}
});
}
};

Related

Bluetooth restart programmatically in android 7 nougat

I have an application which runs in the background and restarts bluetooth programmatically using
...
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.disable();
mBluetoothAdapter.enable();
...
It works fine in Android Marshmallow but not in Nougat. If anyone has come across a solution to this please let me know.
Using Handler you will easily restart bluetooth.
tvCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialogConConnect.dismiss();
}
});
tvOk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String sec = edtConC.getText().toString();
int second = Integer.parseInt(sec);
int minus = second - 1;
int mSecond = minus*1000;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(bluetoothAdapter.isEnabled()){
bluetoothAdapter.disable();
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(!bluetoothAdapter.isEnabled()){
bluetoothAdapter.enable();
}
}
},1000);
}
},mSecond);
dialogConConnect.dismiss();
}
});
dialogConConnect.show();
}
});

Why discovered device is always named "BLE client"?

I know it is not that important question. I am trying out the Bluetooth low energy to discover devices, query for services, and transmit information. I got success in discovering devices. My question is no matter what the Bluetooth device name is, in the bluetoothDevice.getName() always gives me the name "BLE client". Any idea how to change this name? or how to get the device name? is there anything I am missing?
private ScanCallback scanCallBack = new ScanCallback()
{
#Override
public void onScanResult(int callbackType, ScanResult result)
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
progressDialog.dismiss();
}
});
Log.d(TAG, result.getDevice().getName());
}
#Override
public void onBatchScanResults(List<ScanResult> results)
{
super.onBatchScanResults(results);
}
#Override
public void onScanFailed(int errorCode)
{
super.onScanFailed(errorCode);
}
};

Android Bluetooth Low Energy Not Finding Devices

I am trying to set up a basic Android App that will have Bluetooth LE functionality as per the documentation on the Android Developers site. I successfully can get to the point where I am starting a scan, but it is not finding any of the peripherals I have been using to test. Here is the code as it is:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
#Bind(R.id.button) Button mButton;
#Bind(R.id.listView) ListView mListView;
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning = true;
private Handler mHandler;
private static final long SCAN_PERIOD = 10000;
BluetoothLeScanner mBluetoothAdapterBluetoothLeScanner;
ArrayList<String> bluetoothArray = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mButton.setOnClickListener(this);
Context mContext = getBaseContext();
final BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothAdapterBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1900);
}
}
#Override
public void onClick(View view) {
scanLeDevice(mScanning);
}
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
// mHandler.postDelayed(new Runnable() {
// #Override
// public void run() {
// mScanning = false;
// mBluetoothAdapter.stopLeScan(mLeScanCallback);
// }
// }, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
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() {
Log.d("test" ,device.getName());
}
});
}
};
}
Do you know exactly what the advertising data content is? Maybe it's blocked by the bluetooth stack(bluetooth.default.so) .For example, if the advertising device has not set the "discoverable bit" in AD flag, it will be blocked and you will not receive the report in your callback function.

Android Bluetooth Low Energy Callback(LeScanCallBack) on seperate thread?

I'm starting the Bluetooth Low Energy Scan in the MainActivity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BLEScanner.start(bluetoothManager.getAdapter());
}
}
The (static) BLEScanner class is as follows:
public class BLEScanner {
public static void start(final BluetoothAdapter bluetoothAdapter) {
bluetoothAdapter.startLeScan(mLeScanCallback);
}
private static BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
String name = device.getName();
String address = device.getAddress();
Log.d("BLESCANNER", name+" "+address);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
The Thread.sleep() in BLEScanner causes the UIThread to be unresponsive. How can i run the BLEScanner class in a seperate class?
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
new Thread(new Runnable() {
#Override
public void run() {
//The code here is executed on on new thread everytime
Log.e("LeScanCallback", Thread.currentThread().getName());//Prints Thread-xxxx
}
}).start();
}
};

Discovery System for android and desktop machines

I have a distributed system that consists of androids and desktop machines and they need to pass data (a simple serialized object) among themselves. I am interested in a jini-like discovery system for android using which androids/desktop machines can discover each other and then transfer data to each other. The distributed system is very dynamic, in the sense, devices come and go quite abruptly and frequently.
I tried to work with Cling and I could discover my router but could not discover other devices such as android phones. So I was wondering whether android devices are really UPnP compatible or there might be something wrong with my code.
I am using the code discussed in the Cling user manual.
EDIT: Posting the code below-
public class UpnpBrowserActivity extends ListActivity {
private AndroidUpnpService upnpService;
Registry registry;
private ArrayAdapter<DeviceDisplay> listAdapter;
private BrowseRegistryListener registryListener = new BrowseRegistryListener();
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
upnpService = (AndroidUpnpService) service;
registry = upnpService.getRegistry();
// Refresh the list with all known devices
listAdapter.clear();
for (Device device : registry.getDevices()) {
registryListener.deviceAdded(registry,device);
}
// Getting ready for future device advertisements
registry.addListener(registryListener);
// Search asynchronously for all devices
upnpService.getControlPoint().search();
}
public void onServiceDisconnected(ComponentName className) {
upnpService = null;
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upnp_browser);
listAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1);
setListAdapter(listAdapter);
getApplicationContext().bindService(new Intent(this, AndroidUpnpServiceImpl.class),serviceConnection, Context.BIND_AUTO_CREATE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.upnp_browser, menu);
menu.add(0, 0, 0, "Menu1").setIcon(android.R.drawable.ic_menu_search);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == 0 && upnpService != null) {
upnpService.getRegistry().removeAllRemoteDevices();
upnpService.getControlPoint().search();
}
return false;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (upnpService != null) {
upnpService.getRegistry().removeListener(registryListener);
}
getApplicationContext().unbindService(serviceConnection);
}
class BrowseRegistryListener extends DefaultRegistryListener {
#Override
public void remoteDeviceDiscoveryStarted(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
#Override
public void remoteDeviceDiscoveryFailed(Registry registry, final RemoteDevice device, final Exception ex) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(
UpnpBrowserActivity.this,
"Discovery failed of '" + device.getDisplayString() + "': " +
(ex != null ? ex.toString() : "Couldn't retrieve device/service descriptors"),
Toast.LENGTH_LONG
).show();
}
});
deviceRemoved(device);
}
#Override
public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
deviceAdded(device);
}
#Override
public void remoteDeviceRemoved(Registry registry, RemoteDevice device) {
deviceRemoved(device);
}
#Override
public void localDeviceAdded(Registry registry, LocalDevice device) {
deviceAdded(device);
}
#Override
public void localDeviceRemoved(Registry registry, LocalDevice device) {
deviceRemoved(device);
}
public void deviceAdded(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
DeviceDisplay d = new DeviceDisplay(device);
int position = listAdapter.getPosition(d);
if (position >= 0) {
// Device already in the list, re-set new value at same position
listAdapter.remove(d);
listAdapter.insert(d, position);
} else {
listAdapter.add(d);
}
}
});
}
public void deviceRemoved(final Device device) {
runOnUiThread(new Runnable() {
public void run() {
listAdapter.remove(new DeviceDisplay(device));
}
});
}
}
}
I also read this question on SO but if android devices cannot be discovered with Cling or another similar library, I would prefer to write a small discovery system using TCP/IP sockets.
Kindly guide me if I am missing or misunderstanding something. Any help is appreciated. Thanks in advance.

Categories

Resources