I came to know the privacy changes for Android 10 and I'm quite clear that third-party apps won't be able to get IMEI now.
But one thing from documentation is creating confusion for me.
They state
If your app targets Android 9 (API level 28) or lower, the method returns null or placeholder data if the app has the READ_PHONE_STATE permission. Otherwise, a SecurityException occurs.
which means that on Android devices with API LEVEL 28 or lower, this method returns null or placeholder data, even if the app is having READ_PHONE_STATE permission. Right?
But I have tested this thing on my app targetting API LEVEL 28 and I am still able to get IMEI number with the following.
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
fragment.requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_CODE);
}
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = telephonyManager.getImei();
Shouldn't it send me NULL or placeholder (garbage) data?
any idea about it? or am I misinterpreting it?
You're misinterpreting it. What documentation says, is:
If your application targets Android 9 (API level 28) or lower, then it will return null or placeholder data when running on Android 10 device.
Documentation describes here how it will behave on Android 10 in case you don't target Android 10. It's so applications don't suddenly break in strange ways despite not being updated. It has no effect on Android 9 devices (and on emulators that emulate Android 9 devices, which is probably what you're testing it with when targeting API level 28).
Related
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))
}
I'm trying to make a network usage monitor app, which shows mobile data usage history to the user. For this I'm using Usage access to get accurate data usage stats from NetworkStatsManager. But this no longer works in Android 10.
I'm using NetworkStatsManager.querySummaryForDevice which requires subscriber Id, which earlier I was able to obtain using TelephonyManager.getSubscriberId.
But the getSubscriberId is now not working in Android 10 as it requires READ_PRIVILEGED_PHONE_STATE which third-party apps cannot have.
Any ideas on how to make it work? I understand the restrictions for getting subscriber Id, but I don't really care about the subscriber Id as long as I get the mobile data usage, for which I have enough permissions.
Try passing null as subscriber ID in the querySummaryForDevice method .. That worked for me
When calling NetworkStatsManager resolve subscriberId as follows:
use null when running on Android versions 10+ (API Level >= 29) devices
on prior versions of Android (API Level < 29) you should still resolve subscriberId (using TelephonyManager)
Here is a sample code that should help:
public static String getSubscriberId() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getSubscriberId();
} else {
return null;
}
}
Worked for me on Android API Level 29 and Android API Level 26 devices.
There's no way at the moment to get the information you want unless your app is a profile or device owner app. You can just use the TrafficStats but you can't use a query and it resets on reboot.
OnePlus3 Nougat only (so far): TelephonyManager getNetworkType() is sometimes (!?) returning the value 19 which is not defined in the doc, according the the situation it should be NETWORK_TYPE_LTE = 13 as the status bar is showing 4G+.
Obviously users are down-rating my app again, instead of blaming OnePlus.
Any Idea What is going on with the OnePlus3?
Why is the Status Bar working fine?
Is that supposed to be official?
I'll add this 19 as a hard-coded value for LTE but what if it changes in the future... My app will be wrong for real.
And more generally, How can I avoid users to blame me for all the Android/Manufacturer bugs that are introduced in every new release?
Doc:
https://developer.android.com/reference/android/telephony/TelephonyManager.html#getNetworkType()
System Data:
VERSION.RELEASE{7.0},VERSION.INCREMENTAL{97},VERSION.SDK{24},BOARD{QC_Reference_Phone},BRAND{OnePlus},DEVICE{OnePlus3},FINGERPRINT{OnePlus/OnePlus3/OnePlus3:7.0/NRD90M/12311011:user/release-keys},HOST{ubuntu-23},ID{NRD90M}
4G+ is the new LTE-Advanced (LTE-A) and doesn't exist as constant in TelephonyManager class.
4G is LTE (NETWORK_TYPE_LTE = 13).
I hope Google will update its constants or give us the value for 4G+ (19 ?).
I'm using altbeacon library to monitor and range beacons. I've read your requesting permission page and just want to know, if I target location permission for API 23+ (), will scan works on devices with API < 23? I don't have real device, so can't test it. Or is there any way to not request location permission with device with API below 23? Thanks for your answers
Restating the core question:
If you build an app that has a minSdkVersion < 23 but the targetSdkVersion >= 23, what happens when you try to scan for bluetooth beacons?
Short answer: it works.
Longer answer:
The user permissions request won't happen. with a minSdkVersion < 23, The compiler will stop you from including a line of code like requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
because it won't run on earlier Android versions. If you wrap it in an if statement like if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) it won't get executed. If you add annotations like #SuppressLint("NewApi") the app will crash when trying to execute the code.
The beacon scanning will just work, both in the foreground and the background, regardless of the fact that the user permissions have not been granted. Earlier Android versions can't request the permission from the user, so the app just behaves as if they have been granted.
On Android 23 and on, you need to check if the app has been granted a "dangerous" permission and if not ask the user.
The Android support library has helper functions for this.
See Requesting Permissions at Run Time.
The main functions are checkSelfPermission and requestPermissions.
In order not to have problems with older versions of Android you can use the following to check if you are on a device running Marshmallow or not:
public static boolean isMNC() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
This will return true if you are on a device running Marshmallow or newer, false otherwise. So, if this returns true, check for the permission, otherwise don't.
You should probably also use the annotation #SuppressLint("NewApi") on the function where you call the checkSelfPermission and requestPermissions.
I am trying to check for permissions being granted/revoked by user in Android Marshmallow. Unfortunately ContextCompat.checkSelfPermission() (which is a warpper around Context.checkCallingOrSelfPermission) seems to always return PackageManager.PERMISSION_GRANTED (0) if you have included that specific permission in your manifest regardless of the current state of the permission (e.g. if the user has revoked the permission). I also tried someContext.checkCallingOrSelfPermission(), but the result is the same.
Has anyone experienced this? I am using Android Marshmallow on nVidia Shield console (using nVidia's Beta program).
As it turns out, The targetSdkVersion in the manifest must be 23, mine was 22. If your target SDK is 23 (Android 6), all of the permissions (in your manifest) are disabled by default, whereas if your target SDK is 22 (Android 5.1) and your app is running on Android 6, all of the permissions are enabled by default when the user installs the app, and even if the user revokes the permissions later on, the mentioned API returns incorrect value (which is a bug in my opinion).