Bluetooth Devices Not Detected with Bluetooth Scan - android

I've made a little android app to scan for Bluetooth devices and send an HTTP request to my server so i can detect if they are on or off. I've tested it with my Desktop PC with a Bluetooth Adapter and it works just fine. It shows pc is on when detected and off when i turn off bluetooth on PC. Now, the devices that I'd need to use this app for are: a Yaber Projector, Bose SoundLink and JBL Headset, but I'm encountering some problems with these.
First, the Projector seems not being able to comunicate with phones, I can connect only Headset or Speakers going into the projector BT settings and scanning for devices, but when I'm scanning to find my phone nothing appears, like the projector were invisivble to phone, resulting in the app detecting it always off. Same thing if i scan for the projector with my phone. How is that possible?
And last the speakers and headsets, it seems that once they are connected to a device (such as the projector) they are no longer visible to the phone, i think this has something to do with battery saving/security. But is there a workaround to keep being able to detect them even when they are connected?
Thanks.
EDIT
This is the code in the service to run the scan, as far as i understood it's using bluetooth classing technology not BLE.
private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private ArrayList<BluetoothDevice> arrayList = new ArrayList<>();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
Intent intent1 = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent1,0);
Notification notification = new NotificationCompat.Builder(this,"BTAPP")
.setContentTitle("Bluetooth Scan")
.setContentText("App is scanning")
.setContentIntent(pendingIntent).build();
startForeground(1,notification);
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
IntentFilter intentFilter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
IntentFilter intentFilter3 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(broadcastReceiver, intentFilter);
registerReceiver(broadcastReceiver, intentFilter2);
registerReceiver(broadcastReceiver, intentFilter3);
bluetoothAdapter.startDiscovery();
return START_STICKY;
}
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery starts
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//clearing any existing list data
flagJBL = false;
flagBose = false;
flagProjector = false;
arrayList.clear();
}
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter
if (!arrayList.contains(device)) {
if (device.getAddress().equals(JBL_HEADSET_ADDRESS))
flagJBL = true;
if (device.getAddress().equals(BOSE_SOUNDLINK_ADDRESS))
flagBose = true;
if (device.getAddress().equals(PROJECTOR_ADDRESS))
flagProjector = true;
arrayList.add(device);
}
}
// When discovery starts
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//clearing any existing list data
//Toast.makeText(getApplicationContext(), "Scan has stopped",Toast.LENGTH_SHORT).show();
if (flagJBL) {
Intent jbloni = new Intent(getApplicationContext(), RequestHandler.class);
jbloni.putExtra("URL",JBL_ON_URL);
startService(jbloni);
}
//showNotification("JBL Result", "JBL is On");
else {
Intent jbloffi = new Intent(getApplicationContext(), RequestHandler.class);
jbloffi.putExtra("URL",JBL_OFF_URL);
startService(jbloffi);
}
//showNotification("JBL Result", "JBL is Off");
if (flagBose) {
Intent boseoni = new Intent(getApplicationContext(), RequestHandler.class);
boseoni.putExtra("URL",BOSE_ON_URL);
startService(boseoni);
// showNotification("Bose Result", "Bose is On");
}
else {
Intent boseoffi = new Intent(getApplicationContext(), RequestHandler.class);
boseoffi.putExtra("URL",BOSE_OFF_URL);
startService(boseoffi);
//showNotification("Bose Result", "Bose is Off");
}
if (flagProjector) {
Intent projectoroni = new Intent(getApplicationContext(), RequestHandler.class);
projectoroni.putExtra("URL",PROJECTOR_ON_URL);
startService(projectoroni);
//showNotification("Projector Result", "Projector is On");
}
else {
Intent projectoroffi = new Intent(getApplicationContext(), RequestHandler.class);
projectoroffi.putExtra("URL",PROJECTOR_OFF_URL);
startService(projectoroffi);
//showNotification("Projector Result", "Projector is Off");
}
bluetoothAdapter.startDiscovery();
}
}
};

According to your description it sounds like that your Android app ist scanning for Bluetooth LE devices only. As the projector most likely uses Bluetooth classic and both technologies, except for their name, are incompatible your unable to scan for it. If you want to detect those devices too, you need to scan for Bluetooth classic devices in a second step.
As far as your speakers and headset are concerned, I can say from my observation that this behaviour is virtually industry standard. Even if it is technically possible to continue to advertise one's presence during a connection, from an application point of view it only makes sense in rare scenarios and is therefore only very rarely implemented.

Related

How to open application using paired bluetooth device's data in broadcast Receiver

My application is use obd scanner(which is provide bluetooth interface) for get car data. I want to add one feature in this application which is app should be open itself whenever car's obd(already paired) in range of mobile's bluetooth.
My thoughts for implementing this are getting list of paired device in broadcast receiver if any of pair device contain sub-string obd(small or capital)then app should open itself.
what I had achieved :
whenever any bluetooth device which contain obd Sub string is connected with my mobile my app is open itself.process of connection is manually done by me by device setting.
code inside broadcast for above mentioned result:
public class BrodcastBlueTooth extends BroadcastReceiver {
public BrodcastBlueTooth() {
}
#Override
public void onReceive(Context context, Intent intent) {
String DeviceName=null;
String action = intent.getAction();
// Log.d("BroadcastActions", "Action "+action+"received");
int state;
BluetoothDevice bluetoothDevice;
switch(action)
{
case BluetoothDevice.ACTION_ACL_CONNECTED:
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(context, "Connected to "+bluetoothDevice.getName(), Toast.LENGTH_SHORT).show();
Log.d("BroadcastActions", "Connected to "+bluetoothDevice.getName());
DeviceName=bluetoothDevice.getName();
if (DeviceName.contains("OBD")){
Intent newIntent = new Intent();
newIntent.setClassName("com.quad14.obdnewtry", "com.quad14.obdnewtry.activity.MainActivity");
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(newIntent);
}else if(DeviceName.contains("obd")){
Intent newIntent = new Intent();
newIntent.setClassName("com.quad14.obdnewtry", "com.quad14.obdnewtry.activity.MainActivity");
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(newIntent);
}
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED:
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Toast.makeText(context, "Disconnected from "+bluetoothDevice.getName(),
// Toast.LENGTH_SHORT).show();
break;
}
I am declaring my broadcast in manifest so it's always working in background.
I got the paired device list by below code:
public void PairedDevice(){
Set<BluetoothDevice> pairedDevices = BTAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
PaiedDevices.add(device.getName());
Log.e("DeviceName", String.valueOf(PaiedDevices));
PairDeviceFlag=true;
}
}
}
what should i do from this point to get desired result. any other ways also welcome.

How to make the android Bluetooth keep scanning

Hi this is my first time posting.
Im making an android application that only discover Bluetooth device by using the friendly name and the mac address . Not pairing.
The problem im facing is my device fail to detect new device that enter the range after is start the scan about 10 to 12 second.
final BroadcastReceiver bReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name and the MAC address of the object to the arrayAdapter
// System.out.println(device.getAddress());
for(int i=0;i<listmac.size();i++)
{
if(listmac.get(i).equals(device.getAddress())){
System.out.println(listname.get(i));
myListView.setItemChecked(i, true);
}
}
}
}
};
public void find(View view) {
if (myBluetoothAdapter.isDiscovering()) {
// the button is pressed when it discovers, so cancel the discovery
myBluetoothAdapter.cancelDiscovery();
}
else {
myBluetoothAdapter.startDiscovery();
registerReceiver(bReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
isBreceiverRegisted = true;
}
}
public void off(){
myBluetoothAdapter.disable();
Toast.makeText(getApplicationContext(),"Bluetooth turned off",
Toast.LENGTH_LONG).show();
}
Sorry for my broke english
Simply because the discovery task has a timeout to prevent endless searched.
To be able to detect that discovery ended you need add this intent
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
// When discovery is finished , start discovery again
myBluetoothAdapter.startDiscovery();
}
}
Be very careful in general about accidentally leaving your device in discovery-mode. Performing device discovery is a heavy procedure for the Bluetooth adapter and will consume a lot of its resources.

How to check if a bluetooth device is paired

I'm trying to check if there is a bluetooth device paired when running my app.
In the main activity, I find bluetooth devices and pair to them. In the second activity, I must check if there is a device paired or not.
If a device is conected, it starts automatically sending data, but if there is no conexion, then it simply shows a toast.
I need to do this just when the second activity starts. I found this code, but I don't know how to make it to start when the activity is just created.
public void onCreate() {
//...
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter2);
}
//The BroadcastReceiver that listens for bluetooth broadcasts
private final BroadcastReceiver BTReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
//Do something if connected
}
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
//Do something if disconnected
}
}
};
Here is a complete description of the problem, with the correct answer to solve it:
Action to know if there is any bluetooth paired device

16s time delay until the bluetooth disconnected request is recognized

I am working with a bluetooth device (the IOIO developer board).
I want to listen, when my device is disconnected. It is working ok with the code above, but it is not recognized instantaneously. When I power off my bluetooth developer board, I have to wait ~16s until my Android recognized that the connection was lost.
Does anybody know why? I heard it should be a internal Android limitation, that the connection is not checked so often?
Does anybody know how to write a thread which "pings" the bluetooth device if it is still there? I think it is very similar to the Android BluetoothChat example, but I couldn't fixed it on my own.
Thanks.
Felix
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
this.registerReceiver(mReceiver, filter1);
this.registerReceiver(mReceiver, filter2);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
//Device is about to disconnect
Toast.makeText(context,"The device is about to disconnect" , Toast.LENGTH_LONG).show();
}
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
//Device has disconnected
Toast.makeText(context,"Device has disconnected" , Toast.LENGTH_LONG).show();
}
}
};

How to detect if bluetooth device is connected

In android how can my Activity will get to know if a Bluetooth A2DP device is connected to my device.
Is there any broadcast receiver for that?
How to write this broadcast receiver?
Starting from API 11 (Android 3.0) you can use BluetoothAdapter to discover devices connected to a specific bluetooth profile. I used the code below to discover a device by its name:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.A2DP) {
boolean deviceConnected = false;
BluetoothA2dp btA2dp = (BluetoothA2dp) proxy;
List<BluetoothDevice> a2dpConnectedDevices = btA2dp.getConnectedDevices();
if (a2dpConnectedDevices.size() != 0) {
for (BluetoothDevice device : a2dpConnectedDevices) {
if (device.getName().contains("DEVICE_NAME")) {
deviceConnected = true;
}
}
}
if (!deviceConnected) {
Toast.makeText(getActivity(), "DEVICE NOT CONNECTED", Toast.LENGTH_SHORT).show();
}
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, btA2dp);
}
}
public void onServiceDisconnected(int profile) {
// TODO
}
};
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.A2DP);
You can do that for every bluetooth profile. Take a look at Working with profiles in Android's guide.
However, as written in other answers, you can register a BroadcastReceiver to listen to connection events (like when you're working on android < 3.0).
You cannot get the list of connected devices by calling any API.
You need instead to listen to the intents ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED that notifies about devices being connected or disconnected.
No way to get the initial list of connected devices.
I had this problem in my app and the way I handle it (didn't find better...) is to bounce off/on the Bluetooth at application start to be sure to start with an empty list of connected devices, and then listen to the above intents.
muslidrikk's answer is broadly correct; however you can alternatively use fetchUUIDsWithSDP() and see what you get back... it's a bit of a hack though -- you'd have to know what UUIDs (capabilities) you could expect from the device, if it were turned on. And that might be difficult to guarantee.
For BluetoothHeadset specifically, you can call getConnectedDevices() to get connected devices for this specific profile.
Reference: http://developer.android.com/reference/android/bluetooth/BluetoothHeadset.html
Other cases you need to register a receiver for that.
In your activity, define broadcast receiver...
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy

Categories

Resources