Android-Java Bluetooth on Samsung Galaxy - java

Can someone explain me why this code give me back always only one bluetooth device, even if i'm working with two galaxy one next to the other one? This code is running on a Samsung Galaxy Tab and i'm using for tests a Samsung Galaxy Gio both with the right Bluetooth activation. If i check on the default research it works ..but not with this code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
out = new TextView(this);
setContentView(out);
// Getting the Bluetooth adapter
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
out.append("\nAdapter: " + adapter);
// Check for Bluetooth support in the first place
// Emulator doesn't support Bluetooth and will return null
if (adapter == null) {
out.append("\nBluetooth NOT supported. Aborting.");
return;
}
// Starting the device discovery
out.append("\nStarting discovery...");
adapter.startDiscovery();
out.append("\nDone with discovery...");
// Listing paired devices out.append("\nDevices Paired:");
Set<BluetoothDevice> devices = adapter.getBondedDevices();
for (BluetoothDevice device : devices) {
out.append("\nFound device: " + device);
}
}

I think you are misunderstanding what you are doing.
On one hand by calling this ...
Set devices = adapter.getBondedDevices();
for (BluetoothDevice device : devices) {
out.append("\nFound device: " + device);
}
... you are looking up the already paired devices. If you only get one the reason is simple, you have only one paired. Take into account that this will return all the paired devices, no matter if they are live or not.
On the other hand you are starting a discovery with ...
adapter.startDiscovery();
... However you have not registered a broadcast receiver to process the *BluetoothDevice.ACTION_FOUND* intents that you will receive with each discoverable Bluetooth device seen. Discoverable is key here because by default Android devices are not discoverable and they only allow a maximum time of typical 120 seconds.

Look at the API
http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery()
startDiscovery is asynchronous - it will scan for about 12 seconds and then get the device names of any addresses found in the scan. You don't wait for discovery to finish so it's not surprising that not all devices in range are discovered by the time you check the results.

do you say out.append("\nAdapter: " + adapter);
but if do you are work in eclipse with xml OR INTELLIJ
TextView txt;
String text;
....
text += ("Adapter:" + adapter);
txt.setText(text);
Do you see the error?

Related

NFC is on, but adapter is not enabled

I am working on android project, where NFC is used as a communication. I am facing a weird problem, when mobile device has a NFC, it is enabled, but it is not working on some devices (adapter is not enabled when debugging). I am writing logs and it prints, NFC on, adapter disabled.
For example: HTC One m9(os 7.0). Also happens with OnePlus One(os 9)! But again, it works on other devices.
Did you experience the same issue?
Here is some code:
object NfcUtil {
fun getNfcAdapter(c: Context): NfcAdapter? {
val manager = c.getSystemService(Context.NFC_SERVICE) as NfcManager
return manager.defaultAdapter
}
fun doesSupportHce(c: Context): Boolean {
return c.packageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
}
}
val adapter = NfcUtil.getNfcAdapter(this)
if (adapter != null && NfcUtil.doesSupportHce(this)) {
if (adapter.isEnabled) {
tvNfcOff.extHide()
} else {
tvNfcOff.extShow()
}
}
I think that if NFC is supported and enabled but the adapter is disabled (https://developer.android.com/reference/android/nfc/NfcAdapter#isEnabled()) I'll follow the guidelines and redirects the user to the settings screen with the intent mentioned in the documentation.
If the user come back few times you could monitor it and show a different message instead of redirecting to settings, something like: NFC is not working properly on your device. I'd check if you have lots of users using those devices, if yes, I will try to research more on the Operating System and Device having this issue.
And later on I will just try to debug it with that Device and that specific Operating System that is having this kind of issue. I'll try to see if other apps using NFC has same issues or they work fine, and by work fine I mean that the communication happens not that other apps dont show any warning/error popup message.
And if I found out its an issue in a specific OS Version, also with other apps, I'll just try to inform the users and get an update on which version the issue have been fixed. Otherwise if other apps can make a successful NFC communication in that device/OS that is not working for me, I'll just dig deeper.
For now I can say there is nothing wrong in your implementation and looks good.
It might be an issue with the current OS or if you have any Custom ROM that might not fully support or have a functional NFC driver.
Two additional bits of info that might be useful
1) Use a Broadcaster receiver to get notified when the NFC state changes, because using the quick settings pull down does not pause your app, therefore retesting nfc status in onResume does not work (a user changing via the full settings app will pause you App, though)
Example of how to do it in Java
#Override
protected void onCreate(Bundle savedInstanceState) {
// All normal onCreate Stuff
// Listen to NFC setting changes
this.registerReceiver(mReceiver, filter);
}
// Listen for NFC being turned on while in the App
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
NfcAdapter.STATE_OFF);
switch (state) {
case NfcAdapter.STATE_OFF:
// Tell the user to turn NFC on if App requires it
break;
case NfcAdapter.STATE_TURNING_OFF:
break;
case NfcAdapter.STATE_ON:
// Do something with this to enable NFC listening
break;
case NfcAdapter.STATE_TURNING_ON:
break;
}
}
}
};
2) Don't assume that the device has a NFC settings page, if your app works with and without NFC, if the adapter is null don't assume you can start an Intent to the NFC settings page as suggested by #denis_lor as this will cause a crash if the OS does not have a NFC adapter to turn on.

BLE Scan not working in Background with Scanfilters in android pie?

I am using blescan with scanfilters to detect beacons it's working very fine in foreground and background up to oreo version but when it comes to android pie it's not able to send pending broadcast in background.
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)).build();
final List<ScanFilter> scanFilters = new ArrayList<>();
scanFilters.add(getScanFilter());
BluetoothAdapter bluetoothAdapter;
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
Intent intent = new Intent(this.getApplicationContext(), MyBroadcastReceiver.class);
intent.putExtra("o-scan", true);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilters, settings, pendingIntent);
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int bleCallbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1);
if (bleCallbackType != -1) {
Log.d(TAG, "Passive background scan callback type: "+bleCallbackType);
ArrayList<ScanResult> scanResults = intent.getParcelableArrayListExtra(
BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);
// Do something with your ScanResult list here.
// These contain the data of your matching BLE advertising packets
}
}
}
Android 9 introduces several behavior changes, such as limiting background apps' access to device sensors and Wi-Fi scans.
These changes affect all apps running on Android 9, regardless of target SDK version.
Sensors that use the continuous reporting mode, such as accelerometers and gyroscopes, don't receive events.
Android 9 Limited access to sensors in background:
Android 9 limits the ability for background apps to access user input and sensor data. If your app is running in the background on a device running Android 9, the system applies the following restrictions to your app:
Sensors that use the continuous reporting mode, such as accelerometers and gyroscopes, don't receive events.
Sensors that use the on-change or one-shot reporting modes don't receive events.
Solution:
If your app needs to detect sensor events on devices running Android 9 while the app is in the background, use a foreground service.
I an example test Android app using Oreo (API 26) and the the code above (slightly modified) to detect beacons. I am using the Pixel 3 XL (with Pie).
I think that the hard part about this is to know for sure if the code in onRecieve() in MyBroadcastReceiver is actually being run upon detection of a beacon when the device is running on battery only (disconnected from Android-studio and Logcat (USB)).
Using Volley (com.android.volley) to submit a HTTP request to a local http server, I was able to demonstrate that it works as documented - ie. I am able to receive the http request when beacon(s) are detected. However, Volley only sends these these requests when Android is awake or when it periodically wakes up and connects to the network - which in my simple tests was about every 15 minutes (plus some variation), but I did get all the beacon ScanResults on my HTTP server, just in delayed up to 15 minutes. I was even able to remove the app from the list of running apps (you know; swiping up to remove the app) and still see that the onRecieve() in MyBroadcastReceiver was receiving BLE ScanResults.
How do you know that the onRecieve() in MyBroadcastReceiver is being killed? I am very interested to know how you know this.

How to get the Bluetooth device model name?

I have an android application related to bluetooth and I have a question. How can I find out which device is connected to a smartphone? I need to know the device model, I can get the device name, but the user can change it, for example “MEIZU EP51” == >> “My favorite headphones”. I need to get the device model or ID, for example, I connected the Meizu EP51 headphones and I need the phone to recognize exactly the model of these headphones. In the Android documentation, I did not find it, maybe I did not read carefully, I would be grateful for the answer.
You can get the connected ble devices by Bluetooth Manager like this,
BluetoothManager bluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
List<BluetoothDevice> devices = bluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
As i have Mi Band 3 i can see this connected device over it. But as it is BLE device so it is visible to me but not sure about other devices.
By BluetoothDevice object you can get device name and address. Try it.

Appreciation about Pcap devices

I'm just trying to get automatically the active device on my System.
For Example:
My PC has two devices.
1. TAP-Windows Adapter V9
2. Intel(R) Ethernet Connection
Actually the active device is the Intel Connection.
So I want that my application can automatically use the active device to dump a pcap.
My Idea is to search for the Subnetmask in both devices.
The active device has an INET4 IP like this mask=[INET4: 255.255.255.0].
The deactive one gives me this: mask=[0]
Is it the right thinking, that an active device never gets a mask of 0?
This extends also for the broadcast.
Here is my implementation:
static public PcapIf selectActiveDev(List alldevs){
PcapIf device = new PcapIf();
for(int a = 0; a<=alldevs.size()-1; a++){
if(alldevs.get(a).getAddresses().get(0).getNetmask().toString() != "0"){
device = alldevs.get(a);
}
}
return device;
}
I'm using JNetPcap 1.3.0 with eclipse. :)

adding filter to bluetooth discovery

I want to just discover peripheral devices when i start my Bluetooth Device discovery, my app must not discover/show other devices. is this any how possible?
this is how i am searching for devices
IntentFilter filter = new IntentFilter("android.bluetooth.devicepicker.action.DEVICE_SELECTED");
registerReceiver(mBtPickReceiver,filter);
startActivity(new Intent("android.bluetooth.devicepicker.action.LAUNCH")
.putExtra("android.bluetooth.devicepicker.action.EXTRA_NEED_AUTH",false));
To reduce (filter) the number of searched devices as per your requirements, check the Class Type of your desired bluetooth device. Once you know the type , you may filter the searched bluetooth devices based on their class type. For example:
BluetoothDevice btd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(btd.getBluetoothClass().getDeviceClass() == BluetoothClass.Device.bla_bla_bla)
{
//do whatever you want with the filtered device
}

Categories