Android: Test if a character is displayable/supported? - android

I am using Asian characters in my android app, I learned already that some characters are not displayable because they are not supported by the system's fonts. I query a database with Asian characters and I often retrieve signs which are not displayable. These cases are usually not a problem for my application, but are irritating to the user if I display not supported characters.
Is there something like a test of a sign for displayability in Android?

This will be helpful
public boolean isPrintable( char c ) {
Character.UnicodeBlock block = Character.UnicodeBlock.of( c );
return (!Character.isISOControl(c)) &&
block != null &&
block != Character.UnicodeBlock.SPECIALS;
}
Please refer printable char in java

Related

Convert country code 2 letter to 3 letter in Objective-C

I'm working on a function that gets the country code from the phone, but when I get the country code it consists of 2 letters, but I want it to return three letters.
For example US -> USA
In Android, java supports converting from 2 characters to 3 characters with the following code:
Locale locale = new Locale("en", countryCode);
return locale.getISO3Country();
But in iOS with Objective-C I don't know how to convert it, so can anyone help me to solve this problem?
for the sake of standardisation there is no ISO 3166-1 alpha-3 code on apple platforms to convert to. More the other way around, you could use a 3 letter code and still find the 2 letter code.
and if you want to keep at least some consistency to your android code then you need to implement some LUT table supporting this off-standard feature yourself. The available list is not very long anyway (256 codes).
NSArray *isoCountrys = [NSLocale ISOCountryCodes];
for (NSString *code in isoCountrys) {
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:code];
// country name in native language
NSString *country = [locale localizedStringForCountryCode:code];
NSString *iso3 = LUTisoA3counterpartCodes[code];
NSLog(#"%# %# %# %#",code, iso3, country, locale.localeIdentifier);
}
Docu NSLocale -localizedStringForCountryCode:
Docu NSLocale -countryCode
the LUT could look like.. and is much better stored in a plist then the following runtime allocated dictionary.
NSDictionary *LUTisoA3counterpartCodes = #{
#"AC":#"SHN",#"AW":#"ABW",#"AF":#"AFG",#"AO":#"AGO",#"AI":#"AIA",#"AX":#"ALA",
#"AL":#"ALB",#"AD":#"AND",#"AE":#"ARE",#"AR":#"ARG",#"AM":#"ARM",#"AS":#"ASM",
#"AQ":#"ATA",#"TF":#"ATF",#"AG":#"ATG",#"AU":#"AUS",#"AT":#"AUT",#"AZ":#"AZE",
#"BI":#"BDI",#"BE":#"BEL",#"BJ":#"BEN",#"BQ":#"BES",#"BF":#"BFA",#"BD":#"BGD",
#"BG":#"BGR",#"BH":#"BHR",#"BS":#"BHS",#"BA":#"BIH",#"BL":#"BLM",#"BY":#"BLR",
#"BZ":#"BLZ",#"BM":#"BMU",#"BO":#"BOL",#"BR":#"BRA",#"BB":#"BRB",#"BN":#"BRN",
#"BT":#"BTN",#"BV":#"BVT",#"BW":#"BWA",#"CF":#"CAF",#"CA":#"CAN",#"CC":#"CCK",
#"CH":#"CHE",#"CL":#"CHL",#"CN":#"CHN",#"CI":#"CIV",#"CM":#"CMR",#"CD":#"COD",
#"CG":#"COG",#"CK":#"COK",#"CO":#"COL",#"KM":#"COM",#"CV":#"CPV",#"CR":#"CRI",
#"CU":#"CUB",#"CW":#"CUW",#"CX":#"CXR",#"KY":#"CYM",#"CY":#"CYP",#"CZ":#"CZE",
#"DE":#"DEU",#"DJ":#"DJI",#"DM":#"DMA",#"DK":#"DNK",#"DO":#"DOM",#"DZ":#"DZA",
#"EC":#"ECU",#"EG":#"EGY",#"ER":#"ERI",#"EH":#"ESH",#"ES":#"ESP",#"EE":#"EST",
#"ET":#"ETH",#"FI":#"FIN",#"FJ":#"FJI",#"FK":#"FLK",#"FR":#"FRA",#"FO":#"FRO",
#"FM":#"FSM",#"GA":#"GAB",#"GB":#"GBR",#"GE":#"GEO",#"GG":#"GGY",#"GH":#"GHA",
#"GI":#"GIB",#"GN":#"GIN",#"GP":#"GLP",#"GM":#"GMB",#"GW":#"GNB",#"GQ":#"GNQ",
#"GR":#"GRC",#"GD":#"GRD",#"GL":#"GRL",#"GT":#"GTM",#"GF":#"GUF",#"GU":#"GUM",
#"GY":#"GUY",#"HK":#"HKG",#"HM":#"HMD",#"HN":#"HND",#"HR":#"HRV",#"HT":#"HTI",
#"HU":#"HUN",#"ID":#"IDN",#"IM":#"IMN",#"IN":#"IND",#"IO":#"IOT",#"IE":#"IRL",
#"IR":#"IRN",#"IQ":#"IRQ",#"IS":#"ISL",#"IL":#"ISR",#"IT":#"ITA",#"JM":#"JAM",
#"JE":#"JEY",#"JO":#"JOR",#"JP":#"JPN",#"KZ":#"KAZ",#"KE":#"KEN",#"KG":#"KGZ",
#"KH":#"KHM",#"KI":#"KIR",#"KN":#"KNA",#"KR":#"KOR",#"KW":#"KWT",#"LA":#"LAO",
#"LB":#"LBN",#"LR":#"LBR",#"LY":#"LBY",#"LC":#"LCA",#"LI":#"LIE",#"LK":#"LKA",
#"LS":#"LSO",#"LT":#"LTU",#"LU":#"LUX",#"LV":#"LVA",#"MO":#"MAC",#"MF":#"MAF",
#"MA":#"MAR",#"MC":#"MCO",#"MD":#"MDA",#"MG":#"MDG",#"MV":#"MDV",#"MX":#"MEX",
#"MH":#"MHL",#"MK":#"MKD",#"ML":#"MLI",#"MT":#"MLT",#"MM":#"MMR",#"ME":#"MNE",
#"MN":#"MNG",#"MP":#"MNP",#"MZ":#"MOZ",#"MR":#"MRT",#"MS":#"MSR",#"MQ":#"MTQ",
#"MU":#"MUS",#"MW":#"MWI",#"MY":#"MYS",#"YT":#"MYT",#"NA":#"NAM",#"NC":#"NCL",
#"NE":#"NER",#"NF":#"NFK",#"NG":#"NGA",#"NI":#"NIC",#"NU":#"NIU",#"NL":#"NLD",
#"NO":#"NOR",#"NP":#"NPL",#"NR":#"NRU",#"NZ":#"NZL",#"OM":#"OMN",#"PK":#"PAK",
#"PA":#"PAN",#"PN":#"PCN",#"PE":#"PER",#"PH":#"PHL",#"PW":#"PLW",#"PG":#"PNG",
#"PL":#"POL",#"PR":#"PRI",#"KP":#"PRK",#"PT":#"PRT",#"PY":#"PRY",#"PS":#"PSE",
#"PF":#"PYF",#"QA":#"QAT",#"RE":#"REU",#"RO":#"ROU",#"RU":#"RUS",#"RW":#"RWA",
#"SA":#"SAU",#"SD":#"SDN",#"SN":#"SEN",#"SG":#"SGP",#"GS":#"SGS",#"SH":#"SHN",
#"SJ":#"SJM",#"SB":#"SLB",#"SL":#"SLE",#"SV":#"SLV",#"SM":#"SMR",#"SO":#"SOM",
#"PM":#"SPM",#"RS":#"SRB",#"SS":#"SSD",#"ST":#"STP",#"SR":#"SUR",#"SK":#"SVK",
#"SI":#"SVN",#"SE":#"SWE",#"SZ":#"SWZ",#"SX":#"SXM",#"SC":#"SYC",#"SY":#"SYR",
#"TC":#"TCA",#"TD":#"TCD",#"TG":#"TGO",#"TH":#"THA",#"TJ":#"TJK",#"TK":#"TKL",
#"TM":#"TKM",#"TL":#"TLS",#"TO":#"TON",#"TT":#"TTO",#"TN":#"TUN",#"TR":#"TUR",
#"TV":#"TUV",#"TW":#"TWN",#"TZ":#"TZA",#"UG":#"UGA",#"UA":#"UKR",#"UM":#"UMI",
#"UY":#"URY",#"US":#"USA",#"UZ":#"UZB",#"VA":#"VAT",#"VC":#"VCT",#"VE":#"VEN",
#"VG":#"VGB",#"VI":#"VIR",#"VN":#"VNM",#"VU":#"VUT",#"WF":#"WLF",#"WS":#"WSM",
#"XK":#"XKV",#"YE":#"YEM",#"ZA":#"ZAF",#"ZM":#"ZMB",#"ZW":#"ZWE",
//unknown status or codes, to be changed soon
#"DG":#"DGA" , //Diego Garcia
#"EA":#"EA_" , //Ceuta and Melilla
#"CP":#"CPT" , //Clipperton Island -> French Polynesia
#"IC":#"IC_" , //Kanarian Island
#"TA":#"TAA" , //டிரிஸ்டன் டா குன்ஹா , Tristan da Cunha -> St.Helena
};
this LUT makes it easy to lookup by 2 letter code and get the 3 letter codes. And in reality the list is much longer and matter of permanent changes.
and if you trust the sorting of Apples API you could just use a static NSArray instead of a plist or NSDictionary. The following prints it for use..
int i=1;
fprintf(stderr,"\nstatic NSString *isoA3accordingToAppleSorting[256] = {\n");
for (NSString *code in isoCountrys) {
if (i%20 == 19) fprintf(stderr,"\n");
NSString *iso3 = LUTisoA3counterpartCodes[code];
fprintf(stderr,"#\"%s\",",iso3.UTF8String);
i++;
}
fprintf(stderr,"};\n");
which looks like..
static NSString *countryCodeAsA3accordingToAppleSorting[256] = {
#"SHN",#"AND",#"ARE",#"AFG",#"ATG",#"AIA",#"ALB",#"ARM",#"AGO",#"ATA",#"ARG",#"ASM",#"AUT",#"AUS",#"ABW",#"ALA",#"AZE",#"BIH",
#"BRB",#"BGD",#"BEL",#"BFA",#"BGR",#"BHR",#"BDI",#"BEN",#"BLM",#"BMU",#"BRN",#"BOL",#"BES",#"BRA",#"BHS",#"BTN",#"BVT",#"BWA",#"BLR",#"BLZ",
#"CAN",#"CCK",#"COD",#"CAF",#"COG",#"CHE",#"CIV",#"COK",#"CHL",#"CMR",#"CHN",#"COL",#"CPT",#"CRI",#"CUB",#"CPV",#"CUW",#"CXR",#"CYP",#"CZE",
#"DEU",#"DGA",#"DJI",#"DNK",#"DMA",#"DOM",#"DZA",#"EA_",#"ECU",#"EST",#"EGY",#"ESH",#"ERI",#"ESP",#"ETH",#"FIN",#"FJI",#"FLK",#"FSM",#"FRO",
#"FRA",#"GAB",#"GBR",#"GRD",#"GEO",#"GUF",#"GGY",#"GHA",#"GIB",#"GRL",#"GMB",#"GIN",#"GLP",#"GNQ",#"GRC",#"SGS",#"GTM",#"GUM",#"GNB",#"GUY",
#"HKG",#"HMD",#"HND",#"HRV",#"HTI",#"HUN",#"IC_",#"IDN",#"IRL",#"ISR",#"IMN",#"IND",#"IOT",#"IRQ",#"IRN",#"ISL",#"ITA",#"JEY",#"JAM",#"JOR",
#"JPN",#"KEN",#"KGZ",#"KHM",#"KIR",#"COM",#"KNA",#"PRK",#"KOR",#"KWT",#"CYM",#"KAZ",#"LAO",#"LBN",#"LCA",#"LIE",#"LKA",#"LBR",#"LSO",#"LTU",
#"LUX",#"LVA",#"LBY",#"MAR",#"MCO",#"MDA",#"MNE",#"MAF",#"MDG",#"MHL",#"MKD",#"MLI",#"MMR",#"MNG",#"MAC",#"MNP",#"MTQ",#"MRT",#"MSR",#"MLT",
#"MUS",#"MDV",#"MWI",#"MEX",#"MYS",#"MOZ",#"NAM",#"NCL",#"NER",#"NFK",#"NGA",#"NIC",#"NLD",#"NOR",#"NPL",#"NRU",#"NIU",#"NZL",#"OMN",#"PAN",
#"PER",#"PYF",#"PNG",#"PHL",#"PAK",#"POL",#"SPM",#"PCN",#"PRI",#"PSE",#"PRT",#"PLW",#"PRY",#"QAT",#"REU",#"ROU",#"SRB",#"RUS",#"RWA",#"SAU",
#"SLB",#"SYC",#"SDN",#"SWE",#"SGP",#"SHN",#"SVN",#"SJM",#"SVK",#"SLE",#"SMR",#"SEN",#"SOM",#"SUR",#"SSD",#"STP",#"SLV",#"SXM",#"SYR",#"SWZ",
#"TAA",#"TCA",#"TCD",#"ATF",#"TGO",#"THA",#"TJK",#"TKL",#"TLS",#"TKM",#"TUN",#"TON",#"TUR",#"TTO",#"TUV",#"TWN",#"TZA",#"UKR",#"UGA",#"UMI",
#"USA",#"URY",#"UZB",#"VAT",#"VCT",#"VEN",#"VGB",#"VIR",#"VNM",#"VUT",#"WLF",#"WSM",#"XKV",#"YEM",#"MYT",#"ZAF",#"ZMB",#"ZWE",};
but then you have to find the index of your 2 letter code in apples ISOCountryCodes to look them up accordingly.
Reminder. The ISO 3166-1 alpha-3 explains only that it should have 3 letters, not which letter exactly

How to check for illegal characters on swift. (Illegal characters for Windows, Android & IOS)

I'm making a special file saving system for IOS and possibly mac.
My program will basically allow the user to write the name of the file, but before I do that I need to check for illegal characters that exist for IOS, Windows, and Android since they will all be probably be passed into another system via the user's own decision (Like through email or USB for example).
In general if you try to bring any file with an illegal "name" into another system, the file will either become corrupted or not be passed into the system at all.
The problem is with my code is that it ONLY works if there is ONE character in the string in total. If the former situation, the regex checker doesn't detect anything regardless of where or how many illegal characters are there.
This is my code.
//Validates the string for illegal file name characters
//https://stackoverflow.com/questions/14635391/java-function-to-return-if-string-contains-illegal-characters
func hasIllegalCharacters(locationNameString: String) -> Bool{
//do {
//Pattern pattern = Pattern.compile("[\\\\/:*?\"<>|]");
let illegalRegEx = "[~##*+%{}<>\\[\\]|\"\\_^]"
//let ipAddressRegEx = "|\\?*<\":>+[]/'"
let trimmedString = locationNameString.trimmingCharacters(in: .whitespaces)
let validateName = NSPredicate(format:"SELF MATCHES %#", illegalRegEx)
let isIllegal = validateName.evaluate(with: trimmedString)
if(isIllegal){
print("has illegal chars")
}
else{
print("no illegal detected")
}
return isIllegal
}
extension String {
var containsSpecialCharacter: Bool {
let regex = ".*[^A-Za-z0-9].*"
let testString = NSPredicate(format:"SELF MATCHES %#", regex)
return testString.evaluate(with: self)
}
}
Regex makes lists all non illegal characters and then testString tests if the if the string matches with the characters in regex. It will return True or False

Regular expression to match all phone numbers

I have tried matching Phone numbers with the regular expressions provided by Android in Patterns.Phone,this matches a lot of things that are not phone numbers.I have also tried using:
(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?
However,I found that the Test was not successfull for all the inputs.I would like to validate the following inputs using a regular expression:
67450450
+9144-27444444
27444444
27470570
+12142261347
+61406366180
0891 2577456
2577456
+91 9550461668
9550461668
03-1234567
1860 425 3330
Basically any nymber format supported here:WTND
you can use the following code to check phone #:
private boolean validPhone(String phone) {
Pattern pattern = Patterns.PHONE;
return pattern.matcher(phone).matches();
}
if(validPhone("67450450")){
Toast.makeText(this,"The phone number is valid");
}
else
{
Toast.makeText(this,"The phone number is not valid");
}
This isn't clean/efficient, just thrown together to match your sample data:
\b\d{7,10}|\+\d{4}-\d{8}|\+\d{11}|\d{4}\s\d{7}|\+\d{2}\s\d{10}|\d{2}-\d{7}|\d{4}\s\d{3}\s\d{4}\b

Jelly Bean Issue - wifiManager.getConnectionInfo().getSSID() - extra ""

Hi all bug reporting for your information. link
Problem details:
The Code - wifiManager.getConnectionInfo().getSSID()
The above code to returns the current SSID, it is returning the current SSID with extra quotations around it.
For eg. the SSID internet is returned as "internet".
This is only seen on Jelly bean 4.2 using device Nexus 7.
This bug is causing errors in our app as we compare the current SSID with the SSID that we are trying to connect too.
The code wifiManager.getScanResults(); however still returns all SSID's without extra quotation marks.
this is not a bug and behavior is correct as per documentation at http://developer.android.com/reference/android/net/wifi/WifiInfo.html#getSSID()
The so-called bug apparently was in pre 4.2 devices, because they didn't return it with "" enclosure.
Aiden's method looks good to me in the current state of confusion left by Android. However, being theoritically correct would just require
if (ssid.startsWith("\"") && ssid.endsWith("\"")){
ssid = ssid.substring(1, ssid.length()-1);
}
This regular expression is quite neat:
String ssid = wi.getSSID().replaceAll("^\"(.*)\"$", "$1");
Just for the notes
Edit °1 (as per question in the comment):
The issue that OP describes is, that on some devices the SSID returned by getSSID() is enclosed in "" whereas it is not on other devices. E.g. on some devices the SSID is "MY_WIFI" and on others it is MY_WIFI - or spoken in Java code: "\"MY_WIFI\"" and "MY_WIFI".
In order to to unify both results I proposed to remove the " at start and end - only there, because " is a legal character inside the SSID. In the regular expression above
^ means from start
$ means at end
\" means " (escaped)
.* means any number of characters
(...) means a capturing group, that can be referred by $1
So the whole expression means: replace "<something>" by <something> where $1 = <something>.
If there is no " at end/start, the regular expression doesn't match and nothing is replaced.
See Java Pattern class for more details.
For the mean time this is how I am getting around it, although its not great it will fix the issue.
public String removeQuotationsInCurrentSSIDForJellyBean(String ssid){
int deviceVersion= Build.VERSION.SDK_INT;
if (deviceVersion >= 17){
if (ssid.startsWith("\"") && ssid.endsWith("\"")){
ssid = ssid.substring(1, ssid.length()-1);
}
}
return ssid;
}
Two very simple variants:
string = string.replaceAll("^\" | \"$", "");
and
string = string.substring(1, string.length() - 1);
Faced the same problem! Used this technique which is backwards compatible:
if (suppliedSSID.equals(connectionInfo.getSSID()) || ("\"" + suppliedSSID + "\"").equals(connectionInfo.getSSID()) { DO SOMETHING }

JDOM Throwing Parse Exceptions with bad ascii characters

I'm using JDOM with my Android project, and every time I get a certain set of characters in my server response, I end up with these error messages:
05-04 10:08:46.277: E/PARSE: org.jdom.input.JDOMParseException: Error on line 95 of document UTF-8: At line 95, column 5263: unclosed token
05-04 10:08:46.277: E/Error Handler: Handler failed: org.jdom.input.JDOMParseException: Error on line 1: At line 1, column 0: syntax error
When I make the same query through google chrome, I can see that all of the XML came through fine, and that there are in fact no areas where a token is not closed. I have run into this problem several times throughout the development of the application, and the solution has always been to remove odd ascii characters (copyright logos, or trademark characters, etc. that got copied/pasted into those data fields). How can I get it to either a remove those characters, or b strip them and continue the function. Here's an example of one of my parse functions.
public static boolean parseUserData(BufferedReader br) {
SAXBuilder builder = new SAXBuilder();
Document document = null;
try {
document = builder.build(br);
/* XML Output to Logcat */
if (document != null) {
XMLOutputter outputter = new XMLOutputter(
Format.getPrettyFormat());
String xmlString = outputter.outputString(document);
Log.e("XML", xmlString);
}
Element rootNode = document.getRootElement();
if (!rootNode.getChildren().isEmpty()) {
// Do stuff
return true;
}
} catch (Exception e) {
GlobalsUtil.errorUtil
.setErrorMessage("Error Parsing XML: User Data");
Log.e(DEBUG_TAG, e.toString());
return false;
}
}
It distinctly sounds like a character encoding issue. I think duffymo is correct in his assessment. I have two comments though ....
If you are getting your data through a URL you should be using the URLConnection.getContentType() to get the charset (if it is set and the charset is not null) to set up the InputStreamReader on the URL's InputStream...
Have you tried JDOM 2.0.1? It is the first JDOM version that is fully tested on Android... (and the only 'supported' JDOM version on Android). JDOM 2.0.1 also has a number of performance tweaks, and memory optimizations that should make your processing faster. It also fixes a number of bugs.... though from what I see you should not run in to any bug problems.....
Check out https://github.com/hunterhacker/jdom/wiki/JDOM2-Migration-Issues and https://github.com/hunterhacker/jdom/wiki/JDOM2-and-Android
Is the BufferedReader constructed to take the encoding argument? Perhaps you need to tell the Reader or InputStream that you pass to use UTF-8.

Categories

Resources