RubyMotion: how to display unicode character in Android? - android

How to display unicode character in TextView in Android using RubyMotion?
I tried
MainModule.get.setText('\u00d7')
MainModule.get.setText('0x00d7')
Where get is to get the TextView object.
But neither works, it still displays the original string(\u00d7 or 0x00d7).
Edit
I am using Ruby to write Android, not Java.

I get you a method that unicode to string, I hole that would be useful for you.
mTextView.setText(unicode2String("\\u00d7"));
...
public String unicode2String(String unicode) {
StringBuffer string = new StringBuffer();
String[] hex = unicode.split("\\\\u");
for (int i = 1; i < hex.length; i++) {
int data = Integer.parseInt(hex[i], 16);
string.append((char) data);
}
return string.toString();
}

Related

ReplaceAll not working

I'm using google volley to retrieve source code from website. Some looping was done to capture the value in the code. I've successfully captured the data I wanted, but error was shown: NumberFormatException: Invalid float: "2,459.00"
My intention was to store the value after the class=ListPrice>
Sample:
RM 2,899.00
The example value of the source code I wanted to save is "RM2,459.00 "
Below is the code I've written:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lazada_result);
lelongResult = (TextView) findViewById(R.id.lelong_result);
RequestQueue lelong = MyVolley.getRequestQueue(this);
StringRequest myLel = new StringRequest(
Method.GET,
"http://list.lelong.com.my/Auc/List/List.asp?DA=A&TheKeyword=iphone&x=0&y=0&CategoryID=&PriceLBound=&PriceUBound=",
RetrieveLelong(), createMyReqErrorListener());
lelong.add(myLel);
}
private Response.Listener<String> RetrieveLelong() {
return new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<Float> integers = new ArrayList<>();
String to = "class=ListPrice>";
String remainingText = response;
String showP = "";
while (remainingText.indexOf(to) >= 0) {
String tokenString = remainingText.substring(remainingText
.indexOf(to) + to.length());
String priceString = tokenString.substring(0,
tokenString.indexOf("<"));
float price = Float.parseFloat(priceString.replaceAll("[^\\d,]+", "").trim());
integers.add((price / 100));
remainingText = tokenString;
}
for (int i = 0; i < integers.size(); i++) {
String test1 = Float.toString(integers.get(i));
showP += test1 + "\n";
}
lelongResult.setText(showP);
}
};
}
The problem was as below:
I've tried all sort of replaceAll(),
1)replaceAll("[^\d,]+","") result:2,89900
replace all character except digits and comma works.
2)replaceAll("[^\d]+","") result:Invalid int""
replace all character include comma and dot ,not working
3)replaceAll("[^\d.]+,"") result:Invalid int""
replace all character exclude digits and dot, not working
From the experiment 2&3 coding above,I've noticed that if the comma were removed,i cant parseFloat as the value received by it is: "".NumberFormatException:Invalid Float:"" shown.
From the experiment 1,NumberFormatException:Invalid Float "2,45900" is showned.
The problem was replacing comma ,the code will not work but with the presence of comma ,the value cannot be stored into string
try this:
float price = Float.parseFloat(priceString.replaceAll("RM", "").trim());
use `replaceAll(Pattern.quote(","), "");
EDIT
if you want only numbers then use this
String s1= s.replaceAll("\D+","");
Try to parse the number by specifying the Locale.
NumberFormat format = NumberFormat.getInstance(Locale.KOREAN);
Number number = format.parse(priceString.replaceAll("RM", ""));
double d = number.doubleValue();
I'm just guessing the locale, don't know what you should use, depends on country
You need to do it one by one
priceString=priceString.replaceAll("\\D", "");
priceString=priceString.replaceAll("\\s", "");
now
priceString=priceString.trim();
float price = Float.parseFloat(priceString);
the problem is that in your code:
priceString.replaceAll(Pattern.quote(","), "");
float price = Float.parseFloat(priceString.replaceAll("\\D+\\s+", "").trim());
You are replacing coma but not storing the value!
you have to do:
priceString = priceString.replaceAll(",", "");
float price = Float.parseFloat(priceString.replaceAll("\\D+\\s+", "").trim());
I'm not sure of the pattern "\D+\s" because if you remove the coma you don't need to replace anything else (except "RM" that i assume you already removed)
Update: set locale and parse a number:
NumberFormat format = NumberFormat.getInstance(Locale.KOREAN);
Number number = format.parse(priceString.replaceAll("RM", ""));
double d = number.doubleValue();

Show source code in TextView correctly indented and parsed

Is it possible to parse HTML code in a verbatim mode or something similar so that the source code fragments that eventually may appear (enclosed between pre and code HTML tags) can be displayed properly?
What I want to do is show source code in a user-friendly mode (easy to distinguish from the rest of the text, keep indentation, etc.), as Stack Overflow does :)
It seems that Html.fromHtml() supports only a reduced subset of HTML tags.
TextView will never succeed supporting all the html formating and styling you would want it to. Use WebView instead.
TextView is native and more lightweight, but exactly because of its lightweightedness it will not understand some of the directives you describe.
Finally I preparsed by myself the HTML code received, since Html.fromHtml does not support the pre and code tags, y replaced them with my custom format and pre-parsed the code inside those tags replacing "\n" with <br/> and " " with .
Then I send the results to Html.fromHtml, and the result is just fine:
public class HtmlParser {
public static Spanned parse(String text) {
if (text == null) return null;
text = parseSourceCode(text);
Spanned textSpanned = Html.fromHtml(text);
return textSpanned;
}
private static String parseSourceCode(String text) {
if (text.indexOf(ORIGINAL_PATTERN_BEGIN) < 0) return text;
StringBuilder result = new StringBuilder();
int begin;
int end;
int beginIndexToProcess = 0;
while (text.indexOf(ORIGINAL_PATTERN_BEGIN) >= 0) {
begin = text.indexOf(ORIGINAL_PATTERN_BEGIN);
end = text.indexOf(ORIGINAL_PATTERN_END);
String code = parseCodeSegment(text, begin, end);
result.append(text.substring(beginIndexToProcess, begin));
result.append(PARSED_PATTERN_BEGIN);
result.append(code);
result.append(PARSED_PATTERN_END);
//replace in the original text to find the next appearance
text = text.replaceFirst(ORIGINAL_PATTERN_BEGIN, PARSED_PATTERN_BEGIN);
text = text.replaceFirst(ORIGINAL_PATTERN_END, PARSED_PATTERN_END);
//update the string index to process
beginIndexToProcess = text.lastIndexOf(PARSED_PATTERN_END) + PARSED_PATTERN_END.length();
}
//add the rest of the string
result.append(text.substring(beginIndexToProcess, text.length()));
return result.toString();
}
private static String parseCodeSegment(String text, int begin, int end) {
String code = text.substring(begin + ORIGINAL_PATTERN_BEGIN.length(), end);
code = code.replace(" ", " ");
code = code.replace("\n","<br/>");
return code;
}
private static final String ORIGINAL_PATTERN_BEGIN = "<pre><code>";
private static final String ORIGINAL_PATTERN_END = "</code></pre>";
private static final String PARSED_PATTERN_BEGIN = "<font color=\"#888888\"><tt>";
private static final String PARSED_PATTERN_END = "</tt></font>";
}

Getting a utf-8 encoded string from a database, then displaying in a webview

I am attempting to scoop some utf-8 encoded (Spanish text) data from a sqlite database and then display it in a webview. The essential parts of the code are as follows:
String web_data_string = cursor.getString(0);
webview.loadData(web_data_string, "text/html", "utf-8");
The string is a word containing all normal characters except one which should be a lower-case e+acute. In the webview all the normal characters appear correctly, but the e+acute appears as two characters, an A+tilde followed by a copyright symbol.
Where did I go wrong?
EDIT: +1 to dd619 for a solution that can be made to work, but I am hoping for a more general solution where there may be many more special characters, in other languages too.
This does the trick...
String web_data_string = cursor.getString(0);
webview.loadData(utf_eight_to_web(web_data_string), "text/html", "utf-8");
String utf_eight_to_web(String str)
{
String ans = "";
Character c;
for(int i = 0;i<str.length();i++)
{
c = str.charAt(i);
if (c <= 127)
{
ans += str.charAt(i);
}
else
{
ans += String.format("&#%d;",(int)c);
}
}
return ans;
}
If you have any special character/letter then you need to replace it with respective escape character sequence.
Have a look at this useful link.
I had the same problem with some Spanish characters e.g.á and i solved it by replacing á with \u00e1
e.g. if you want to print "Parámetros" then simply do.
String str="Parámetros";
str=str.replace("á","\u00e1");
Log.i("MyClass",str);
Now you can str in database or java or in C++ or any web platform!
The Mick's answer could be improved using StringBuilder:
private String utfEightToWeb(String str)
{
StringBuilder stringBuilder = new StringBuilder();
Character c;
for (int i = 0; i<str.length(); i++) {
c = str.charAt(i);
if (c <= 127) {
stringBuilder.append(str.charAt(i));
} else {
stringBuilder.append(String.format("&#%d;",(int)c));
}
}
return stringBuilder.toString();
}

How to convert a string to character by character in Android?

I have Edittext field that the user can enter their name. I want to check it with alphabets for how many times a letter comes.
Which is the best way to do this?
I tried the below code for getting each character from the string but error occurring? I appreciate it if any one can help.
name=(EditText)findViewById(gami.Numerology.R.id.inputUI);
String a=name.getText().toString();
for ( int i = 0; i < a.length(); i++ )
{
c = a.charAt(i);
if (c=='s')
{
s=1; //like this for all characters
}
}
I just put this in a click event of button.
//declare the original String object
String strOrig = "Hello World";
//declare the char array
char[] stringArray;
//convert string into array using toCharArray() method of string class
stringArray = strOrig.toCharArray();
//display the array
for(int index=0; index < stringArray.length; index++)
//check of character appearance
You can use a hashmap or some sort of dictionary in Java.
Rough example since I don't know how to use Hashmap in Java:
HashMap<Character, Integer> counter = new HashMap<Character, Integer>();
for (Character c: name)
{
counter.put(c, counter.get(c) == null ? 1 : counter.get(c)++);
}

Anything better than JSoup for Android?

What I want to do...
I have a webview in my android app. I get a huge html content from the server as a string and a search string from the application user(the android phone user). Now I break the search string and create a regex out of it. I want all the html content that matches my regex to be highlighted when I display it into my WebView.
What I tried...
Since it is html, I just want to wrap the regex matched words into a pair of tags with yellow background.
Simple regex and replaceAll on the html Content that i get. Very wrong because it screws and replaces even what is inside the '<' and '>'.
I tried using Matcher and Pattern combo. It is difficult to omit what is inside the tags.
I used JSOUP Parser and it worked!
I traverse the html using NodeTraversor class. I used Matcher and Pattern classes to find and replace matched words with tags as i wanted to do.
But it is very slow. And I basically want to use it on Android and the size of it is like 284kB. I removed some unwanted classes and it is now 201kB but it is still too much for an android device. Additionally, the html content can be really large. I looked into JSoup source as well. It kind of iterates over every single character when it parses. I do not know whether all the parsers do the same but it is definitely slow for large html documents.
Here is my code -
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Highlighter {
private String regex;
private String htmlContent;
Pattern pat;
Matcher mat;
public Highlighter(String searchString, String htmlString) {
regex = buildRegexFromQuery(searchString);
htmlContent = htmlString;
pat = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
}
public String getHighlightedHtml() {
Document doc = Jsoup.parse(htmlContent);
final List<TextNode> nodesToChange = new ArrayList<TextNode>();
NodeTraversor nd = new NodeTraversor(new NodeVisitor() {
#Override
public void tail(Node node, int depth) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
String text = textNode.getWholeText();
mat = pat.matcher(text);
if(mat.find()) {
nodesToChange.add(textNode);
}
}
}
#Override
public void head(Node node, int depth) {
}
});
nd.traverse(doc.body());
for (TextNode textNode : nodesToChange) {
Node newNode = buildElementForText(textNode);
textNode.replaceWith(newNode);
}
return doc.toString();
}
private static String buildRegexFromQuery(String queryString) {
String regex = "";
String queryToConvert = queryString;
/* Clean up query */
queryToConvert = queryToConvert.replaceAll("[\\p{Punct}]*", " ");
queryToConvert = queryToConvert.replaceAll("[\\s]*", " ");
String[] regexArray = queryString.split(" ");
regex = "(";
for(int i = 0; i < regexArray.length - 1; i++) {
String item = regexArray[i];
regex += "(\\b)" + item + "(\\b)|";
}
regex += "(\\b)" + regexArray[regexArray.length - 1] + "[a-zA-Z0-9]*?(\\b))";
return regex;
}
private Node buildElementForText(TextNode textNode) {
String text = textNode.getWholeText().trim();
ArrayList<MatchedWord> matchedWordSet = new ArrayList<MatchedWord>();
mat = pat.matcher(text);
while(mat.find()) {
matchedWordSet.add(new MatchedWord(mat.start(), mat.end()));
}
StringBuffer newText = new StringBuffer(text);
for(int i = matchedWordSet.size() - 1; i >= 0; i-- ) {
String wordToReplace = newText.substring(matchedWordSet.get(i).start, matchedWordSet.get(i).end);
wordToReplace = "<b>" + wordToReplace+ "</b>";
newText = newText.replace(matchedWordSet.get(i).start, matchedWordSet.get(i).end, wordToReplace);
}
return new DataNode(newText.toString(), textNode.baseUri());
}
class MatchedWord {
public int start;
public int end;
public MatchedWord(int start, int end) {
this.start = start;
this.end = end;
}
}
}
Here is how I call it -
htmlString = getHtmlFromServer();
Highlighter hl = new Highlighter("Hello World!", htmlString);
new htmlString = hl.getHighlightedHTML();
I am sure what i'm doing is not the most optimal way. But I can't seem to think of anything else.
I want to
- reduce the time it takes to highlight it.
- reduce the size of library
Any suggestions?
How about highlighting them using javascript?
You know, everybody love javascript, and you can find example like this blog.
JTidy and HTMLCleaner are aloso among the best Java HTML Parser.
see
Comparison between different Java HTML Parser
and
What are the pros and cons of the leading Java HTML parsers?

Categories

Resources