Find what Android version is been using? - android

I am developing an app which should perform differently based on the different Android Versions. For instance if a user has version below 3.0, the font should be "Anmol.ttf" but if it's above 3.0 the font should rather be "AnmolUniBani.ttf" How can I approach to this solution?

There are different ways to go about this. I do
android.os.Build.VERSION.SDK_INT;
this gets the version number 10,11, 14,...
See the Documentation for the different possibilities.
I don't know if this is preferred but I set mine in a static variable on startup
public static int androidVersion = android.os.Build.VERSION.SDK_INT;
then check against that. I'm going to move it to SharedPreferences but haven't yet.
Code Example
For 3.0 and above check that the SDK_INT >= 11. So in my example
if (Globals.androidVersion >= 11)
{
// change fonts or whatever
}
It is in a Globals class for now where I put things for testing before making them more permanent as in SharedPreferences or the DB

Related

Implement multiple methods for different API levels and not do if else to decide which one to call

I wonder if it's possible to implement multiple methods to support different API levels and call the right one without if(android.os.Build.VERSION.SDK_INT >= ...) else if...?
I want to use android platform's newer features like streams etc. and still support backwards.
Example:
wrote a method
public void myMethod24() {
// some logic requires api level N(24) and above
}
but my app supports lower apis, so i need another method that's compatible with them.
here is a method compatible for older versions:
public void myMethod21() {
// the same logic, requires api level LOLLIPOP(21) and above
}
How to use the correct method for current running version without doing this ugly if else:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
myMethod24();
} else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
myMethod21();
}
Maybe annotate my methods with #RequiresApi(), #TargetApi or something else..?
i saw this question but the answer there is with if else.
How to use the correct method for current running version without doing this ugly if else
You can't. Somewhere, something needs to do the version check and route to the appropriate logic.
Maybe annotate my methods with #RequiresApi(), #TargetApi or something else..?
Those are there to help advise the compiler that you know what you are doing. They do not code-generate the version comparisons.
Depending on what you are doing, existing ...Compat classes might handle the version checks for you (e.g., NotificationCompat.Builder). If you were using Kotlin, we could come up with some funky code that hides the if checks. And there might be a third-party library that offers some annotation-based code generator that code-generates the if checks.

Is there some standard configuration method to disable some features in the android app I am writing?

I am writing my first android app. It is a Unit Convertor. I planned to give four types of conversions in v1.0. While two of those are working fine, two more are not.
I want to release it with the two which are working first. But don't want to delete the code written for the buggy conversions.
While I can use my VCS for such purposes, I wanted to know if there is a way to control the availability of a feature using some configuration or something. I could not find any such reference online. But don't think I am the first person who has come up with such a need.
Is there some standard way of doing this? If so, can someone point me to it?
You don't say how you're displaying these 'features' If it's a button you could just change its visibility to Gone in the xml:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
/>
The standard way that I have seen in some organizations is to maintain a separate Feature file where they have public methods that return whether or not this is supported in the particular version. Say for example,
inches to cm is available in version 1
pounds to kilogram is not.
In the Feature file, you can specifically mention these.
private static int InchesToCm = 1;
private static int PoundsToKg = 2;
public static boolean shouldShowInchesToCm() {
return InchesToCm <= getResources().getDimension(R.dimen.current_version);
}
I hope you get the point. You can set current_version separately. And then call these functions to check if or not you should show the View. Obviously just removing them by setting their visibility to INVISIBLE will work as well, but this is a standard method.

Android backwards compatibility: reflection versus simple conditional check

I understand there are (at least) two ways to do runtime checks to ensure my code doesn't call APIs that don't exist:
Use a conditional version number check, a la if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
Use java.lang.reflect and wrapper class techniques as explained here: http://android-developers.blogspot.com/2009/04/backward-compatibility-for-android.html
But I don't understand when one technique should be used in lieu of the other. Reflection seems necessary when trying to use Android classes that may not exist, since loading such a class referenced in my code will cause a fatal error. But what about calling a method belonging to a class that I know exists? For example, on a device running 2.2 (API 8):
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
ActionBar actionBar = getActionBar();
}
...
Is this always safe, or are there circumstances where a crash will happen? Is there any reason to check if the "getActionBar" method exists in Activity using reflection instead of using the above version check?
But I don't understand when one technique should be used in lieu of the other.
Use the first bulleted technique.
Is this always safe, or are there circumstances where a crash will happen?
First, you need to change that to HONEYCOMB, as the ActionBar class was added in API Level 11.
Beyond that, so long as you are only supporting Android 2.0 and higher, you are fine. If you are supporting Android 1.x still, you would need to rewrite your code as:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
HoneycombHelper.doSomethingCoolWithTheActionBar();
}
where HoneycombHelper is another class you write that contains your API Level 11 code (e.g., ActionBar actionBar = getActionBar()).
This difference is because Dalvik on Android 1.x would fail fast, giving you a VerifyError as soon as you try loading a class that contains an unrecognized reference. Android 2.0+ will not fail until you actually execute the statement containing the unrecognized reference, and your if test should prevent this.
Is there any reason to check if the "getActionBar" method exists in Activity using reflection instead of using the above version check?
No. Just set your build target (e.g., Project > Properties > Android in Eclipse) to a value high enough to cover everything you want to refer to, and set your android:minSdkVersion to the level you are willing to support. Anything that you try using that is newer than android:minSdkVersion will be flagged with an error by Lint, and you can add your Java version guard block (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.WHATEVER)) and the #TargetApi() annotation to get Lint to stop complaining.

Better way of upping my Minimum API Level?

So I just had to up my min API level to 11 for the Preference (addpreferenceresource was depreciated) - turns out 9-10 takes out like 50% of the market. So my question is, is it better to just suppress the warning to cater to the Gingerbread market or is there a different way to make my preference reference without using Preference Fragments?
I would implement both types (the one that works in 11+ and the one that works in 10-), then use conditional checks for them. This is written in quite a bit of detail in this answer.
Basically, you end up setting up OtherPreferencesActivity with PreferenceFragment, and then PreferencesActivity with the deprecated PreferenceActivity. (Your APK will not break by including this deprecated code, as long as you use a version check so that if/when it's removed in the future, it doesn't try to find it.)
if (Build.VERSION.SDK_INT < 11) {
startActivity(new Intent(this, PreferencesActivity.class);
} else {
startActivity(new Intent(this, OtherPreferencesActivity.class);
}
Keep in mind, you will want to have them use each others' methods as much as possible so that you don't end up duplicating code.
Last tip: #TargetApi(11) and #SuppressWarnings("deprecation") will come in handy here. Just be careful that you're not ignoring other deprecations by doing so.
"depreciated" doesn't mean you can't use it and will break your system if you run the code. It means that it is officially not recommended to use and this method maybe removed from the api. In the future but we don't know when. So I would say it is save to use in this case for now.

How to use new API elements like Switch so, that the app is compatible with older Android version?

I want to use new UI elements like Switch for new Android devices, and by older devices I would use something else like Button.
I have created to layouts
~/res/
layout/main.xml
layout-v14/main.xml
that has different elements like Button in layout/main.xml and Switch in layout-v14/main.xml
But how can I add different elements in the Activity, without to get Exception like
Could not find class 'android.widget.Switch' ...
You can reference Build.VERSION.SDK_INT to inspect the device's API level at runtime. That way, you can add conditional code in your Java classes that will vary its behavior based on the user's API level, like so:
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH ) {
// Some code that requires API level 14+
} else {
// Code that will run on lower API levels instead
}
For Switch you can try the SwitchCompat library, to make it backwards compatible.
You usually include the Support Library in your project dependencies for that purpose.
(http://developer.android.com/tools/extras/support-library.html)
You can then use new objects (like Fragments for example) with older devices.
Unfortunately, Switch is not among them...

Categories

Resources