Missing font character like reduced Planck constant - android

I want to display two Unicode characters in TextView, but I get squares:
- ℏ (reduced Planck constant/PLANCK CONSTANT OVER TWO PI http://www.fileformat.info/info/unicode/char/210f/index.htm)
- ℞ (PRESCRIPTION TAKE http://www.fileformat.info/info/unicode/char/211e/index.htm)
I know that not all Unicode characters are supported by default Android font, but reduced "h-bar" is Latin character and it's one of the fundamental physical constants. Can anyone confirm that I making everything right? And if, how to solve this problem (third-part font is the only solution)?
view = new TextView(this);
int[] codePoint = { 0x210f, 0x211e };
String hhh = new String(codePoint, 0, codePoint.length);
view.setText(hhh);

According to the character set page the Droid fonts don't support U+210F (ℏ), but they do support U+0127 (ħ), so you might consider using an italic font and U+0127 instead.

add font containing characters to /system/fonts,
modify /system/etc/fallback_fonts.xml so android finds font then
reboot.
Everything should be working now

Related

How to detect emoji support on Android by code

By code, I can make a button that inserts these 3 emojis into the text: ⚽️😈🐺
On many phones when the user clicks the button, though, the problem is that ⚽️😈🐺 displays as [X][X][X]. Or even worse, it displays only three empty spaces.
I would like to disable and hide my own built-in emoji-keypad on Android devices that do not display emojis correctly. Does anyone knows or have a tip on how to detect in code if a device has emoji support?
I have read that emoji is supported from android 4.1, but that is not my experience....
I just implemented a solution for this problem myself. The nice thing with Android is that it is open source so that when you come around problems like these, there's a good chance you can find an approach to help you.
In the Android Open Source Project, you can find a method where they use Paint.hasGlyph to detect whether a font exists for a given emoji. However, as this method is not available before API 23, they also do test renders and compare the result against the width of 'tofu' (the [x] character you mention in your post.)
There are some other failings with this approach, but it should be enough to get you started.
Google source:
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java#441
https://android.googlesource.com/platform/packages/inputmethods/LatinIME/+/master/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
Based on Jason Gore answer:
For example create boolean canShowFlagEmoji:
private static boolean canShowFlagEmoji() {
Paint paint = new Paint();
String switzerland = "\uD83C\uDDE8\uD83C\uDDED"; // Here enter Surrogates of Emoji
try {
return paint.hasGlyph(switzerland);
} catch (NoSuchMethodError e) {
// Compare display width of single-codepoint emoji to width of flag emoji to determine
// whether flag is rendered as single glyph or two adjacent regional indicator symbols.
float flagWidth = paint.measureText(switzerland);
float standardWidth = paint.measureText("\uD83D\uDC27"); // U+1F427 Penguin
return flagWidth < standardWidth * 1.25;
// This assumes that a valid glyph for the flag emoji must be less than 1.25 times
// the width of the penguin.
}
}
And then in code whenever when you need to check if emoji is available:
if (canShowFlagEmoji()){
// Code when FlagEmoji is available
} else {
// And when not
}
Surrogates of emoji you can get here, when you click on detail.
An alternative option might be to include the Android "Emoji Compatibility" library, which would detect and add any required Emoji characters to apps running on Android 4.4 (API 19) and later: https://developer.android.com/topic/libraries/support-library/preview/emoji-compat.html
final Paint paint = new Paint();
final boolean isEmojiRendered;
if (VERSION.SDK_INT >= VERSION_CODES.M) {
isEmojiRendered = paint.hasGlyph(emoji);
}
else{
isEmojiRendered = paint.measureText(emoji) > 7;
}
The width > 7 part is particularly hacky, I would expect the value to be 0.0 for non-renderable emoji, but across a few devices, I found that the value actually ranged around 3.0 to 6.0 for non-renderable, and 12.0 to 15.0 for renderable. Your results may vary so you might want to test that. I believe the font size also has an effect on the output of measureText() so keep that in mind.
The second part was answerd by RogueBaneling here how can I check if my device is capable to render Emoji images correctly?

Textview does not support base 64 decoding Android

I have some content encoded in base64 from my server.
When I get a response and try to decode it, it does not show new lines and spaces encoded in the content.
The below code decodes properly, but when I set it as the text of the textview, no new lines or spaces are shown in content decoded.
However, saving the content decoded in sqlite and viewing in sqlite browser notepad show the text correctly.
String base64data = response.getString("data");
byte[] data = Base64.decode(base64data, Base64.DEFAULT);
String text1 = new String(data, "UTF-8");
My decoded content is like:
In typography, the point is the smallest unit of measure. It is used for measuring font size, leading, and other items on a printed page. The size of the point has varied throughout the history of printing. Since the 18th century, the point's size has varied from 0.18 to 0.4 millimeters.
1P̸2p (12 points would be just "1P̸")—traditional style
1p2 (12 points would be just "1p")—format for desktop
14pt (12 points would be "12pt" or "1pc" since it is the same as 1 pica)—format used by Cascading Style Sheets defined by the World Wide Web Consortium[3]
A typographic or printer's foot contains 72 picas or 864 points. The Metric Act of 1866 established a legal ratio of 1200 : 3937 between the foot and the meter.[4] For the survey foot used prior to 1959, this was 0.0002% more than 304.8 mm, the length of the international foot established by the 1959 International Yard and Pound Agreement.
And in textview,it is showing like this:
In typography, the point is the smallest unit of measure. It is used for measuring font size, leading, and other items on a printed page. The size of the point has varied throughout the history of printing. Since the 18th century, the point's size has varied from 0.18 to 0.4 millimeters. 1. 1P̸2p (12 points would be just "1P̸")—traditional style 2. 1p2 (12 points would be just "1p")—format for desktop 3. 14pt (12 points would be "12pt" or "1pc" since it is the same as 1 pica)—format used by Cascading Style Sheets defined by the World Wide Web Consortium[3] A typographic or printer's foot contains 72 picas or 864 points. The Metric Act of 1866 established a legal ratio of 1200 : 3937 between the foot and the meter.[4] For the survey foot used prior to 1959, this was 0.0002% more than 304.8 mm, the length of the international foot established by the 1959 International Yard and Pound Agreement.
It's hard to say what is the cause of your problem without content but there are some advices which can help you.
First, use TextView with enough size. Something like this one:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="false" />
I suppose you use \n symbol as line break. So when you are adding your text, replace \n symbols with System.getProperty("line.separator"). Something like this:
String text1 = new String(data, "UTF-8");
String string = text1.replace("\\\n", System.getProperty("line.separator"));
As alternative you can use SpannableString.
While decoding your base64data try to use other flags.
I guess Base64.NO_WRAP is what you want. You can also see other flags from here
byte[] data = Base64.decode(base64data, Base64.NO_WRAP);
I found a Simple but strange answer :
String base64data = response.getString("data");
byte[] data = Base64.decode(base64data,
Base64.DEFAULT);
String decoded_text= new String(data, "UTF-8");
decoded_text=decoded_text.replaceAll("[\n\r]", "WRAP");
decoded_text=decoded_text.replaceAll("WRAP","\n\r");
textview.setText(decoded_text);
Thanks

chemistry formula on Android

I'm developing an android project and I want to render some chemistry formula.
I wrote the following code and I got the following result.
I create a custom string and show it in a textview.
But my question is this: Is this the best way to do this? And is there another way to handle that?
str = new SpannableString(Html.fromHtml("2H<sup>+</sup> + So<sub size = 2>4</sub><sup size = 2>2-</sup> --> H<sub size =2>2</sub>So<sub size = 2>4</sub>"));
ss1.setSpan(new RelativeSizeSpan(0.6f), 2,3, 0); // set size
ss1.setSpan(new RelativeSizeSpan(0.6f), 8,11, 0); // set size
ss1.setSpan(new RelativeSizeSpan(0.6f), 17,18, 0); // set size
ss1.setSpan(new RelativeSizeSpan(0.6f), 20,21, 0); // set size
TempF.setText(ss1,TextView.BufferType.SPANNABLE);
I don't think there is a better way.
Unfortunately Html.fromHtml() ignores <font size="n"> tags, so these spans need to be added manually, as you have done.
I had a similar problem to solve. I created a simple library by extending WebView and using JavaScript in the background. https://github.com/RanaRanvijaySingh/EquationView
String strChem = "Chemistry: \\(\\ce{CO2 + C -> 2 CO}\\)";
EquationView equationViewChem = findViewById(R.id.equationViewChem);
equationViewChem.setText(strChem);
In your layout file:
<com.rana.equationview.EquationView
android:id="#+id/equationViewChem"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Hope this helps someone.
I think you have found a solution that fits you.
Perhaps, if there is a rule to know when a symbol will be a subscript or superscript, or the spansize you have to use, you can write a method to parse a given a formula privided as a string and automatically provide the formated html output.
To do this, and assuming there are specific rules, you can use a finite state machine that will "compile" a text string to the html output you need.
If you are looking for something like this let me know and we may be able to work it out.
Another option would be to see if you find (in Internet) a font that meets your needs (Or perhaps build your own). You can import a font putting the font file in the assets folder and setting it from there in the source.

Same color for android and iphone

I tried to use the same color used in iphone to my android device
This is the color for iphone.
(UIColor *)navBarColor {
return [UIColor colorWithRed:0.329f green:0.584f blue:0.898f alpha:1.0f];
}
I tried to convert the above using the below lines of code to use for android
String colorString =
String.format("%s%s%s%s",
Integer.toString(Math.round((1.0f*255)), 16),
Integer.toString(Math.round((102.0f/255.0f*255)), 16),
Integer.toString(Math.round((255.0f/255.0f*255)), 16),
Integer.toString(Math.round((204.0f/255.0f*255)), 16));
I got the hexadecimal like this ff5394e4 . But i am getting very different color in android can anyone help me in this?.
IPhone Color:
Android Color
My first guess would be that you need to round the converted values instead of just casting to an int.
For example, for a number 6.5, rounding would get you 7, but casting to an int gets you 6. This may be the source of your problem.
I believe the java code to round a number is Math.round(int).

Android Locale.US code resetting to normal font when we need small

Edited:
A few days ago I posted a question on how to make the tablet look like Locale.US for everything from string conversions, numbers, editText input, etc. I was given this code to put in onCreate:
Locale.setDefault(Locale.US);
Configuration config = new Configuration();
config.locale = Locale.US;
getBaseContext().getResources().updateConfiguration(config,getBaseContext().getResources().getDisplayMetrics());
I found that the font scaling was working on some devices (Nexus-4) but was not working on other devices (Nexus-7, Nexus-S). My application needs to have font scaling to work across the range of devices so this was a big problem. I guessed that the problem was that the font scale factor was not being read for all devices so that when I wrote the new configuration, it would overwrite the font scaling on these devices. I found that this could be explicitly read and added two lines to read the font scaling and write it as part of my new configuration. This solved my problem before anyone commented here on SO but I thought someone else might have this problem so I am updating my question to this solution. the code added is this:
float scale = getResources().getConfiguration().fontScale;
config.fontScale = scale;

Categories

Resources