I know this question has already been asked but It does not work for me. I want to automatically pair 2 devices without having a pairing notification on my device. I followed the instruction here: How to pair Bluetooth device programmatically Android but it does not work. Indeed, I still have a pairing notification.
Here is my code:
IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
final BroadcastReceiver mReceiver2 = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int pin=intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 0);
byte[] pinBytes = Integer.toString(pin).getBytes();
device.setPin(pinBytes);
boolean b = device.createBond();
}
}
}
};
registerReceiver(mReceiver2, filter2);
Related
I have problem with Futronic fingerprint usb device on Android 10 & 11. The code
intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
always return false when I press the OK button on permission dialog. I have old an android 5 device, it works OK.
Here is the code from their SDK (UsbDeviceDataExchangeImpl.java), included as module on Android Studio
public UsbDeviceDataExchangeImpl( Context ctx, Handler trg_handler )
{
context = ctx;
handler = trg_handler;
mDevManager = (UsbManager)ctx.getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(ctx, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
context.registerReceiver(mUsbReceiver, filter);
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (mPermissionIntent)
{
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
if(device != null)
{
usb_ctx = OpenDevice(device);
}
handler.obtainMessage(MESSAGE_ALLOW_DEVICE).sendToTarget();
}
else
{
handler.obtainMessage(MESSAGE_DENY_DEVICE).sendToTarget();
}
}
}
}
};
Are there any extra permission settings for Android 10 & 11 for external usb device ?
Thank you.
Might be the same issue: AndroidStudio USB: EXTRA_PERMISSION_GRANTED returns false - always
Changing PendingIntent.FLAG_IMMUTABLE to PendingIntent.FLAG_MUTABLE helped in my case.
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.
For my application, I need to establish a connection with an attached Arduino device, here is the code:
public String openConnection(UsbManager manager, Context context) {
// getting the driver with an external library...
UsbSerialDriver driver = availableDrivers.get(0);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
manager.requestPermission(driver.getDevice(), pi);
UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
if (connection == null) {
return "Found a device, but cannot connect";
}
// otherwise, continue and do stuff
}
The problem is that, when a device is attached, the first time I open the app it shows the alert asking for the permission, but if I click "OK", the connection is null, so it returns early. However, the second time it does not ask for any permission but the connection is opened and everything works fine.
Why does this happen?
I know this is not the most correct approach to open an USB connection, but I have other issues that are not inherent to the question, so I'm rather intrested to understand why does this happen than what should I do instead
I'm testing this on Android 8.1.0
Try to previously ask for permission and start the rest of your code from a Broadcast Receiver that listens for the USB permission granted.
This is showed in Google's docs:
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
}
}
else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
}
};
Here's how you register the Broadcast Receiver:
UsbManager mUsbManager = (UsbManager)
getSystemService(Context.USB_SERVICE);
private static final String ACTION_USB_PERMISSION =
"com.android.example.USB_PERMISSION";
...
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new
Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
And then you start it all with:
UsbDevice device;
...
mUsbManager.requestPermission(device, mPermissionIntent);
In the way you do it, the device tries to connect to USB even before the permission has been granted and so it fails.
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
I used ACTION_MEDIA_MOUNTED and ACTION_MEDIA_UNMOUNTED to detect USB connection on Nexus 4, but I cannot receive any broadcast signal.
Here is my broadcast receiver code:
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
filter.addDataScheme("file");
debugReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
debugOn = true;
} else if (Intent.ACTION_MEDIA_UNMOUNTED.equals(action)) {
debugOn = false;
}
}
};
registerReceiver(debugReceiver, filter);
Any ideas? I also searched others questions; they said if I add
"filter.addDataScheme("file");"
I will get the signal, but I have tried and nothing was received.
Use UsbManager.ACTION_USB_DEVICE_ATTACHED and UsbManager.ACTION_USB_DEVICE_DETACHED for your intent filter.
To check for connection to PC use Intent.ACTION_BATTERY_CHANGED and onReceive intent.getInt(BatteryManager.EXTRA_PLUGGED) and see if the value is BatteryManager.BATTERY_PLUGGED_USB.