Android: remove deprecation warning for Html.fromHtml - android

I would like to remove the deprecation warning for Html.fromHtml(string).
I tried to do like this:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
htmlSpanned = Html.fromHtml(string,Html.FROM_HTML_MODE_LEGACY);
} else {
//noinspection deprecation
htmlSpanned = Html.fromHtml(string);
}
but it still gives me a warning during compilation:
Warning:(18, 31) [deprecation] fromHtml(String) in Html has been
deprecated

Well, the one-parameter fromHtml() is deprecated. The Build checks ensure that you will not call it on older devices, but it does not change the fact that it is deprecated with a compileSdkVersion of 24.
You have four choices:
Drop your compileSdkVersion below 24. This has rippling effects (e.g., you cannot use 24.x.x versions of the support libraries) and is not a great option.
Set your minSdkVersion to 24 and get rid of the one-parameter fromHtml() call. This is impractical in 2016.
Live with the strikethrough and Lint complaints.
Add the appropriate #SuppressLint annotation to the method, to get the IDE to stop complaining. As Ahlem Jarrar notes, the simplest way to add this is via the quick-fix.

If your minSdkVersion is 24 or higher, use the version of fromHtml() that takes some flags as a parameter . AFAIK, FROM_HTML_MODE_LEGACY would be the flag value to use for compatibility with the older flag-less fromHtml().
If your minSdkVersion is lower than 24, your choices are:
Always use the fromHtml() you are, possibly using the quick-fix (Alt-Enter) to suppress the Lint warning
Use both versions of fromHtml(): the one taking the flags if your app is running on an API Level 24+ device, or the one without the flags on older devices.

This was my solution at one point:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textField.setText(Html.fromHtml(htmlText, Html.FROM_HTML_MODE_COMPACT));
} else {
textField.setText(Html.fromHtml(htmlText);
}
It worked just fine.

You can try it. I mean your code looks well, I tried it and it worked for me.
// get our html content
String htmlAsString = getString(R.string.html);
Spanned htmlAsSpanned = Html.fromHtml(htmlAsString);
// used by TextView
// set the html content on the TextView
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(htmlAsSpanned);
Our you can try it:
#SuppressWarnings("deprecation")

Android or Kotlin or Google has created HtmlCompat which can be used instead of the method Html. Add this dependency implementation 'androidx.core:core:1.0.1' to the build.gradle file of your app. Make sure you use the latest version of androidx.core:core.
This allows you to use:
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);
You can convert the HTML.FROM_HTML_MODE_LEGACY into an additional parameter if you want. This gives you more control about it which flag to use.
You can read more about the different flags on the HTML Class documentation

Related

Button setTextAppearance is deprecated

Button setTextAppearance(Context context, int resid) is deprecated
and setTextAppearance(int resid) - only available for API level 23
What should I use instead?
Deprecated means that support will be dropped for it sometimes in the future, but it is still working as expected. On older APIs, there is no alternative, since the new setTextAppearance(int resid) got only released with API level 23.
If you want to be safe for a long time, you can use the following code:
if (Build.VERSION.SDK_INT < 23) {
yourButton.setTextAppearance(context, resid);
} else {
yourButton.setTextAppearance(resid);
}
This code prefers the new version on phones with API level 23 or higher, but uses the old one when the API level 23 one isn't available.
I am going to say the same this as #Daniel Zolnai. But do not make the check Build.VERSION>SDK_INT < 23 in all the places in your code. Put this in one place, so it will be easy for you to remove this in the future or make changes to it. So how to do it? I will do this for the yourButton case.
Never use Button or any other view provided by android just like that. I say this, because in the future you will need to tweak something and hence it's better to have your own MyButton or something of that sort. So create MyButton extends Button.
Inside MyButton, put the below code:
public void setTextAppearance(Context context, int resId) {
if (Build.VERSION.SDK_INT < 23) {
super.setTextAppearance(context, resId);
} else {
super.setTextAppearance(resId);
}
}
This way you can always use setTextAppearance without needing to worry about checking for BUILD versions. If in future, you plan to remove this whole thing, then you have to refactor in just one place. This is a bit of work, but in the long run, this will help you a lot and will reduce some maintanance nightmares.

Setting a button background resource with a .png from internal storage

I have a button that I want to set the background of using a png file from internal storage. For android api 16 and up, this works fine:
filePath = getActivity().getFileStreamPath(colorCodes.get(i-1));
temp.setBackground(Drawable.createFromPath(filePath.toString()));
When running on an android tablet with 4.0.4, this part crashes the app with a nosuchmethod error (setBackground). After a little research, I see that setBackground is only available for api 16+. After looking around on SO and a few other places, it looks like I need to use setBackgroundDrawable (deprecated) or setBackgroundResource. I tried this:
filePath = getActivity().getFileStreamPath(colorCodes.get(i-1));
if (android.os.Build.VERSION.SDK_INT < 16) {
temp.setBackgroundDrawable(Drawable.createFromPath(filePath.toString()));
} else {
temp.setBackground(Drawable.createFromPath(filePath.toString()));
}
When logging it out, it shows that setBackgroundDrawable is running and not setBackground, but I get the same nosuchmethod error (setBackground).
The other option is setBackgroundResource, but it accepts an int and not a drawable. Can I convert from drawable to int for this purpose?
What can I do here to set the background of the button to a file in internal storage for APIs < 16?
Thanks.
***EDIT - ok, this is working. just missed a little part elsewhere in the code that had the same problem. However, is using a deprecated method really the only way?
Deprecation is a status applied to a computer software feature,
characteristic, or practice indicating it should be avoided, typically
because of it being superseded. The term is also sometimes used for a
feature, design, or practice that is permitted but no longer
recommended in other areas, such as hardware design or compliance to
building codes. (source link)
Now we can answer your question.
Before API level 16 there is a method named setBackgroundDrawable. After API Level 16 google decided to write a new method setBackground for same purpose and recommend us to use new method. (Reason of this may be found by googling.)
You can use setBackgroundDrawable method for all api levels. There aren't any constraint for this. But using new method setBackground is recommended after API Level 16.
But you can only use setBackground method for devices which is running on API Level 16 or higher. So if you only implement setBackground method in your code, you are going to get MethodNotFoundException for devices which run below API Level 16.
To sum up; it is a best practice(for me it is a must) to use new methods then deprecated ones with supportted api version check such as;
if (android.os.Build.VERSION.SDK_INT < 16) {
temp.setBackgroundDrawable(Drawable.createFromPath(filePath.toString()));
} else {
temp.setBackground(Drawable.createFromPath(filePath.toString()));
}
I am not quite sure whether it is the only way to achieve this but in my opinion it is the correct one. Because the annotation #Deprecated defines the method to be superseded (in most cases) it automatically implies you can (I would even say should) use it to address older versions which are the targeted versions of this method.

setBackgroundDrawable() is API 16 and my app requires a minimum API 9 I get no error when building

I have my app that requires SDK 9+ with code containing setBackgroundDrawable() which is API level 16. I did not get any error while coding or building the apk. but I got about 50 reports of this error happening in google analytics and a few reports in my developers console.
When I run the lint checker It also doesn't warn me. I am using eclipse. Is there a reason why it doesn't fail to compile like usually when you add a method that's not supported by the minimum API or is it simply an eclipse bug?
First of all you get no error when building since you probably are building with SDK 16+ and the method is there. But if you install the apk to a 2.1 Android phone it will throw a MethodNotFound Exception. So in the future ALWAYS install your apk on a min-target device to see if you didn't forget something. Min-Target basically is only a filter for the PLAY store (and for lint warnings, etc.)
AFAIK moving from imageView.setBackground(...) to imageView.setBackgroundDrawable(...) was just an api style design choice. So if you look at the source of Android SDK 18 you will see:
/**
* Set the background to a given Drawable, or remove the background. If the
* background has padding, this View's padding is set to the background's
* padding. However, when a background is removed, this View's padding isn't
* touched. If setting the padding is desired, please use
* {#link #setPadding(int, int, int, int)}.
*
* #param background The Drawable to use as the background, or null to remove the
* background
*/
public void setBackground(Drawable background) {
//noinspection deprecation
setBackgroundDrawable(background);
}
So for now its absolutely irrelevant if you use one or the other - but of course this COULD change (but it's unlikely it does in the future since it would break nearly every app done before SDK 16) - basically it's fine to use setBackground() even on SDK 18+
So if you want to be on the future-proof but ugly side you could use a version fork depicted by the other answers
if(Build.VERSION.SDK_INT >= 16) {
//new code
} else {
//deprecated code
}
Just one thing, and maybe this is a personal style preference, I would not suppress Lint warnings with annotations like this:
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
I like to keep the warnings since maybe later if I want to refactor/move to higher SDK I could easily get rid of these ugly switches.
Update:
Google's v4 support library contains helper classes for sdk boiler plate code. In this instance you would use:
ViewCompat.setBackground(view,drawable);
which handles the SDK check for you.
Seems to be a bug in eclipse or your eclipse is not working perfectly. But you can try project clean and try. But code wise you can try something like this:
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
public void setImage(ImageView imageView, BitmapDrawable bd) {
if(Build.VERSION.SDK_INT > 16) {
imageView.setBackground(bd);
} else {
imageView.setBackgroundDrawable(bd);
}
}
You can call this function along with ImageView and bitmap drawable.

API Level error

In an Activity I have a code that shows this error, but only if you press save.
Call requires API level 11 (current min is 8): android.widget.SearchView#setSearchableInfo
If I change the android:minSdkVersion to 7, it works, but when I save the code again, the same error is thrown. The minSdk must then be changed back to 8,...
What is wrong?
SearchView is available since API lvl 11.
Since your minimum sdk is 8 (lower than 11), Lint will give an error when using SearchView.
You can remove that error by using #TargetApi annotation before your method or class.
But you have to make sure you use a conditional statement before using SearchView to check if it is available, and provide an alternative for earlier versions.
Here's what your code should look like:
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
void yourMethod(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
// use SearchView
} else {
// use some other backward compatible custom view
}
}
The SearchView exists in Android from the version 11 ant more.
So, if you would like to use the SearchView in your code, you have to put the minSdkVersion in your manifest to be 11. In the case you put a number smaller than 11, you will get an error, which is normal beause you are giving access to your app to some android versions which will not support your app.
This can be seen (thanks to #JesseJ) here: http://developer.android.com/reference/android/widget/SearchView.html
Added in API level 11

TextView.getAlpha doesnt exist in Android

I want to get current alpha of textview i am using the following code but i am getting an error that
java.lang.NoSuchMethodError: android.widget.TextView.getAlpha
Please guide me.
This method since API Level 11. Check your API version.
View.getAlpha() only exists since API level 11. You are trying to running your code on a too-old version of Android.
If you absolutely require this functionality, then update your app's minSdkVersion in AndroidManifest.xml to prevent it running on older Android versions. If you can live without it, do a runtime check to see if the API level is high enough.
you can use Alpha method like below
Textview tv_password;
tv_password =(TextView) findviewById(R.id.tv1);
tv_password.getBackground().setAlpha(50);
you can't use getAlpha() method with Textview
View.getAlpha() available from API level 11.But if you want to use this on older api then you may use NineOldAndroids library available for using the Honeycomb (Android 3.0) animation API on all versions of the platform back to 1.0!
So use need to change for e.g.
mAlpha = mView.getAlpha();
to
mAlpha = ViewHelper.getAlpha(mView);
where mView is your view.
Note : Don't forget to import com.nineoldandroids.view.ViewHelper;

Categories

Resources