https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#disable()
public boolean disable ()
This method was deprecated in API level 33.
Starting with Build.VERSION_CODES.TIRAMISU, applications are not allowed to enable/disable Bluetooth. Compatibility Note: For applications targeting Build.VERSION_CODES.TIRAMISU or above, this API will always fail and return false. If apps are targeting an older SDK (Build.VERSION_CODES.S or below), they can continue to use this API.
How to implement properly disabling bluetooth?
I have no problem with enable bluetooth, I do like this (following https://developer.android.com/guide/topics/connectivity/bluetooth/setup):
if (bluetoothAdapter?.isEnabled == false) {
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
}
I was searching for solution, but in Android documentation they did not add proper implementation for disabling BT in Android API 33.
There is a simple reason why a normal application cannot simply turn off the Bluetooth sub-system in Android.
Nowadays, the Bluetooth sub-system is used by a large number of applications running simultaneously. One example is the Exposure Notifications Framework introduced for COVID 19 which is even part of the operating system. So if individual applications could simply switch off this sub-system, a large number of other applications would be negatively affected.
If you still feel that it is imperative for your application that Bluetooth be turned off, then ask the user to do so via the System menu.
Related
I have implemented Companion device pairing and it works great for most devices without requiring any location permission or location services enabled. However, we found for example Xiaomi Redmi Note 10 Pro (Android 11) where the BLE scan timeouts when Location services are disabled.
Do I still need to implement requiring Location services enabled before the scan or this is undesirable behavior? I hoped it is not needed anymore with this system-level BLE scan.
If so, is there a way how to distinguish which device needs it? I don't want to force all people when it is not needed (for example my Pixel 5)
In my opinion the Companion Device feature was implemented and designed in a rush. You could expect bugs like the "Location services" must be turned on and the Companion Device pairing dialog doesn't warn when it is not enabled. Until Xiaomi or Google fixes this bug, you will need to have workarounds in your app, for example telling the user to first enable Location services if you think that will be needed.
I am also facing issues with applying a scan filter. It is completely a nightmare.
I have started with this:
val filter = ScanFilter.Builder().apply {
setManufacturerData(SOME_INDEX, byteArrayOf(1))
setDeviceName(SOME_NAME)
setServiceUuid(ParcelUuid.fromString(SOME_UUID))
}.build()
Finally, I have only this:
ScanFilter.Builder().apply {
setManufacturerData(SOME_INDEX, byteArrayOf(1))
}.build()
Because setServiceUuid() is not working for example on all tested Huawei phones and Sony Xperia X.
And setDeviceName() is not working for example on Samsung S10e. Finally I have found solution for name filtering by applying directly:
BluetoothLeDeviceFilter.Builder()
.setNamePattern(Pattern.compile(SOME_NAME))
.setScanFilter(filter)
I have a mobile application that allows users to enable/disable WiFi on click of a button.
However I noticed today that my app is no longer able to change the WiFi status. It was working since before few weeks. I tried to debug it but the following method always returns false.
boolean result = wifiManager.setWifiEnabled(true);
I am testing it on Samsung Galaxy Note 9 and Android 10.
This API is no longer supported when targeting Android 10 or higher.
Starting with Build.VERSION_CODES#Q, applications are not allowed to enable/disable Wi-Fi. Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always fail and return false. If apps are targeting an older SDK (Build.VERSION_CODES.P or below), they can continue to use this API.
Instead, you should use the Settings.Panel API to present a system UI allowing users to enable or disable Wi-Fi.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startActivity(Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY))
}
On the android 11 device, I want to check for the "data limit" option is enabled or disabled on the device those are running Android 11. Currently, I am using NetowrkPolicy, NetworkPolicyManager, NetworkTemplate classes. But those all are hidden APIs and now blocked or restricted in targeting device android 11. And code is below -
if (networkPolicy.limitBytes == NetworkPolicy.LIMIT_DISABLED) {
//currentlly data limit is not enabled on device
} else {
//currentlly data limit is enabled on device, so that we can calculate how much is remaining.
}
I have already searched in for ConnectivityManager [Not provide much information related to my task]. I am guessing this may be currently in any setting package or not sure.
Note - I just want to check if the option is enabled or not on device those are targeting android 11.
Update - 1
I am not sure how this can be useful - KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG (Controls the cellular data limit), this says - If the user uses more than this amount of data in their billing cycle, as defined by KEY_MONTHLY_DATA_CYCLE_DAY_INT, cellular data will be turned off by the user's phone. If the value is set to DATA_CYCLE_THRESHOLD_DISABLED, the data limit will be disabled.
My app is working fine, until Android 5.0.2 doesn't allow third party app to connect to HID device over Bluetooth low energy.
myGatt.setCharacteristicNotification(gattChar, true);
06-01 17:39:35.356: W/BluetoothGatt(21599):
java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission:Neither
user 10157 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
BLUETOOTH_PRIVILEGED permission doesn't work on a third party app. It's only for system or manufacturer apps.
The latest changes from Android note:
Enforce BLUETOOTH_PRIVILEGED permission for HID-over-GATT
https://android.googlesource.com/platform/packages/apps/Bluetooth/+/02bebee
Code snippet:
private static final UUID[] HID_UUIDS = {
UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB") };
if (isHidUuid(charUuid)) enforcePrivilegedPermission();
My question: is there a way to overwrite HID_UUIDS or enforcePrivilegedPermission? Can I use reflection to by pass it?
Every times Android released a new version, it breaks the previous code.
Thanks!
The question is old, but still worth answering.
The HID (and FIDO https://fidoalliance.org/) service is protected and indeed requires system permission source. Only apps signed with the system key may use this service, that is only Bluetooth settings. This is to ensure that 3rd party apps are not able to listen to keys typed on a wireless keyboards, as all notifications and indications are transferred to all BluetoothGatt objects. Without this protection you would be able to connect to a HID device (you still can), enable notifications using gatt.setCharacteristicNotification(.., true) and receive updates whenever a key is typed. With a bit of knowledge about Report characteristics you can then get all the keys and mouse positions, including passwords, etc. So it's not a break, but a bug fix. On KitKat you still may do this.
The only solution is to compile your own AOSP Android version and sign your app with the same key. Otherwise it would be useless protection.
Btw, starting form Android 8 or perhaps earlier you don't get SecurityException. The call just returns true as if any other and you never get any callback.
This might have been changed here: https://android.googlesource.com/platform/packages/apps/Bluetooth/+/32dc7a6b919375aede777f3c821fa316d85449ae%5E%21/#F2
I am analysing Android JellyBean 4.3 source code.I could find the varialbe p2p_supported in HAL layer for Wi-Fi Direct support. In the below code snippet from wifi_ath.c
int wifi_start_supplicant(int p2p_supported)
{
if (p2p_supported)
{
strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
strcpy(supplicant_prop_name, P2P_PROP_NAME); // for P2P support
.......................
}
else {
strcpy(supplicant_name, SUPPLICANT_NAME);
strcpy(supplicant_prop_name, SUPP_PROP_NAME); //for station support
}
The values of the macros are:
P2P_SUPPLICANT_NAME = p2p_supplicant ,P2P_PROP_NAME= init.svc.p2p_supplicant
SUPPLICANT_NAME=wpa_supplicant ,SUPP_PROP_NAME=init.svc.wpa_supplicant
Even while connecting in station mode the if part is getting executed and I could not make the WiFi up. Where in the code exactly p2p_supported variable is enabled and disabled so that both the P2P and Wi-Fi works smoothly?
From Jelly Bean(4.1) you only need to turn WiFi on to use WiFi Direct functionality, though using both together depends upon whether your chip supports it.(For that see this SO question)