Scan discovery not work in android application - java

I am able to list unpaired devices on scan discovery only if other devices are on their 'bluetooth setting screen'.If other devices are on their homepage then my application cannot find those devices.
I have android 7 on my mobile phone and other devices have android 9 on them.
Any help is appreciated.Thanks:)
public void startDiscovery()
{
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
BA.startDiscovery();
registerReceiver(mReceiver, filter);
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("main","action found"+action);
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Toast.makeText(getApplicationContext(), "Discovery finished", Toast.LENGTH_SHORT).show();
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
Log.d("main","devicename"+deviceName);
Log.d("main","deviceHardwareAddress"+deviceHardwareAddress);
}
};
#Override
protected void onDestroy() {
Log.d("main","destroyed");
super.onDestroy();
BA.cancelDiscovery();
// Don't forget to unregister the ACTION_FOUND receiver.
unregisterReceiver(mReceiver);
}

Its not being discovered because its hidden according to the bt protocol however see https://stackoverflow.com/a/36984988/8461344

Related

I don't receive an action on my BroadcastReceiver - AndroidStudio

It's my first time working with Bluetooth module in Android, I'm trying to scan devices not paired yet and show them in a message but it doesn't work. I have tried a lot of things but nothing. I have all the permissions needed. This is part of my code
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//registerReceiver(mBroadcastReceiver, filter);
if(mBlueAdapter!=null && mBlueAdapter.isEnabled()) {
listAdapter.clear();
mBlueAdapter.startDiscovery();
showToast("Discovery");
IntentFilter filtera = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
}
And this is my BroadcastReceiver
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listAdapter.add(device.getName() + device.getAddress());
listAdapter.notifyDataSetChanged();
showToast("Action Scan Mode " );
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
mpossibleBtn.setText("Scanning Bluetooth Devices");
showToast("Scannning Bluetooth Devices... " );
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
mpossibleBtn.setText("Scanning in progress...");
showToast("Scanning in progress... " );
}
if (action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {
showToast("Action Scan Mode " );
int modeValue=intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR);
if(modeValue==BluetoothAdapter.SCAN_MODE_CONNECTABLE){
mPairedTv.setText("The device is not in discoverable mode but still can receive connections");
} else if(modeValue==BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
mPairedTv.setText("The device is in discoverable mode");
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
showToast("onReceive: " + device.getName() + ": " + device.getAddress());
} else if (modeValue==BluetoothAdapter.SCAN_MODE_NONE){
mPairedTv.setText("The device is not in discoverable mode and can't receive connection");
} else{
mPairedTv.setText("Error");
}
}
}
};
I'm testing the app on my Xiaomi cellphone.
you need to ADD after registering receiver
mBtAdapter.startDiscovery();
Start discovery after registering your receiver.
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mBroadcastReceiver, intent);
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mBroadcastReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
mBtAdapter.startDiscovery();
Or in your case
IntentFilter filtera = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
mBtAdapter.startDiscovery();
Also ensure you have bt permissions on your manifest
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
On some phones you will need to restart the adapter first.
mBluetoothAdapter.disable();
mBluetoothAdapter.enable();
for some time on the broadcast receiver if you don't receive BluetoothAdapter.ACTION_DISCOVERY_STARTED after starting discovery, you have to prompt device restart as the bt may not be working properly.you can use a timer to check this.
Ok so I just found my error. In this case BLUETOOTH and BLUETOOTH_ADMIN permissions have a protection Level of normal, and so all you need to do is request them in the manifest. The location permissions are dangerous, though, and so on Android 6.0+ devices, with a targetSdkVersion of 23 or higher, you need to request those at runtime.
I alredy have the permissions however, we do need to request ACCESS_COARSE_LOCATION at runtime.
This time the code works
mScanBtn.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View v) {
if(mBlueAdapter!=null && mBlueAdapter.isEnabled()) {
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (mMap != null) {
mMap.setMyLocationEnabled(true);
mBlueAdapter.startDiscovery();
}
}
else {
// Permission to access the location is missing. Show rationale and request permission
PermissionUtils.requestPermission(MainActivity.this, MY_PERMISSIONS_REQUEST_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION, true);
mBlueAdapter.startDiscovery();
}
}
});

Connect to Bluetooth Device By Name Programmatically in Java Android?

My intention is to make my android app that only connects to the specific bluetooth name. For Example, I want to connect it to "ABC" only . I tried
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// HERE
}
}
};
How DO I specifically get the name to the output?
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Discovery has found a device. Get the BluetoothDevice
// object and its info from the Intent.
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String deviceName = device.getName();
//
// use try-catch to keep tying on the logic -- John Melody added
try {
if (deviceName.contains("somethingsomething")) {
System.out.println(String.format("Ok %s", deviceName));
}
} catch(Exception e) {
e.printStackTrace();
}
//
}
}
};
Checkout[this][1] link
[1] : https: //developer.android.com/guide/topics/connectivity/bluetooth#FindingDevices

Android - ArrayList containing Bluetooth devices remains empty

I am trying to discover all available bluetooth devices and pass to another activity.
However even when looking at the Android Docs, I am unable to figure out why I cannot discover any devices and my ArrayList remains empty.
OnClick execute this:
mBluetoothAdapter.startDiscovery();
My broadcast listener also works but nothing is every returned and ArrayList remains empty.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
showToast("Found device " + device.getName());
}
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_ON) {
showToast("Enabled");
showEnabled();
}
}
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
mDeviceList = new ArrayList<>();
mProgressDlg.show();
}
if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
mProgressDlg.dismiss();
Intent newIntent = new Intent(MainScreen.this, DeviceListActivity.class);
if (mDeviceList.isEmpty()){
Log.d("onReceive: ", "EMPTY");
}
newIntent.putParcelableArrayListExtra("device.list", mDeviceList);
startActivity(newIntent);
}
}
};
GIST
Answered my own question.
The fix was to turn location on with app permissions.
Apparently this is required for Android Marshmallow

How to call onReceive method in another method?

Currently I developed a new method to discover bluetooh ready connections. Here is my code:
private void DiscoverOBDConnection() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.startDiscovery();
BroadcastReceiver mReceiver;
// Create a BroadcastReceiver for ACTION_FOUND
final List<String> discoverableDevicesList = new ArrayList<String>();
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);
short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
discoverableDevicesList.add(device.getName() + "\n" + device.getAddress() + "\n" + rssi);
String discoveredDeviceName = device.getName();
discoverableDevicesList.add(discoveredDeviceName);
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(mReceiver,filter); // Don't forget to unregister during onDestroy
}
I just do not know how to call the onreceive method from another method. Could you help me to learn how to implement and discover the ready to connect bluetooth devices?
You can just send broadcast
Intent i = new Intent(BluetoothDevice.ACTION_FOUND);
sendBroadcast(i);
Or call it directly
mReceiver.onReceive(this, new Intent(BluetoothDevice.ACTION_FOUND));

how to get Bluetooth name of peer device in Android?

how is it possible to get the Bluetooth information (name, Mac address,...) of the peer device that the android device is connected to that via Bluetooth ?
You can use the following code to get all remote devices :)
private void discoveryDevice(){
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
mBluetoothAdapter.startDiscovery();
}
// 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);
Log.d(TAG, "device " + device.getName() + "\n" + device.getAddress());
}
}
};
It's really good for you to get the name of remote device throught the code:
Log.d(TAG, "device " + device.getName() + "\n" + device.getAddress());
I can't test this code at this moment but maybe can give an idea to how you can get the name and others parameters of bluetooth.
static BluetoothSocket socket ;
public static boolean btCon(Context ctx){
Method m;
try {
BluetoothDevice devc = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(MAC_ADRS);
m = devc.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
socket = (BluetoothSocket)m.invoke(devc, Integer.valueOf(1));
socket.connect();
String name = devc.getName();/* or */ String name2 = devc.getName().toString();
Log.i("Test","Name: "+name);
Log.i("Test","Name 2: "+name2);
return true;
}catch(Exception e)
{
return false;
}
}

Categories