Lokalizowanie aplikacji

Android działa na wielu urządzeniach w wielu regionach. Aby dotrzeć do jak największej liczby użytkowników, upewnij się, że aplikacja obsługuje tekst, pliki audio, liczby, waluty i grafikę w sposób odpowiedni dla regionów, w których jest używana.

Na tej stronie znajdziesz sprawdzone metody lokalizowania aplikacji na Androida.

Musisz mieć praktyczną wiedzę o Kotlinie i znać proces wczytywania zasobów Androida, kwestie związane z programowaniem, takie jak cykl życia aktywności, oraz ogólne zasady internacjonalizacji i lokalizacji.

Dobrą praktyką jest używanie platformy zasobów Androida do jak największego oddzielenia zlokalizowanych aspektów aplikacji od jej podstawowych funkcji aplikacji.

  • Umieść większość lub całą zawartość interfejsu aplikacji w plikach zasobów, jak opisano na tej stronie i w omówieniu zasobów aplikacji.
  • Z kolei zachowanie interfejsu użytkownika jest określane przez kod w języku Kotlin. Jeśli na przykład użytkownicy wprowadzają dane, które muszą być sformatowane lub posortowane inaczej w zależności od języka, możesz użyć Kotlina, aby obsłużyć te dane programowo. Na tej stronie nie opisano, jak lokalizować kod oparty na Kotlinie.

Ten przewodnik dotyczy podstawowego systemu lokalizacji Androida, który jest używany we wszystkich aplikacjach na Androida. Aby dowiedzieć się, jak wczytywać te zlokalizowane zasoby w interfejsie Jetpack Compose, przeczytaj artykuł Zasoby w Compose.

Krótki przewodnik po lokalizowaniu ciągów tekstowych w aplikacji znajdziesz w artykule Obsługa różnych języków i kultur.

Omówienie: przełączanie zasobów na Androidzie

Zasoby to ciągi tekstowe, dźwięki, grafika i inne dane statyczne, których potrzebuje aplikacja na Androida. Aplikacja może zawierać wiele zestawów zasobów, z których każdy jest dostosowany do innej konfiguracji urządzenia. Gdy użytkownik uruchamia aplikację, Android automatycznie wybiera i wczytuje zasoby, które najlepiej pasują do urządzenia.

Ta strona dotyczy lokalizacji i ustawień regionalnych. Pełny opis przełączania zasobów i wszystkich typów konfiguracji, które możesz określić, takich jak orientacja ekranu czy typ ekranu dotykowego, znajdziesz w artykule Udostępnianie zasobów alternatywnych.

Podczas pisania aplikacji tworzysz domyślne i alternatywne zasoby, których aplikacja będzie używać. Gdy użytkownicy uruchamiają aplikację, system Android wybiera zasoby do wczytania na podstawie ustawień regionalnych urządzenia. Aby utworzyć zasoby, umieść pliki w podkatalogach o specjalnych nazwach w katalogu res/ projektu.

Dlaczego zasoby domyślne są ważne

Gdy aplikacja działa w języku, dla którego nie podano tekstu, Android wczytuje domyślne ciągi znaków z pliku res/values/strings.xml. Jeśli brakuje tego domyślnego pliku lub ciągu znaków, którego potrzebuje aplikacja, nie będzie ona działać i wyświetli błąd. Przykład poniżej pokazuje, co może się stać, gdy domyślny plik tekstowy jest niekompletny.

Przykład:

Kod aplikacji oparty na języku Kotlin odnosi się tylko do 2 ciągów tekstowych: text_a i text_b. Aplikacja zawiera zlokalizowany plik zasobów (res/values-en/strings.xml), który definiuje text_a i text_b w języku angielskim. Aplikacja zawiera też domyślny plik zasobów (res/values/strings.xml), który zawiera definicję text_a, ale nie text_b.

  • Gdy ta aplikacja zostanie uruchomiona na urządzeniu z ustawionym językiem angielskim, może działać bez problemu, ponieważ res/values-en/strings.xml zawiera oba potrzebne ciągi tekstowe.
  • Jednak gdy ta aplikacja zostanie uruchomiona na urządzeniu z ustawionym językiem innym niż angielski, użytkownik zobaczy komunikat o błędzie i przycisk Wymuś zamknięcie. Aplikacja się nie wczytuje.

Aby uniknąć tej sytuacji, upewnij się, że plik res/values/strings.xml istnieje i zawiera wszystkie potrzebne ciągi znaków. Dotyczy to wszystkich typów zasobów, nie tylko ciągów tekstowych. Musisz utworzyć zestaw domyślnych plików zasobów zawierających wszystkie zasoby, które wywołuje aplikacja, takie jak obiekty rysowalne, czcionki czy kolory. Informacje o testowaniu znajdziesz w sekcji Testowanie zasobów domyślnych.

Używanie zasobów do lokalizacji

W tej sekcji dowiesz się, jak tworzyć zasoby domyślne i alternatywne. Wyjaśnia też, jak zasobom przypisywany jest priorytet i jak odwoływać się do zasobów w kodzie.

Tworzenie zasobów domyślnych

Umieść domyślny tekst aplikacji w pliku res/values/strings.xml. W przypadku tych ciągów użyj języka domyślnego, czyli języka, którym posługuje się większość użytkowników aplikacji.

Domyślny zestaw zasobów zawiera też wszystkie domyślne elementy rysowalne i może obejmować inne typy zasobów, takie jak ikony czy ciągi znaków. Te zasoby znajdują się w tych katalogach:

  • res/drawable/: wymagany katalog zawierający co najmniej 1 plik graficzny ikony aplikacji w Google Play.
  • res/xml/: wymagane, jeśli masz foldery res/xml-<qualifiers>
  • res/raw/: wymagane, jeśli masz foldery res/raw-<qualifiers>

Tworzenie zasobów alternatywnych

Dużą częścią lokalizacji aplikacji jest dostarczanie tekstu alternatywnego w różnych językach. W niektórych przypadkach udostępniasz też alternatywne grafiki, dźwięki i inne zasoby dostosowane do konkretnych regionów.

Aplikacja może określać wiele katalogów res/<qualifiers>/, z których każdy ma inne kwalifikatory. Aby utworzyć zasób alternatywny dla innego języka, użyj kwalifikatora, który określa język lub kombinację języka i regionu. Nazwa katalogu zasobów musi być zgodna ze schematem nazewnictwa opisanym w artykule Udostępnianie zasobów alternatywnych. W przeciwnym razie nie będzie można skompilować aplikacji.

Przykład:

Załóżmy, że domyślnym językiem aplikacji jest angielski i chcesz przetłumaczyć cały tekst w aplikacji na francuski, a na japoński – cały tekst oprócz tytułu aplikacji. W tym przypadku tworzysz 3 pliki strings.xml, z których każdy jest przechowywany w katalogu zasobów dla danego języka:

  1. res/values/strings.xml
    Zawiera angielski tekst wszystkich ciągów znaków używanych przez aplikację, w tym tekst ciągu o nazwie title.
  2. res/values-fr/strings.xml
    Zawierać francuskie tłumaczenie wszystkich ciągów tekstowych, w tym title.
  3. res/values-ja/strings.xml
    Zawierać japoński tekst dla wszystkich ciągów z wyjątkiem title.

Jeśli kod w języku Kotlin odwołuje się do R.string.title, w czasie działania dzieje się tak:

  • Jeśli na urządzeniu jest ustawiony inny język niż francuski, Android wczytuje title z pliku res/values/strings.xml.
  • Jeśli na urządzeniu jest ustawiony język francuski, Android wczytuje title z pliku res/values-fr/strings.xml.

Jeśli na urządzeniu jest ustawiony język japoński, Android szuka ciągu title w pliku res/values-ja/strings.xml. Ponieważ jednak w tym pliku nie ma takiego ciągu, Android używa domyślnego i wczytuje ciąg title w języku angielskim z pliku res/values/strings.xml.

Które zasoby mają pierwszeństwo?

Jeśli konfiguracji urządzenia odpowiada wiele plików zasobów, Android stosuje zestaw reguł, aby zdecydować, którego pliku użyć. Wśród kwalifikatorów, które można określić w nazwie katalogu zasobów, ustawienia regionalne prawie zawsze mają pierwszeństwo.

Przykład:

Załóżmy, że aplikacja zawiera domyślny zestaw grafiki i 2 inne zestawy, z których każdy jest zoptymalizowany pod kątem innej konfiguracji urządzenia:

  • res/drawable/
    Zawiera domyślną grafikę.
  • res/drawable-small-land-stylus/
    Zawiera grafikę zoptymalizowaną pod kątem używania na urządzeniu, które oczekuje danych wejściowych z rysika i ma ekran QVGA o niskiej gęstości pikseli w orientacji poziomej.
  • res/drawable-ja/
    Zawiera grafikę zoptymalizowaną pod kątem języka japońskiego.

Jeśli aplikacja działa na urządzeniu, na którym ustawiono język japoński, Android wczytuje grafikę z katalogu res/drawable-ja/, nawet jeśli urządzenie oczekuje danych wejściowych z rysika i ma ekran QVGA o niskiej gęstości pikseli w orientacji poziomej.

Wyjątek: jedynymi kwalifikatorami, które mają pierwszeństwo przed ustawieniami językowymi w procesie wyboru, są mobile country code (MCC) i kod MNC.

Przykład:

Załóżmy, że masz taką sytuację:

  • Kod aplikacji wywołuje R.string.text_a.
  • Dostępne są 2 odpowiednie pliki zasobów:
    • res/values-mcc404/strings.xml, który zawiera text_a w domyślnym języku aplikacji, w tym przypadku angielskim.
    • res/values-hi/strings.xml, który zawiera text_a w języku hindi.
  • Aplikacja działa na urządzeniu o tej konfiguracji:
    • Karta SIM jest połączona z siecią komórkową w Indiach (MCC 404).
    • Język jest ustawiony na hindi (hi).

Android wczytuje plik text_a z folderu res/values-mcc404/strings.xml (w języku angielskim), nawet jeśli urządzenie jest skonfigurowane na język hindi. Dzieje się tak, ponieważ w procesie wyboru zasobów Android preferuje dopasowanie MCC nad dopasowanie języka.

Proces wyboru nie zawsze jest tak prosty, jak sugerują te przykłady. Bardziej szczegółowy opis tego procesu znajdziesz w artykule Jak Android znajduje najlepiej pasujący zasób. Wszystkie kwalifikatory są opisane i wymienione w kolejności pierwszeństwa w omówieniu zasobów aplikacji.

Odwoływanie się do zasobów w kodzie

W kodzie aplikacji opartym na języku Kotlin odwołujesz się do zasobów, używając składni R.resource_type.resource_name lub android.R.resource_type.resource_name. Więcej informacji znajdziesz w artykule o uzyskiwaniu dostępu do zasobów aplikacji.

Zarządzanie ciągami tekstowymi na potrzeby lokalizacji

W tej sekcji znajdziesz sprawdzone metody zarządzania ciągami tekstowymi związane z lokalizacją.

Przenieś wszystkie ciągi znaków do pliku strings.xml.

Podczas tworzenia aplikacji nie koduj na stałe żadnych ciągów znaków. Zamiast tego zadeklaruj wszystkie ciągi tekstowe jako zasoby w domyślnym pliku strings.xml, co ułatwi ich aktualizowanie i lokalizowanie. Ciągi tekstowe w pliku strings.xml można łatwo wyodrębnić, przetłumaczyć i ponownie zintegrować z aplikacją, używając odpowiednich kwalifikatorów, bez wprowadzania zmian w skompilowanym kodzie.

Na przykład w Compose możesz wczytać ciąg znaków w ten sposób:

// In the res/values/strings.xml file
// <string name="compose">Jetpack Compose</string>

// In your Compose code
Text(
    text = stringResource(R.string.compose)
)

Jeśli generujesz obrazy z tekstem, umieść te ciągi znaków również w pliku strings.xml i wygeneruj obrazy ponownie po przetłumaczeniu.

Przestrzeganie wskazówek dotyczących ciągów tekstowych interfejsu na Androidzie

Podczas projektowania i tworzenia interfejsów użytkownika zwracaj szczególną uwagę na to, jak komunikujesz się z użytkownikiem. Ogólnie rzecz biorąc, używaj zwięzłego, przyjaznego, ale krótkiego stylu i zachowaj spójność we wszystkich interfejsach.

Przeczytaj i zastosuj zalecenia dotyczące stylu pisania i doboru słów w Material Design. Dzięki temu aplikacje wyglądają na bardziej dopracowane i użytkownicy szybciej rozumieją interfejs.

Zawsze, gdy to możliwe, używaj standardowej terminologii Androida, np. w przypadku elementów interfejsu, takich jak pasek aplikacji, menu opcji, pasek systemowy i powiadomienia. Prawidłowe i spójne używanie terminów związanych z Androidem ułatwia tłumaczenie i pozwala uzyskać lepszy produkt końcowy dla użytkowników.

Podawanie wystarczającego kontekstu w przypadku zadeklarowanych ciągów tekstowych

Deklarując ciągi znaków w pliku strings.xml, pamiętaj o opisaniu kontekstu, w którym dany ciąg jest używany. Te informacje są nieocenione dla tłumacza i pozwalają uzyskać lepszą jakość tłumaczenia. Ułatwia też efektywne zarządzanie ciągami tekstowymi.

Oto przykład:

<!-- The action for submitting a form. This text is on a button that can fit 30 chars -->
<string name="login_submit_button">Sign in</string>

Możesz podać informacje kontekstowe, takie jak:

  • Do czego służy ten ciąg znaków? Kiedy i gdzie jest wyświetlana użytkownikowi?
  • Gdzie to jest w interfejsie? Na przykład tłumaczenia są mniej elastyczne w przypadku przycisków niż pól tekstowych.

Oznaczanie części wiadomości, które nie mają być tłumaczone

Ciągi znaków często zawierają tekst, który nie powinien być tłumaczony na inne języki. Typowe przykłady to fragment kodu, obiekt zastępczy wartości, symbol specjalny lub nazwa. Przygotowując ciągi tekstowe do tłumaczenia, wyszukaj i oznacz tekst, który musi pozostać bez zmian, aby tłumacz go nie zmienił.

Aby oznaczyć tekst, który nie ma być tłumaczony, użyj tagu zastępczego <xliff:g>. Oto przykładowy tag, który wskazuje, że tekst "%1$s" nie powinien być zmieniany podczas tłumaczenia, aby nie uszkodzić wiadomości:

<string name="countdown">
  <xliff:g id="time" example="5 days">%1$s</xliff:g> until holiday
</string>

Podczas deklarowania tagu obiektu zastępczego dodaj atrybut ID, który wyjaśnia, do czego służy obiekt zastępczy. Jeśli aplikacja później zastąpi wartość zmiennej, podaj przykładowy atrybut, aby wyjaśnić oczekiwane użycie.

Oto kilka innych przykładów tagów obiektów zastępczych:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Example placeholder for a special Unicode symbol -->
<string name="star_rating">Check out our 5
    <xliff:g id="star">\u2605</xliff:g>
</string>
<!-- Example placeholder for a URL -->
<string name="app_homeurl">
    Visit us at <xliff:g
    id="application_homepage">http://my/app/home.html</xliff:g>
</string>
<!-- Example placeholder for a name -->
<string name="prod_name">
    Learn more at <xliff:g id="prod_gamegroup">Game Group</xliff:g>
</string>
<!-- Example placeholder for a literal -->
<string name="promo_message">
    Please use the "<xliff:g id="promotion_code">ABCDEFG</xliff:g>" to get a discount.
</string>
...
</resources>

Lista kontrolna lokalizacji

Pełne omówienie procesu lokalizowania i rozpowszechniania aplikacji na Androida znajdziesz w artykule Tłumaczenie i lokalizowanie aplikacji.

Wskazówki dotyczące lokalizacji

Podczas lokalizowania aplikacji postępuj zgodnie z tymi wskazówkami.

Zaprojektuj aplikację tak, aby działała w każdym regionie

Nie zakładaj niczego na temat urządzenia, na którym użytkownik uruchamia Twoją aplikację. Urządzenie może mieć sprzęt, którego się nie spodziewasz, lub może być ustawione na region, którego nie planujesz lub którego nie możesz przetestować. Zaprojektuj aplikację tak, aby działała normalnie lub nie powodowała błędów niezależnie od urządzenia, na którym jest uruchomiona.

Ważne: upewnij się, że aplikacja zawiera pełny zestaw zasobów domyślnych: foldery res/drawable/ i res/values/ bez dodatkowych modyfikatorów w nazwach, które zawierają wszystkie obrazy i teksty potrzebne aplikacji.

Jeśli w aplikacji brakuje choćby jednego zasobu domyślnego, nie będzie ona działać na urządzeniu, na którym ustawiono nieobsługiwany język. Jeśli na przykład w domyślnym pliku res/values/strings.xml brakuje jednego ciągu, którego aplikacja potrzebuje, to gdy aplikacja zostanie uruchomiona w nieobsługiwanym języku i spróbuje wczytać res/values/strings.xml, użytkownik zobaczy komunikat o błędzie i przycisk Wymuś zamknięcie.

Więcej informacji znajdziesz w sekcji Testowanie zasobów domyślnych.

Unikaj tworzenia większej liczby plików zasobów i ciągów tekstowych, niż potrzebujesz

Prawdopodobnie nie musisz tworzyć alternatywnych wersji każdego zasobu w aplikacji dla poszczególnych języków. Na przykład logo aplikacji zdefiniowane w katalogu res/drawable/ może działać w każdym języku, więc nie trzeba tworzyć żadnych alternatywnych plików graficznych.

Możesz też nie potrzebować tekstu alternatywnego dla każdego ciągu znaków. Załóżmy na przykład, że:

  • Domyślnym językiem Twojej aplikacji jest amerykański angielski. Każdy ciąg znaków używany przez aplikację jest zdefiniowany w pliku res/values/strings.xml z użyciem amerykańskiej pisowni angielskiej.
  • W przypadku kilku ważnych wyrażeń chcesz podać pisownię w brytyjskiej odmianie języka angielskiego. Chcesz, aby te alternatywne ciągi znaków były używane, gdy aplikacja działa na urządzeniu w Wielkiej Brytanii.

Aby to zrobić, utwórz mały plik o nazwie res/values-en-rGB/strings.xml, który zawiera tylko ciągi znaków różniące się od tych, które są używane, gdy aplikacja działa w Wielkiej Brytanii. W przypadku wszystkich pozostałych ciągów znaków aplikacja będzie używać domyślnych wartości zdefiniowanych w pliku res/values/strings.xml.

Użyj LocalConfiguration do ręcznego wyszukiwania języka

Możesz sprawdzić region, używając LocalConfiguration udostępnianego przez Androida, jak w tym przykładzie:

val locale = LocalConfiguration.current.locales[0]

Korzystanie z usługi tłumaczenia aplikacji

Usługa tłumaczenia aplikacji jest zintegrowana z Konsolą Play. Pozwala ona uzyskać natychmiastową wycenę i złożyć zamówienie w firmie tłumaczeniowej. Możesz zamówić tłumaczenia na co najmniej 1 język ciągów tekstowych interfejsu aplikacji, tekstu na stronie aplikacji w Sklepie Play, nazw produktów w aplikacji i tekstu kampanii reklamowej.

Tłumaczenie ciągów tekstowych z aplikacji za pomocą Gemini

Możesz używać Gemini w Android Studio, aby tłumaczyć zasoby tekstowe aplikacji bezpośrednio w projekcie. Więcej informacji znajdziesz w artykule Tłumaczenie i lokalizowanie aplikacji.

Testowanie zlokalizowanych aplikacji

Przetestuj zlokalizowaną aplikację na urządzeniu lub za pomocą Android Emulator. W szczególności przetestuj aplikację, aby upewnić się, że zawiera wszystkie niezbędne zasoby domyślne.

Testowanie na urządzeniu

Pamiętaj, że urządzenie, na którym testujesz, może się znacznie różnić od urządzeń dostępnych dla konsumentów w innych miejscach. Ustawienia regionalne dostępne na Twoim urządzeniu mogą się różnić od tych dostępnych na innych urządzeniach. Rozdzielczość i gęstość ekranu urządzenia mogą się różnić, co może mieć wpływ na wyświetlanie ciągów znaków i obiektów rysowalnych w interfejsie.

Aby zmienić region lub język na urządzeniu, użyj aplikacji Ustawienia.

Testowanie za pomocą podglądów funkcji kompozycyjnych

Przed testowaniem na urządzeniu możesz użyć podglądu funkcji kompozycyjnych w Android Studio, aby przetestować zlokalizowane interfejsy bez wdrażania ich w emulatorze. Aby wyświetlić podgląd interfejsu w różnych językach, użyj adnotacji @Preview (np. @Preview(locale = "fr")). Możesz też przetestować układy z zapisem od prawej do lewej (RTL), określając ustawienia regionalne RTL, np. @Preview(locale = "ar").

Testowanie w emulatorze

Szczegółowe informacje o korzystaniu z emulatora znajdziesz w artykule Uruchamianie aplikacji w Android Emulator.

Tworzenie i używanie niestandardowych ustawień regionalnych

„Niestandardowe” ustawienia regionalne to kombinacja języka i regionu, która nie jest wyraźnie obsługiwana przez obraz systemu Android. Możesz sprawdzić, jak aplikacja działa w niestandardowym regionie, tworząc go w emulatorze. Możesz to zrobić na 2 sposoby:

  • Użyj aplikacji Custom Locale, która jest dostępna na karcie aplikacji. Po utworzeniu niestandardowego ustawienia regionalnego przełącz się na nie, naciskając i przytrzymując jego nazwę.
  • Zmień na niestandardowe ustawienia regionalne z poziomu powłoki adb, jak opisano w następnej sekcji.

Jeśli ustawisz emulator na język, który nie jest dostępny w obrazie systemu Android, system będzie wyświetlany w języku domyślnym. Aplikacja jest jednak prawidłowo zlokalizowana.

Zmienianie języka emulatora z poziomu powłoki adb

Aby zmienić język w emulatorze za pomocą powłoki adb, wykonaj te czynności:

  1. Wybierz region, który chcesz przetestować, i określ jego tag języka BCP-47, np. fr-CA dla francuskiego w Kanadzie.
  2. Uruchom emulator.
  3. W powłoce wiersza poleceń na komputerze hosta uruchom to polecenie:
    adb shell
    Jeśli masz podłączone urządzenie, określ, że chcesz użyć emulatora, dodając opcję -e:
    adb -e shell
  4. W wierszu polecenia powłoki adb (#) uruchom to polecenie:
    setprop persist.sys.locale [BCP-47 language tag];stop;sleep 5;start
    Zastąp sekcje w nawiasach odpowiednimi kodami z kroku 1.

    Aby na przykład przetestować francuski (Kanada):
    setprop persist.sys.locale fr-CA;stop;sleep 5;start

Spowoduje to ponowne uruchomienie emulatora. Gdy ponownie pojawi się ekran główny, uruchom ponownie aplikację. Zostanie ona uruchomiona z nowymi ustawieniami językowymi.

Testowanie zasobów domyślnych

Aby sprawdzić, czy aplikacja zawiera wszystkie potrzebne zasoby tekstowe, wykonaj te czynności:

  1. Ustaw na emulatorze lub urządzeniu język, którego Twoja aplikacja nie obsługuje. Jeśli na przykład aplikacja ma francuskie ciągi znaków w res/values-fr/, ale nie ma hiszpańskich ciągów znaków w res/values-es/, ustaw język emulatora na hiszpański. Możesz użyć aplikacji Custom Locale, aby ustawić w emulatorze nieobsługiwane ustawienia regionalne.
  2. Uruchom aplikację.
  3. Jeśli aplikacja wyświetla komunikat o błędzie i przycisk Wymuś zamknięcie, może to oznaczać, że szuka ciągu, który jest niedostępny. Upewnij się, że plik res/values/strings.xml zawiera definicję każdego ciągu używanego przez aplikację.

Jeśli test się powiedzie, powtórz go w przypadku innych typów konfiguracji. Jeśli na przykład aplikacja zawiera plik z ciągami znaków o nazwie res/values-land/strings.xml, ale nie zawiera pliku o nazwie res/values-port/strings.xml, ustaw emulator lub urządzenie w orientacji pionowej i sprawdź, czy aplikacja się uruchamia.

Dodatkowe materiały

Więcej informacji o lokalizacji znajdziesz w tych materiałach:

Dokumentacja

Wyświetlanie treści