Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DFUA: Developing for the Rest of the World

DFUA: Developing for the Rest of the World

Many businesses are looking for growth outside the United States and Europe. To capture these new markets dedicated engineering effort will be required. This talk will provide tips for developing apps intended for an international audience.

Eric Frohnhoefer

October 13, 2017
Tweet

More Decks by Eric Frohnhoefer

Other Decks in Technology

Transcript

  1. Market size and opportunity Local pricing and financial factors Competitive

    landscape Identify target languages and locales Localization Checklist — Google
  2. Spending by Hispanic and Asian households US Chinese speakers (mainly

    Cantonese and Mandarin) US Spanish speakers 37.5 2.8 2.1 Trillion Million Million Language Use — US Census Bureau Audience - United States
  3. Move all strings into strings.xml Mark message parts that should

    not be translated Provide sufficient context for declared strings String localization Localization Checklist — Google
  4. Move all strings into strings.xml <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- A explanation

    of how something works. Max 30 characters --> <string name="app_name">demonstration</string> <!-- Random lorem ipsum text --> <string name="lorem_ipsum">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</string> <!-- Stuff that should not be translated --> <string name="is_rtl" translatable="false"> isRTL():<xliff:g id="result" example="true">%1$b</xliff:g> </string> <string name="gravity" translatable="false"> gravity():<xliff:g id="left" example="true">%1$s</xliff:g> </string> </resources>
  5. Move all strings into strings.xml <resources> <string name="app_name">ﻞﯿﺜﻤﺗ</string> <string name="lorem_ipsum">ﺔﻄﻘﻧ

    ّﻢﻟ ﻊﻣ ,ﺔﻟوﺎﺤﻣو داﺪﻣﻹا رﺎﻌﺷو ﻚﻠﺗ ٣٠ .هﺪﯾوﺰﺗو ﺔﻄﻘﻨﻛ</string> </resources>
  6. Provide context for declared strings • Is the meaning ambiguous?

    • The word “demonstration” is a homonym. • “A practical exhibition and explanation of how something works.” • “A public meeting or march protesting against something.” <!-- A explanation of how something works. Max 30 characters --> <string name="app_name">demonstration</string>
  7. Provide context for declared strings • Where is the string

    displayed? • App launcher • Action bar • Hint text • Section heading • Button <!-- A explanation of how something works. Max 30 characters --> <string name="app_name">demonstration</string>
  8. Provide context for declared strings • What are the layout

    constrains? • Buttons are usually more space constrained • Application name limited to 30 characters • Text limited to single line <!-- A explanation of how something works. Max 30 characters --> <string name="app_name">demonstration</string>
  9. Mark parts that should not be translated • Strings that

    should not be localized • Brand name like Twitter • Certain proper names • Placeholders • Special Unicode characters • Urls • Code <string name="is_rtl" translatable="false"> isRTL():<xliff:g id="result" example="true">%1$b</xliff:g> </string>
  10. System provided formats - Date Date • Accepts Unicode date

    format pattern. • Order is irrelevant. “MM/dd/yyyy” will return “dd.MM.yyyy” in Locale ukr_ua. SimpleDateFormat getBestDateTimePattern(Locale locale, String dateFormat) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { final String fmt = DateFormat.getBestDateTimePattern(locale, dateFormat); return new SimpleDateFormat(fmt, locale); } else { return new SimpleDateFormat(dateFormat, locale); } }
  11. System provided formats - Date format = getBestDateTimePattern(Locale.US, "MMddyyyy"); Log.i("Date",

    "US=" + format.format(date)); // US=10/17/2017 format = getBestDateTimePattern(Locale.FRANCE, "MMddyyyy"); Log.i("Date", "FR=" + format.format(date)); // FR=17/10/2017 format = getBestDateTimePattern(Locale.JAPAN, "MMddyyyy"); Log.i("Date", "JP=" + format.format(date)); // JP=2017/10/17 format = getBestDateTimePattern(new Locale("ukr", "ua"), "MMddyyyy"); Log.i("Date", "UA=" + format.format(date)); // UA=17.10.2017
  12. System provided formats - Decimal Date decimal = NumberFormat.getInstance(Locale.US); Log.i("Decimal",

    "US=" + decimal.format(1822.22)); // US=1,822.22 decimal = NumberFormat.getInstance(Locale.FRANCE); Log.i("Decimal", "FR=" + decimal.format(1822.22)); // FR=1 822,22 decimal = NumberFormat.getInstance(Locale.JAPAN); Log.i("Decimal", "JP=" + decimal.format(1822.22)); // JP=1,822.22 decimal = NumberFormat.getInstance(new Locale("ukr", "ua")); Log.i("Decimal", "UA=" + decimal.format(1822.22)); // UA=1 822,22
  13. System provided formats - Currency Date currency = NumberFormat.getCurrencyInstance(Locale.US); Log.i("Currency",

    "US=" + currency.format(1822.22)); // US=$1,822.22 currency = NumberFormat.getCurrencyInstance(Locale.FRANCE); Log.i("Currency", "FR=" + currency.format(1822.22)); // FR=1 822,22 € currency = NumberFormat.getCurrencyInstance(Locale.JAPAN); Log.i("Currency", "JP=" + currency.format(1822.22)); // JP=¥1,822 currency = NumberFormat.getCurrencyInstance(new Locale("ukr", "ua")); Log.i("Currency", "UA=" + currency.format(1822.22)); // UA=822,22 грн.
  14. System provided formats - Phone Date phone = PhoneNumberUtils.formatNumber("5551231234", Locale.US.getCountry());

    Log.i("Phone", "US=" + phone); // US=(555) 123-1234 phone = PhoneNumberUtils.formatNumber("765454545", Locale.FRANCE.getCountry()); Log.i("Phone", "FR=" + phone); // FR=7 65 45 45 45 phone = PhoneNumberUtils.formatNumber("7911123456", Locale.UK.getCountry()); Log.i("Phone", "UK=" + phone); // UK=7911 123456 phone = PhoneNumberUtils.formatNumber("+380893239961", "UA"); Log.i("Phone", "UA=" + phone); // UA=89 323 9961
  15. System provided formats - Sorting Date final List<String> stuff =

    Arrays.asList("abc", "ABC", "CBA"); Collections.sort(stuff, String.CASE_INSENSITIVE_ORDER);
  16. System provided formats - Sorting Date final List<String> stuff =

    Arrays.asList("abc", "ABC", "CBA"); Collections.sort(stuff, String.CASE_INSENSITIVE_ORDER);
  17. System provided formats - Sorting Date final Collator collator =

    Collator.getInstance(Locale.US); collator.setStrength(Collator.PRIMARY); if (collator.compare("ABC", "abc") < 0) { Log.i("Collator", "Strings are equal"); }
  18. Other considerations Date • Machine to machine interactions • Units

    of measure • Some domains have specific conventions that don’t match locale
  19. New APIs • Android now provides a subset of the

    ICU4J API. • android.icu.lang.UCharacter • android.icu.text.BreakIterator • android.icu.text.DecimalFormat • android.icu.util.Calendar • android.icu.text.Bidi • android.icu.text.DateFormat • android.icu.text.RelativeDateTi meFormatter • By creating multiple APKs using product flavors one could remove ICU files from 24+ APK.
  20. Web content in Arabic Phones shipped with Android in Middle

    East Arabic Internet Users 160 80 0.8 Percent Percent Million Number of Internet Users by Language — Internet World Stats Audience - Arabic Speakers Usage of content languages of websites — W3Techs Middle East and Africa Smartphone Market — IDC
  21. RTL Support 4.1 • Bi-directional support for TextView and EditText

    elements. 4.2 • RTL layout mirroring. • Improved fonts for international users. 4.3 • Improved Bi-directional support to handle mixed direction text.
  22. ViewPager • No support for RTL • Long standing request

    for support by community • https://code.google.com/p/android/ issues/detail?id=56831 • Other developers have created their own solutions • https://github.com/duolingo/rtl- viewpager
  23. RTL Support Script types • English and English-like (Latin, Greek,

    and Cyrillic) • Dense (Chinese, Japanese, and Korean) • Tall (South and Southeast Asian and Middle Eastern languages) Material Design • English: Regular 14sp • Dense: Regular 15sp • Tall: Regular 15sp Material Design — Google
  24. Set up a test environment Review with native- language speakers

    Look for common localization issues Testing localization Localization Checklist — Google
  25. Common Issues •Clipped text, or text that overlaps the edge

    of UI elements or the screen •Poor line wrapping •Incorrect word breaks or punctuation •Incorrect alphabetical sorting •Incorrect layout direction or text direction •Untranslated text
  26. Force RTL • Easier to debug RTL layout issues without

    switching to RTL language. • Found under Settings -> Developer Options -> Force RTL layout direction
  27. Generate localized screenshots of your Android app Upload screenshots, metadata,

    and your app to the Play Store screengrab supply https://github.com/fastlane/fastlane/tree/master/screengrab https://github.com/fastlane/fastlane/tree/master/supply
  28. Paypal market share in Middle East Unbanked Credit-card penetration 2

    82 5 Percent Percent Percent PayPal, Others Still Bet on Middle East E-Commerce — WSJ Audience - Middle East
  29. Payment gateways PayPal • Available in all countries • Limited

    penetration • Usually linked to Credit Card or Bank Account Stripe • Not Available in Middle East
  30. Payment gateways Carrier billing • Billed to wireless account •

    Carrier charges a processing fee • Typically only used for digital goods Prepaid • Popular for young adults and those without credit • Value can be added at retail locations • Usually a fee associated with adding value to card or processing payment
  31. Payment gateways TPay.me • Direct carrier billing provider • Charged

    to phone bill Cash U • Prepaid card accepted by online retailers • Available in the Middle East and North Africa • Users load cards at physical retail locations • Commonly used for games and VOIP
  32. Data used by 3G subscribers in India per month 4G

    subscribers in India Wireless subscribers in India 300 1 800 MB Million Million Telecom Regulatory Authority of India — 30 June 2015 Audience - India
  33. WebP • Lossy and lossless image compression developed by Google

    • Open source, BSD licensed • Native support on Android 4.0+ • 28% reduction in size compared to PNGs re-compressed with pngcrush and pngout
  34. PJPEG • Image is compressed in multiple passes of progressively

    higher detail • No transparency support • No native support on Android
  35. Fresco • Image loading and display library from Facebook •

    Support for PJPEG out of the box • No feature gaps • Caching • Progress bars • Scaling • Resize and rotation • Rounded corners and circles
  36. Results • Images were 25% smaller compared to PNG or

    JPEG images • 9% decrease in p50 load times • 74% decrease in failures • Increased user engagement, especially in emerging markets 3,000 images per second — Henna Kerman/Twitter
  37. User Empathy 2G Day • Throttled all employee accounts •

    iOS and Android only • Didn’t simulate network error rates Cost Notification • Currently iOS only • Provides employee with region specific costs for network usage
  38. #PerfMatters • http://highscalability.com/blog/2016/4/20/how-twitter-handles-3000-images-per-second.html • https://code.facebook.com/posts/1566627733629653/mobile-scale-london-recap/ • https://en.wikipedia.org/wiki/WebP • https://en.wikipedia.org/wiki/JPEG •

    http://www.economist.com/blogs/graphicdetail/2013/10/daily-chart-5 Localization • https://developer.android.com/distribute/tools/localization-checklist.html • https://developer.android.com/guide/topics/resources/icu4j-framework.html • http://www.terry.uga.edu/news/releases/asians-hispanics-driving-u.s.-economy-forward-according-to-uga- study References
  39. RTL • https://www.youtube.com/watch?v=4dJHtT4-vBE (From Right to Left and Back) •

    https://material.google.com/ • https://www.idc.com/getdoc.jsp?containerId=prAE25737515 • http://mpcabd.xyz/python-arabic-text-reshaper/ Images • http://android-developers.blogspot.com/ References