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

When in Rome, speak…maybe not Italian?

When in Rome, speak…maybe not Italian?

A talk about i18n that Raquel Moss and I gave at Droidcon London 2019.

With a diverse, global base of users, how do you decide which language to use to present content to your user? Location makes sense, right? Romans speak Italian, Osakans speak Japanese, and Ohians speak English. Simple!

Except that you know it’s not like that. Everyone knows there’s Vietnamese people living in Rome, British people living in Osaka, and Argentinians living in Ohio—such is life in 2019.

So why do so many companies solely use location to determine things like language, currency formats, and other important internationalisation features? It’s a frustrating experience for users, and the tools exist to do much better.

In this session, you will explore some examples where companies are getting it right, some examples where companies are getting it very wrong. You will also discover some suggestions on how you can improve the experience in your own apps.

30966c6e1a52faf6b287b59a01195938?s=128

Kai Koenig

October 25, 2019
Tweet

Transcript

  1. RAQUEL MOSS & KAI KOENIG WHEN IN ROME, SPEAK… MAYBE

    NOT ITALIAN?
  2. None
  3. None
  4. None
  5. None
  6. None
  7. None
  8. WHEN IT MIGHT BE OK TO ASSUME?

  9. Inferring language from location is a heuristic that is limited

    by our own biases and often wrong
  10. THIS DOESN’T JUST AFFECT TRAVELLERS

  11. MULTI-LINGUAL COUNTRIES

  12. MULTI-LINGUAL COUNTRIES

  13. YOUR APPLICATION DOES NOT LIVE IN A VACUUM

  14. YOUR APPLICATION DOES NOT LIVE IN A VACUUM

  15. YOUR APPLICATION DOES NOT LIVE IN A VACUUM

  16. • Language • Location • Locales ◦ Number and Currency

    formats ◦ Reading direction ◦ Date and Time formats i18n TERMINOLOGY en_US or en-US ???
  17. • Language • Location • Locales ◦ Number and Currency

    formats ◦ Reading direction ◦ Date and Time formats i18n TERMINOLOGY zh-Hans-SG
  18. THE LOCALE STACK Android Device Browser App Debian Java Code

    JVM Native A P I
  19. Use the choices that the user has already made

  20. • Sent by the browser with every request • Gives

    weighted values for each accepted language • Every browser handles this differently • Browsers usually set this initially from the system language THE ACCEPT-LANGUAGE HEADER
  21. THE ACCEPT-LANGUAGE HEADER

  22. None
  23. None
  24. None
  25. None
  26. In all of those examples, my Accept-Language header was asking

    for English
  27. WHAT ABOUT ANDROID?

  28. WHAT ABOUT ANDROID?

  29. CUSTOM HEADERS WITH OKHTTP

  30. Q FOR QUALITY

  31. Q-VALUES

  32. CONTENT NEGOTIATION

  33. SERVER DRIVEN CONTENT-NEGOTIATION Client /en /de /da /th /en

  34. CLIENT DRIVEN CONTENT-NEGOTIATION Client English German Danish Thai /en /de

    /da /th Engli sh Ger man Dani sh Thai /en /de /da /th Client
  35. CLIENT DRIVEN CONTENT-NEGOTIATION /es /ru /fr /en /zh /ar

  36. CLIENT DRIVEN CONTENT-NEGOTIATION

  37. • Make an initial choice based on the Accept-Language header

    (server driven) • Allow a reliable override with a language selector (client driven) USE BOTH
  38. • Be guided by your framework • But stick closely

    to Content Negotiation if you can DYNAMIC & MULTI-LANGUAGE
  39. • Dynamically set the locale based on ◦ Stored preferences,

    if logged in ◦ TLD or subdomain (example.es) ◦ Path (example.com/es) ◦ Accept-Language header DYNAMIC & MULTI-LANGUAGE
  40. • Don’t roll-your-own algorithm for figuring out which language to

    serve up • ….but if you do, RFC 2616 is what you’re looking for to guide you DYNAMIC & MULTI-LANGUAGE
  41. What should you do in the UI?

  42. ANDROID UI AND i18N

  43. SYSTEM LOCALES ON ANDROID

  44. LOCALE RESOLUTION (PRE API 24) Device App de_CH en_US (default)

    de_DE en_US (default)
  45. LOCALE RESOLUTION (POST API 24) Device App de_CH en_US (default)

    de_DE de_CH
  46. LOCALES AT RUNTIME en_AU es_MX es_ES it_CH mi_NZ fr_CH en_NZ

    de_DE
  47. USING updateConfiguration()

  48. USING attachBaseContext()

  49. i18N WITH APP BUNDLES

  50. SplitInstallManager

  51. UIs ON THE WEB

  52. UIs ON THE WEB

  53. UIs ON THE WEB

  54. UIs ON THE WEB

  55. UIs ON THE WEB

  56. WHAT ABOUT FLAGS?

  57. PERSISTING SETTINGS

  58. PERSISTING SETTINGS

  59. In summation

  60. RAQUEL MOSS @RAQUELXMOSS KAI KOENIG @AGENTK