I'm developing an Android app which communicates via BLE with an external module, and I am trying to set the BLE connection PHY.
I've tried calling the method gatt.setPreferredPhy(txPhy, rxPhy, phyOptions) with all the different phy type integer arguments (for both tx and rx), and added the appropriate integer argument for phyOptions in case I was requesting a coded phy.
Every time the onPhyUpdate callback is invoked with a status 6 = GATT_REQUEST_NOT_SUPPORTED.
All other GATT callbacks are invoked with a status 0 = GATT_SUCCESS.
My permissions:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The Android device spec, according to nrf connect:
The datasheet for the bluetooth module I'm communicating with:
https://www.renesas.com/us/en/document/dst/da14531-datasheet?language=en&r=1564826
Well, the error says that your peripheral (the Renesas) doesn't support this particular GATT request. I quickly scanned the Renesas doc and I couldn't find any confirmation that it support 2M phy....
Related
I have Android 10 and Android 12 phones. BLE scanner works fine after rebooting the first one, but doesn't work on the second one.
App has all required permissions requested in runtime:
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="23"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
GPS and Bluetooth are enabled on the phone.
After rebooting, Foreground service is started from the broadcast receiver (Intent.ACTION_BOOT_COMPLETED).
This service then starts the BLE scanner with the scan filter:
bleAdapter.bluetoothLeScanner.startScan(filters, settings, callback)
It's successfully registered in system (BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=7 mScannerId=0), but there are no devices in the scanner callback on Android 12.
What is the reason and how to solve this problem?
Your app is missing the BLUETOOTH_SCAN and BLUETOOTH_CONNECT runtime permissions for API 31 and above. The BLUETOOTH_SCAN is for accessing the ble scan results and the latter is for accessing and communicating with remote devices, hence makes use of the APIs like BluetoothDevice. You need to implement this permissions in your code where you access to these APIs. Also have a look at Target Android 12 or higher.
BLE scanner in service started after phone reboot requires android.permission.ACCESS_BACKGROUND_LOCATION permission at runtime - Allow all the time in location permission settings page (not Allow only while using the app). It's not enough to only put it in AndroidManifest.
More about permission here:
https://developer.android.com/training/location/permissions#request-background-location
We're working on a project that includes connecting a sensor to an android device. The android device will send data to google cloud. We're facing a bit of a problem here, and we would appreciate help.
The problem statement is “The Bluetooth connection state is disconnected whenever the screen is switched off, while we need it to work in the background, and keep receiving data from a sensor and sending data to cloud”.
Implemented a background service that initializes the bluetooth connections
with all following permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
It turned out that it also depends on the phone type itself. Some phone companies tries to extend the battery life of certain types of phones, so it was shutting down any background service that was not in use.
A work-around that can be done by creating a loop that sends a message every small period of time to maintain the connection.
I am currently able to get the Bluetooth adapter mac address on devices with sdk from Marshmallow till Oreo.
However, starting Pie, the retrieved mac address is null.
The following method is working only till and including oreo.
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission
android:name="android.permission.LOCAL_MAC_ADDRESS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
String macAddress = Settings.Secure.getString(context.getContentResolver(), "bluetooth_address");
return macAddress;
I also tried to access BluetoothAdapter.getDefaultAdapter().getAddress() but it returns a fake Mac address like this "02:00:00:00:00"
I only ask the user for runtime permission for fine location. Should I ask for something else? Is there a way to achieve this on Pie and 10?
N.B: I know such app can not be uploaded to Google Play. I just want to implement this for testing purposes on personal devices.
I developed an android app which shows the caller's Telecom Location on Incoming Call.
I uploaded it on Google Play, but this app does not appear on WiFi only devices, it says your device is not compatible .
My Manifest permission details are below.
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
I doubt about following permissions
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Which particular permissions are creating problem?
What is the solution.
Thanks
The google play store filters applications based on the permissions they require and the features available in the android device. So, your app will not show up in WiFi only devices because the app requires the CALL_PHONE permisssion and the MODIFY_STATE_PERMISSION.
The MODIFY_PHONE_STATE permission does not allow you to place calls but it implies that telephony is a requirement.
Source : https://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions
Hence, you should use the <uses-feature> element instead of the above mentioned permissions.
From Docs : You can disable filtering based on the implied feature by explicitly declaring the implied feature, in a element, with an android:required="false" attribute.
In your case :
<uses-feature android:name="android.hardware.telephony" android:required="false" />
But then you also need to ensure that you do not use any of the telephony related features before actually checking if it's available of not.
In the android app, for SDK >=5 , you should use :
PackageManager pm = this.getPackageManager();
boolean hasTelephony = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
You are correct to suspect the following...
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Certain permissions "imply" the necessity for certain hardware to exist. In other words, permissions relating to the phone require the device to have phone capabilities (obviously).
You can get around this by using the <uses-feature> element in the AndroidManifest.xml. This allows you to specify if the 'feature' is required or not.
Take a look at the documentation for <uses-feature-element>
In particular the Permissions that Imply Feature Requirements section which explains the requirements related to the <uses-permission> elements.
EDIT: One more thing - if a feature CAN be used but it's not REQUIRED, it is up to you to check for its availability in your code before attempting to use it otherwise you'll get unpredictable results or possible exceptions / crashes.
I have given user permission in manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
chat app works well with wifi but it doesn't work with GSM connection.
http://pastie.org/9776176 i wrote the database connection code.