Android Airplane Mode - Different API versions - android

Can somebody tell me how to handle this situation. I am aware that with API 17, testing for airplane mode has been moved from Setting.System to Settings.Global. Knowing that many of the users will be on phones using the older api, but wanting to handle the deprecation correctly, I've written the following method:
#SuppressWarnings("deprecation")
public static boolean isAirplaneModeOn(Context context) {
try {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
} catch (Exception e) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
}
The problem is that in my manifest, I've set the minSDK value to 9, which is where I want it. The conflict is that then I get this error:
Call requires API level 17 (current min is 9)
What is the correct way to handle this type of situation? Thanks!

check which version the user has
if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLYBEAN){
}else{
}
then just suppress the lint error

Related

Function to check development settings not working as expected

I have a function that checks if developer mode is enabled or not, as the suggestion here:
Android - How to check if Developer option is enabled
Here is the code:
public boolean isDevMode() {
if(Build.VERSION.SDK_INT >= 17) {
return android.provider.Settings.Global.getInt(getApplicationContext().getContentResolver(),
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0) != 0;
} else {
return false;
}
}
It works perfectly on API 26+ but I've just tested it on the emulator on API 24 and it returns false regardless of if developer settings are enabled or not.
What am I missing? Is it a different option for < 26?
Fixed it by changing the default value to true for builds under oreo only.
public boolean isDevMode() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
} else {
return Settings.Secure.getInt(context.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1) != 0;
}
}

How to detect Samsung S10 5G is running on 5G network?

Android Q added a new network type, NETWORK_TYPE_NR for 5G which is
not available for Android Pie. Recently released Samsung S10 fully supports 5G. It can show 5G icon on the status bar when it is on the 5G network.
Is it possible for a third-party app to know if Android Pie device on a 5G network or not?
Any help will be appreciated.
The following link is the definition for the new network type. It is not available on the Android Pie branch.
Source code for Pie release
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/pie-release-2/telephony/java/android/telephony/TelephonyManager.java
The latest source code that has NETWORK_TYPE_NR
https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/telephony/java/android/telephony/TelephonyManager.java#2375
I believe they backported the code from Q to Pie as the logic for 5G was implemented at the end of last year in Q (alpha).
So when using
TelephonyManager.getNetworkType()
you will likely get
20 (5G)
EDIT
As per comment below: The network type will be 13 so it doesn't solve the thing.
EDIT
Try using reflection
static boolean isNRConnected(TelephonyManager telephonyManager) {
try {
Object obj = Class.forName(telephonyManager.getClass().getName())
.getDeclaredMethod("getServiceState", new Class[0]).invoke(telephonyManager, new Object[0]);
Method[] methods = Class.forName(obj.getClass().getName()).getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("getNrStatus") || method.getName().equals("getNrState")) {
method.setAccessible(true);
return ((Integer) method.invoke(obj, new Object[0])).intValue() == 3;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
There is an official documentation to detect 5G on Android 11.
https://developer.android.com/about/versions/11/features/5g#detection
Call TelephonyManager.listen(), passing in LISTEN_DISPLAY_INFO_CHANGED, to determine if the user has a 5G network connection.
as #Hunter suggested you need to use "listen" from telephony manager but if it's api 30+ you need to have READ_PHONE permission granted and listen for LISTEN_DISPLAY_INFO_CHANGED and override onDisplayInfoChanged from PhoneStateListener
(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).listen(customPhoneStateListener,PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED)
The listener should be something like this:
private class CustomPhoneStateListener : PhoneStateListener() {
override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo) {
super.onDisplayInfoChanged(telephonyDisplayInfo)
when (telephonyDisplayInfo.overrideNetworkType) {
//5G
OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO,
OVERRIDE_NETWORK_TYPE_NR_NSA,
OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE -> setNetworkChange(NETWORK_TYPE_NR)
OVERRIDE_NETWORK_TYPE_LTE_CA -> {
setNetworkChange(19) //LTE+
}
else -> setNetworkChange(telephonyDisplayInfo.networkType)
}
} else {
setNetworkChange(telephonyDisplayInfo.networkType)
}
}
}
Link: https://developer.android.com/about/versions/11/features/5g#detection
Couldn't add this as a comment, but as #Pavel Machala said, looking at the ServiceState class in the AOSP yields the following:
/**
* Get the NR 5G status of the mobile data network.
* #return the NR 5G status.
* #hide
*/
public #NRStatus int getNrStatus() {
final NetworkRegistrationState regState = getNetworkRegistrationState(
NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
if (regState == null) return NetworkRegistrationState.NR_STATUS_NONE;
return regState.getNrStatus();
}
I have extracted the ServiceState.java from SM-G977N firmware and it confirms that they have added
ServiceState.getNrStatus()
5G(NR) is active is if NetworkRegistrationState.NR_STATUS_CONNECTED = 3;

Roaming detection on OnePlus One/Two/Three

I'm willing to detect if roaming switch on a telephone is turned off.
if (Build.VERSION.SDK_INT < 17) {
isDataRoamingDisabled =
(Settings.System.getInt(context.getContentResolver(), Settings.Secure.DATA_ROAMING, 0)
== 0);
} else {
isDataRoamingDisabled =
(Settings.Global.getInt(context.getContentResolver(), Settings.Global.DATA_ROAMING, 0)
== 0);
}
Unfortunately only for OnePlus One/Two/Three the setting is always false (0).
On rest devices that i tested - Nexus 6P, LG G5, Samsung S5 all is working fine...
telephonyManager.isNetworkRoaming(), is not really the solution here since it detects if a user in roaming and not switch in settings.
Thanks for help! :)
I found some solution regarding this issue..
It seems like it caused by the using of Dual SIM on these devices, which adopted the newer API for this functionality. (I found it on the source code of Oxygen)
This solution requires READ_PHONE_STATE permission
Accessing the roaming of each subscription:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
List<SubscriptionInfo> subscriptions = SubscriptionManager.from(context).getActiveSubscriptionInfoList();
for (SubscriptionInfo subscriptionInfo:subscriptions) {
if (subscriptionInfo.getDataRoaming() == SubscriptionManager.DATA_ROAMING_ENABLE) {
return true;
}
}
return false;
}
For the rest of the devices you may use the solution you specified above.

Reliable alternative of LOCATION_MODE for KitKat and above to get the degree of location access enabled by the user?

What I'm trying to do:
Since LOCATION_PROVIDERS_ALLOWED was depreciated in API level 19, I am trying to use LOCATION_MODE to get the degree of location access enabled by the user for API above 19 as follows:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int locationMode;
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
// Check if Location services in ON and if YES then make sure its in either HIGH_ACCURACY or POWER_SAVING mode (Not in GPS_ONLY)
switch (locationMode) {
case Settings.Secure.LOCATION_MODE_OFF:
//....
break;
case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
//....
break;
//....
}
} catch (SettingNotFoundException e) {
e.printStackTrace();
}
}
Issue:
Now, for LOCATION_MODE, the docs mention
Note: do not rely on this value being present in settings.db or on ContentObserver notifications for the corresponding Uri.
By what I can understand, it means that its not reliable to use LOCATION_MODE. Then for API > 19, what else is recommended to use for knowing the extent to location access that has been allowed by user for the apps?

How to check "Automatic date and time" is enabled or not?

I need to check whether "Automatic date and time" in the android device is enabled or not. If it is not enabled I need to display the popup that it is not enabled.
Is it possible to achieve. If possible, how to check enabled or not ?
Link for API 17 and above
android.provider.Settings.Global.getInt(getContentResolver(), android.provider.Settings.Global.AUTO_TIME, 0);
Link for API 16 and below
android.provider.Settings.System.getInt(getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0);
public static boolean isTimeAutomatic(Context c) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
return Settings.Global.getInt(c.getContentResolver(), Settings.Global.AUTO_TIME, 0) == 1;
} else {
return android.provider.Settings.System.getInt(c.getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0) == 1;
}
}
I would just like to point out that it is possible to cheat (I just did it on a Samsung Galaxy S4, Android 5.0.1):
Disable auto time
Disconnect from the internets (airplane mode, no wifi etc...)
reboot phone (otherwise the real time is retrieved)
set auto time on
Done today:
Unix time: 1129294173
Date: 14102005024933
is automatic? 1 (using android.provider.Settings.Global.getInt(getActivity().getContentResolver(), android.provider.Settings.Global.AUTO_TIME, 0))
And today definitely isn't Oct 14, 2005
if(Settings.Global.getInt(getContentResolver(), Global.AUTO_TIME) == 1)
{
// Enabled
}
else
{
// Disabed
}
Check is Auto Time or Zone is Enabled ? (Kotlin)
fun isAutoTimeEnabled(activity: Activity) =
Settings.Global.getInt(activity.contentResolver, Settings.Global.AUTO_TIME) == 1
fun isAutoTimeZoneEnabled(activity: Activity) =
Settings.Global.getInt(activity.contentResolver, Settings.Global.AUTO_TIME_ZONE) == 1
in kotlin you can use
fun isTimeAutomatic(c: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Settings.Global.getInt(c.contentResolver, Settings.Global.AUTO_TIME, 0) == 1
} else {
Settings.System.getInt(c.contentResolver, Settings.System.AUTO_TIME, 0) == 1
}}

Categories

Resources