How to get the device is supported for Dual Sim for Below Android R.
I am using the following code. But I am getting a deprecated warning for telephony.getPhoneCount().
How to get for below Android R. Or do we need to add #SuppressWarnings( "deprecation" )?
public boolean isDuelSim(Context pContext) {
TelephonyManager telephony = (TelephonyManager) pContext.getSystemService(Context.TELEPHONY_SERVICE);
if (telephony != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return telephony.getActiveModemCount() == 2; //Dual SIM functionality
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return telephony.getPhoneCount() == 2;
}
}
return false;
}
The getPhoneCount() method seems to be the right way of checking if the device supports dual SIM on api levels from M to Q. If you are compiling your project for R or greater, you will get the deprecation lint warning.
IMO, your implementation is correct and if you need to suppress that warning then either add the #SuppressWarnings("deprecation") annotation to your isDualSim() method signature or the //noinspect comment above the telephony.getPhoneCount() call.
BTW, I'd also suggest considering the case when getActiveModemCount() or getPhoneCount() returns a 3. Whether a tri SIM phone should pass your dualSIM test or not depends on your use case, of course.
Related
I'm working on a application where I use the API 19 and the feature Closed Caption, but not all my devices have Kit kat installed, for this reason when I use something of this API I put that:
#TargetApi(19)
private Boolean getStateAndroidCC()
{
CaptioningManager captioningManager = (CaptioningManager) context.getSystemService(
Context.CAPTIONING_SERVICE);
return captioningManager.isEnabled();
}
But When I run the application and check the console of Logcat, I see this line:
**Could not find class 'android.view.accessibility.CaptioningManager'
Can you help me to resolve that ?
Because I read that if I use this tag #TargetApi(19),this problem will be resolved, but I can not fix it.
Thanks in advance.
#TargetApi annotation is used to supress the Lint API check, so you wouldn't have a compile error.
It means: I'm aware that I'm calling an API which might not be available on all devices and I am properly handling it.
So you have to check if you're running Kitkat before you call the API in question:
#TargetApi(19)
private Boolean getStateAndroidCC()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
CaptioningManager captioningManager = (CaptioningManager) context.getSystemService(
Context.CAPTIONING_SERVICE);
return captioningManager.isEnabled();
}
return false;
}
I have some code that compiles successfully using ViewTreeObserver#removeOnGlobalLayoutListener(...) and when it runs, this method throws NoSuchMethodError. Why?
There are two methods in ViewTreeObserver with almost the same name.
removeOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)
(on then global) is a method that was added in API 16. It replaces
removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener victim)
(global then on) which has existed since API 1, but which is now deprecated.
Both methods can appear present at compile-time (if you're building against Jellybean or higher) but the newer one will fail on pre-Jellybean devices.
This code thwarts the error:
try {
thing.removeOnGlobalLayoutListener(victim);
} catch (NoSuchMethodError x) {
thing.removeGlobalOnLayoutListener(victim);
}
So does this code:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
thing.removeGlobalOnLayoutListener(victim);
} else {
thing.removeOnGlobalLayoutListener(victim);
}
I assume you are talking about removeOnGlobalLayoutListener from ViewTreeObserver class. This method was added in API level 16. My best guess is that you try to use it on a device running an old version of Android that's why it can't be found.
I have working code
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if (Build.VERSION.SDK_INT < 16) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
Im developing an app with the latest android version (4.2.1 API-Level 17) for tablets with multiuser capabilities.
I want to restrict certain features (like the access to the app preferences) to the owner of the tablet (that is the user who can add and remove other user accounts)
is there any way i can find out if the current user is the owner?
i read through the UserManager and UserHandle API docs but couldn't find a function that allows me to check for it.
have i missed something or is there another way to do that?
Similar but without reflection:
static boolean isAdminUser(Context context)
{
UserHandle uh = Process.myUserHandle();
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
if(null != um)
{
long userSerialNumber = um.getSerialNumberForUser(uh);
Log.d(TAG, "userSerialNumber = " + userSerialNumber);
return 0 == userSerialNumber;
}
else
return false;
}
You can create an extension property in Kotlin to make it simpler:
val UserManager.isCurrentUserDeviceOwner: Boolean
get() = if (SDK_INT >= 23) isSystemUser
else if (SDK_INT >= 17) getSerialNumberForUser(Process.myUserHandle()) == 0L
else true
Then, using it is as simple as the following:
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
if (userManager.isCurrentUserDeviceOwner) TODO() else TODO()
You can further reduce boilerplate by using global system services definitions that makes userManager and other Android System Services available anywhere in your Kotlin code, with code included in this library I made: https://github.com/LouisCAD/Splitties/tree/master/systemservices
After researching further i found out that the multiuser api is not functional yet, it cant really be used for anything. there is a hack though for checking if the user is the owner using reflections:
public boolean isCurrentUserOwner(Context context)
{
try
{
Method getUserHandle = UserManager.class.getMethod("getUserHandle");
int userHandle = (Integer) getUserHandle.invoke(context.getSystemService(Context.USER_SERVICE));
return userHandle == 0;
}
catch (Exception ex)
{
return false;
}
}
This works for me on the Nexus 7 and Nexus 10 with Android 4.2.1
Its very dirty. so i wouldnt recommend using it unless you are making an app thats device and version specific
So the code is following:
public static ActionBarHelper createInstance(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS(activity);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new ActionBarHelperHoneycomb(activity);
} else {
return new ActionBarHelperBase(activity);
}
}
If my device is 2.3 (api 9) it shouldn't support Build.VERSION_CODES.ICE_CREAM_SANDWICH but yet it runs, why is that? If it had been a method I called it would have crashed. Is it because it is a public static final int and therefor added from to my code? Please give some general detail and not just a yes/no answer :)
As Stefan pointed out, the api level used to compile the code determines the constants visible at compile time. For my case this doesn't give any problems as I just compare simple values. This only give problems if you use a set method that uses different constants and you happent to use a constant that wasn't possible to handle for your api version.
I would like to write an application that uses live wallpapers for insatnce. this feature is supported only in version 7 and up. Is it posiible, that the application checks the version of the android phone and depending on that runs different code (e.g. uses live wallpaper or static background.)
Do you have a code example for that? Does that require special permissions?
Assuming you're requiring Android 1.6 or newer:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
...
}
Yes there is. Look at the Build class in Android. You can use it like so Build.VERSION.SDK_INT
public static final int ECLAIR_MR1 =7;
public static final int FROYO =8;
if(Build.VERSION.SDK_INT==FROYO){
Toast.makeText(getApplicationContext(), "Iam a FROYO-Phone", 1).show();
}else if(Build.VERSION.SDK_INT==ECLAIR_MR1){
Toast.makeText(getApplicationContext(), "Iam an ECLAIR-Phone", 1).show();
}
SDK_INT is not available on very early builds. So if your manifest has for instance:
android:minSdkVersion="1"
you can use something like this:
#TargetApi(Build.VERSION_CODES.DONUT)
static boolean getPreHoneyComb() {
try {
Build.VERSION.class.getField("SDK_INT");
}
catch (NoSuchFieldException e) {
return true;
}
return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
}