Dokumentacja dotycząca licencjonowania

Klasy i interfejsy LVL

Tabela 1 zawiera listę wszystkich plików źródłowych w bibliotece weryfikacji licencji (LVL), która jest dostępna w pakiecie Android SDK. Wszystkie pliki wchodzą w skład pakietu com.android.vending.licensing.

Tabela 1. Podsumowanie klas i interfejsów biblioteki LVL.

Kategoria Nazwa Opis
Sprawdzanie licencji i wynik Narzędzie LicenseChecker Klasa, którą tworzysz (lub podklasę), aby rozpocząć sprawdzanie licencji.
Wywołanie zwrotne sprawdzania licencji Interfejs, który stosujesz do obsługi wyniku sprawdzania licencji.
Zasady Zasady Interfejs, który stosujesz do określania, czy zezwolić na dostęp do aplikacji na podstawie odpowiedzi licencji.
Zasada zarządzania serwerem Domyślna implementacja Policy. Wykorzystuje ustawienia udostępnione przez serwer licencjonowania do zarządzania lokalnym przechowywaniem danych licencji, ich ważność i ponawianiem prób.
Ścisła zasada Alternatywna implementacja Policy. Wymusza licencjonowanie tylko na podstawie bezpośredniej odpowiedzi licencji z serwera. Brak buforowania i ponawiania żądań.
Zaciemnianie danych
(opcjonalne)
Zaciemnianie Interfejs, który musisz wdrożyć, jeśli używasz Policy (np. ServerManagedPolicy), który przechowuje w pamięci podręcznej dane odpowiedzi licencji w pamięci trwałej. Stosuje algorytm zaciemniania do kodowania i dekodowania danych zapisywanych lub odczytywanych.
Moduł AESObfuscator Domyślna implementacja maskowania, która do zaciemniania i usuwania zaciemnienia danych wykorzystuje algorytm AES szyfrowania/odszyfrowywania.
Ograniczenie dotyczące urządzeń
(opcjonalne)
DeviceLimiter Interfejs, który musisz wdrożyć, aby ograniczyć korzystanie z aplikacji do konkretnego urządzenia. Wywołano z elementu LicenseValidator. Wdrożenie funkcji DeviceLimiter nie jest zalecane w przypadku większości aplikacji, ponieważ wymaga serwera backendu i może spowodować utratę dostępu do licencjonowanych aplikacji, jeśli nie zostały starannie zaprojektowane.
Ogranicznik urządzenia o wartości null Domyślna implementacja ograniczenia parametru DeviceLimiter, która nie jest obsługiwana (umożliwia dostęp do wszystkich urządzeń).
Podstawowa biblioteka, integracja nie jest wymagana Dane odpowiedzi Klasa, która zawiera pola odpowiedzi licencji.
Element LicenseValidator Klasa, która odszyfrowuje i weryfikuje odpowiedź otrzymaną z serwera licencji.
Wyjątek walidacji Klasa, która wskazuje błędy występujące podczas weryfikacji integralności danych zarządzanych przez zaciemniacz.
Selektor preferencji Klasa narzędzia, która zapisuje/czyta zaciemnione dane w magazynie SharedPreferences systemu.
ILicensingService Jednokierunkowy interfejs IPC, przez który do klienta Google Play jest przekazywane żądanie sprawdzania licencji.
ILicenseResultListener Jednokierunkowa implementacja wywołania zwrotnego IPC, w ramach której aplikacja otrzymuje asynchroniczną odpowiedź z serwera licencjonowania.

Odpowiedź serwera

Tabela 2 zawiera listę wszystkich pól odpowiedzi licencji zwróconych przez serwer licencjonowania.

Tabela 2. Podsumowanie pól odpowiedzi dotyczących licencji zwracanych przez serwer Google Play.

Pole Opis
responseCode Kod odpowiedzi zwrócony przez serwer licencjonowania. Kody odpowiedzi znajdziesz w sekcji Kody odpowiedzi serwera.
signedData Konkatenacja ciągu znaków zawierająca dane zwrócone przez serwer licencjonowania w następujący sposób: responseCode|nonce|packageName|versionCode|userId|timestamp:extras.
  • responseCode: kod odpowiedzi zwrócony przez serwer licencjonowania.
  • nonce: identyfikator jednorazowy żądania.
  • packageName: nazwa pakietu aplikacji, której licencję chcesz sprawdzić.
  • versionCode: kod wersji aplikacji, w przypadku której chcesz sprawdzić licencję.
  • userId: unikalny identyfikator użytkownika dla każdej aplikacji. Ten sam użytkownik otrzymuje inny identyfikator dla innej aplikacji.
  • timestamp: liczba milisekund od początku epoki UTC 1970-01-01 do 00:00:00 czasu UTC do żądania.
  • extras: dodatkowe informacje ułatwiające zarządzanie licencjami na aplikację. Dodatkowe pola znajdziesz w artykule Dodatki do odpowiedzi serwera.
signature Podpis klucza signedData za pomocą klucza specyficznego dla aplikacji.

Kody odpowiedzi serwera

Tabela 3 zawiera wszystkie kody odpowiedzi licencji obsługiwane przez serwer licencjonowania. Ogólnie aplikacja powinna obsługiwać wszystkie te kody odpowiedzi. Domyślnie klasa LicenseValidator w LVL zapewnia obsługę wszystkich kodów odpowiedzi.

Tabela 3. Podsumowanie kodów odpowiedzi zwróconych przez serwer Google Play w odpowiedzi dotyczącej licencji.

Kod odpowiedzi Reprezentacja liczby całkowitej Opis Podpisano? Dodatkowe treści Komentarze
LICENSED 0 Użytkownik otrzyma licencję na aplikację. Użytkownik kupił aplikację lub ma uprawnienia do pobrania i zainstalowania jej wersji alfa lub beta. Tak VT, GT GR Zezwalaj na dostęp zgodnie z ograniczeniami Policy.
LICENSED_OLD_KEY 2 Użytkownik ma licencję na aplikację, ale dostępna jest zaktualizowana wersja aplikacji podpisana innym kluczem. Tak VT, GT, GR, UT Opcjonalnie zezwól na dostęp zgodnie z ograniczeniami Policy.

Może wskazywać, że para kluczy używana przez zainstalowaną wersję aplikacji jest nieprawidłowa lub została zhakowana. Aplikacja może zezwolić na dostęp w razie potrzeby lub poinformować użytkownika o możliwości uaktualnienia i ograniczyć dalsze korzystanie z aplikacji do czasu uaktualnienia.

NOT_LICENSED 1 Użytkownik nie ma licencji na tę aplikację. Nie Nie zezwalaj na dostęp.
ERROR_CONTACTING_SERVER 257 Błąd lokalny – aplikacja Google Play nie mogła nawiązać połączenia z serwerem licencjonowania, prawdopodobnie z powodu problemów z dostępnością sieci. Nie Ponów próbę sprawdzenia licencji zgodnie z limitem ponownych prób (Policy).
ERROR_SERVER_FAILURE 4 Błąd serwera – serwer nie mógł wczytać pary kluczy aplikacji na potrzeby licencjonowania. Nie Ponów próbę sprawdzenia licencji zgodnie z limitem ponownych prób (Policy).
ERROR_INVALID_PACKAGE_NAME 258 Błąd lokalny – aplikacja zażądała sprawdzenia licencji pakietu, który nie jest zainstalowany na urządzeniu. Nie Nie próbuj ponownie sprawdzić licencji.

Zwykle przyczyną jest błąd deweloperski.

ERROR_NON_MATCHING_UID 259 Błąd lokalny – aplikacja zażądała sprawdzenia licencji pakietu, którego identyfikator UID (pakiet, para identyfikatora użytkownika) nie jest zgodny z identyfikatorem aplikacji, która wysłała żądanie. Nie Nie próbuj ponownie sprawdzić licencji.

Zwykle przyczyną jest błąd deweloperski.

ERROR_NOT_MARKET_MANAGED 3 Błąd serwera – aplikacja (nazwa pakietu) nie została rozpoznana przez Google Play. Nie Nie próbuj ponownie sprawdzić licencji.

Może wskazywać, że aplikacja nie została opublikowana w Google Play lub wystąpił błąd w implementacji licencjonowania.

Uwaga: zgodnie z opisem w sekcji Konfigurowanie środowiska testowego kod odpowiedzi można ręcznie zastąpić w Konsoli Google Play dla dewelopera aplikacji i wszystkich zarejestrowanych użytkowników testowych.

Uwaga: wcześniej można było testować aplikację, przesyłając nieopublikowaną wersję roboczą. Ta funkcja nie jest już obsługiwana. Musisz ją opublikować w kanale dystrybucji alfa lub beta. Więcej informacji znajdziesz w artykule Wersje robocze aplikacji nie są już obsługiwane.

Dodatki do funkcji odpowiedzi serwera

Aby pomóc aplikacji w zarządzaniu dostępem do aplikacji w okresie zwrotu środków za aplikację oraz podać inne informacje, serwer licencjonowania umieszcza w odpowiedziach licencji kilka rodzajów informacji. W szczególności usługa podaje zalecane wartości okresu ważności licencji aplikacji, okresu prolongaty ponawiania próby, maksymalnej dozwolonej liczbie ponownych prób i innych ustawień. Jeśli Twoja aplikacja korzysta z plików rozszerzeń APK, odpowiedź zawiera też nazwy plików, rozmiary i adresy URL. Serwer dołącza te ustawienia w postaci par klucz-wartość w polu „extras” odpowiedzi licencji.

Każda implementacja Policy może wyodrębnić ustawienia dodatków z odpowiedzi licencji i użyć ich w razie potrzeby. Domyślna implementacja Policy na poziomie LVL (ServerManagedPolicy) służy jako działająca implementacja i pokazuje, jak uzyskiwać, przechowywać i używać ustawień.

Tabela 4. Podsumowanie ustawień zarządzania licencjami dostarczonych przez serwer Google Play w odpowiedzi na żądanie licencji.

DodatekOpis
VT Sygnatura czasowa ważności licencji. Określa datę i godzinę wygaśnięcia aktualnej (w pamięci podręcznej) odpowiedzi dotyczącej licencji i należy ją ponownie sprawdzić na serwerze licencjonowania. Zapoznaj się z sekcją Okres ważności licencji poniżej.
GT Sygnatura czasowa okresu prolongaty. Określa koniec okresu, w którym zasada może zezwalać na dostęp do aplikacji, mimo że stan odpowiedzi to RETRY.

Wartość jest zarządzana przez serwer, ale typowa wartość to 5 lub więcej dni. Zapoznaj się z sekcją poniżej na temat okresu ponawiania i maksymalnej liczby ponownych prób.

GR Maksymalna liczba ponownych prób. Określa, na ile następujących po sobie kontroli licencji RETRY ma zezwalać Policy, zanim odmówisz użytkownikowi dostępu do aplikacji.

Wartość jest zarządzana przez serwer, ale typowa to „10” lub większa. Zapoznaj się z sekcją poniżej na temat okresu ponawiania i maksymalnej liczby ponownych prób.

UT Sygnatura czasowa aktualizacji. Określa dzień i godzinę przesłania i opublikowania najnowszej aktualizacji aplikacji.

Serwer zwraca te dodatkowe odpowiedzi tylko w przypadku odpowiedzi LICENSED_OLD_KEYS, aby umożliwić Policy określenie, ile czasu upłynęło od opublikowania aktualizacji z nowymi kluczami licencyjnymi, zanim użytkownik odmówi dostępu do aplikacji.

FILE_URL1 lub FILE_URL2 Adres URL pliku rozszerzenia (1 oznacza plik główny, 2 – plik poprawki). Służy do pobierania pliku przez HTTP.
FILE_NAME1 lub FILE_NAME2 Nazwa pliku rozszerzenia (1 oznacza plik główny, 2 to plik poprawki). Musisz użyć tej nazwy podczas zapisywania pliku na urządzeniu.
FILE_SIZE1 lub FILE_SIZE2 Rozmiar pliku w bajtach (1 oznacza plik główny, 2 – plik poprawki). Użyj tej opcji, aby pomóc w pobieraniu danych i przed pobraniem upewnić się, że w pamięci współdzielonej urządzenia jest dość miejsca.

Okres ważności licencji

Serwer licencji Google Play ustawia okres ważności licencji dla wszystkich pobranych aplikacji. Okres określa przedział czasu, w którym stan licencji aplikacji powinien być uważany za niezmienny i buforowany przez Policy licencjonowania w aplikacji. Serwer licencjonowania uwzględnia okres ważności w odpowiedzi na wszystkie kontrole licencji i dodaje do odpowiedzi sygnaturę czasową zakończenia ważności (jako dodatkowy element pod kluczem VT). Policy może wyodrębnić wartość klucza VT i użyć jej, aby warunkowo zezwolić na dostęp do aplikacji bez ponownego sprawdzania licencji, dopóki nie wygaśnie okres ważności.

Ważność licencji sygnalizuje licencję Policy, gdy musi ponownie sprawdzić jej stan na serwerze licencji. Nie służy on do sugerowania, czy aplikacja jest rzeczywiście licencjonowana do użytku. Oznacza to, że gdy okres ważności licencji na aplikację wygaśnie, nie oznacza to, że aplikacja nie jest już licencjonowana. Wskazuje jedynie, że Policy musi ponownie sprawdzić stan licencji na serwerze. Dlatego, o ile okres ważności licencji nie upłynął, Policy może lokalnie zapisywać początkowy stan licencji w pamięci podręcznej i zwracać stan licencji zapisanej w pamięci podręcznej, zamiast wysyłać do serwera nowe sprawdzanie licencji.

Serwer licencji zarządza okresem ważności, aby pomóc aplikacji we właściwym egzekwowaniu licencjonowania w okresie zwrotu kosztów w przypadku płatnych aplikacji oferowanych przez Google Play. który określa okres ważności w zależności od tego, czy aplikacja została zakupiona, a jeśli tak, to jak dawno temu. Serwer ustawia ten okres ważności:

  • W przypadku płatnej aplikacji serwer ustawia początkowy okres ważności licencji, tak aby odpowiedź była ważna tak długo, jak aplikacja podlega zwrotowi. Licencjonowany Policy w aplikacji może buforować wynik wstępnego sprawdzenia licencji i nie musi robić tego ponownie, dopóki nie wygaśnie okres jej ważności.
  • Gdy aplikacja nie podlega już zwrotowi, serwer ustawia dłuższy okres ważności, który zwykle jest liczbą dni.
  • W przypadku bezpłatnej aplikacji serwer ustawia okres ważności na bardzo wysoką wartość (long.MAX_VALUE). Dzięki temu, jeśli Policy zapisze sygnaturę czasową ważności lokalnie w pamięci podręcznej, w przyszłości nie będzie trzeba ponownie sprawdzać stanu licencji aplikacji.

Implementacja ServerManagedPolicy używa wyodrębnionej sygnatury czasowej (mValidityTimestamp) jako głównego warunku przy określaniu, czy należy ponownie sprawdzić stan licencji na serwerze, zanim zezwolisz użytkownikowi na dostęp do aplikacji.

Okres i maksymalna liczba ponownych prób

W niektórych przypadkach warunki systemu lub sieci mogą uniemożliwić sprawdzenie licencji aplikacji z serwera licencyjnego albo spowodować, że odpowiedź serwera nie dotrze do aplikacji klienckiej Google Play. Na przykład użytkownik może uruchomić aplikację, gdy sieć komórkowa lub połączenie transmisji danych nie są dostępne (np. w samolocie) albo gdy połączenie sieciowe jest niestabilne lub sygnał sieci komórkowej jest słaby.

Gdy problemy z siecią uniemożliwiają sprawdzanie licencji lub przerywają sprawdzanie licencji, klient Google Play powiadamia aplikację, zwracając kod odpowiedzi RETRY do metody processServerResponse() w Policy. W przypadku problemów systemowych, np. gdy aplikacja nie może powiązać się z implementacją ILicensingService w Google Play, sama biblioteka LicenseChecker wywołuje metodę zasad processServerResponse() z kodem odpowiedzi RETRY.

Ogólnie kod odpowiedzi RETRY jest sygnałem dla aplikacji, że wystąpił błąd, który uniemożliwia ukończenie sprawdzania licencji.

Serwer Google Play pomaga aplikacji zarządzać licencjonowaniem w przypadku błędów przez ustawienie „okresu prolongaty” i zalecanej maksymalnej liczby ponownych prób. Serwer uwzględnia te wartości we wszystkich odpowiedziach dotyczących sprawdzania licencji i dołącza je jako dodatki pod kluczami GT i GR.

Aplikacja Policy może wyodrębnić dodatki GT i GR oraz użyć ich do warunkowego zezwolenia na dostęp do aplikacji w ten sposób:

  • Jeśli sprawdzanie licencji skutkuje odpowiedzią RETRY, Policy powinno buforować kod odpowiedzi RETRY i zwiększać liczbę odpowiedzi (RETRY).
  • Policy powinien umożliwiać użytkownikowi dostęp do aplikacji, pod warunkiem że okres prolongaty ponawiania jest nadal aktywny lub nie została osiągnięta maksymalna liczba ponownych prób.

ServerManagedPolicy używa podanych przez serwer wartości GT i GR, jak opisano powyżej. Przykład poniżej pokazuje warunkową obsługę odpowiedzi na ponawianie w metodzie allow(). Liczba odpowiedzi typu RETRY jest zachowywana w metodzie processServerResponse(), a nie wyświetlana.

Kotlin

fun allowAccess(): Boolean {
    val ts = System.currentTimeMillis()
    return when(lastResponse) {
        LICENSED -> {
            // Check if the LICENSED response occurred within the validity timeout.
            ts <= validityTimestamp  // Cached LICENSED response is still valid.
        }
        RETRY -> {
            ts < lastResponseTime + MILLIS_PER_MINUTE &&
                    // Only allow access if we are within the retry period
                    // or we haven't used up our max retries.
                    (ts <= retryUntil || retryCount <= maxRetries)
        }
        else -> false
    }
}

Java

public boolean allowAccess() {
    long ts = System.currentTimeMillis();
    if (lastResponse == LicenseResponse.LICENSED) {
        // Check if the LICENSED response occurred within the validity timeout.
        if (ts <= validityTimestamp) {
            // Cached LICENSED response is still valid.
            return true;
        }
    } else if (lastResponse == LicenseResponse.RETRY &&
                ts < lastResponseTime + MILLIS_PER_MINUTE) {
        // Only allow access if we are within the retry period
        // or we haven't used up our max retries.
        return (ts <= retryUntil || retryCount <= maxRetries);
    }
    return false;
}