Riferimento per le licenze

Classi e interfacce LVL

La tabella 1 elenca tutti i file di origine nella libreria di verifica delle licenze (LVL) disponibili tramite l'SDK Android. Tutti i file fanno parte del pacchetto com.android.vending.licensing.

Tabella 1. Riepilogo delle classi e delle interfacce della libreria LVL.

Categoria Nome Descrizione
Controllo e risultato della licenza Controllo licenze Classe di cui crei un'istanza (o una sottoclasse) per avviare un controllo delle licenze.
Chiamata del controllo licenza Interfaccia che implementi per gestire il risultato del controllo della licenza.
Norme Norme Interfaccia che implementi per determinare se consentire l'accesso all'applicazione, in base alla risposta della licenza.
Criterio gestito dal server Implementazione predefinita di Policy. Utilizza le impostazioni fornite dal server di licenze per gestire l'archiviazione locale dei dati delle licenze, la validità della licenza e i nuovi tentativi.
Criterio massimo Implementazione alternativa di Policy. Impone le licenze in base a una risposta di licenza diretta solo dal server. Nessuna memorizzazione nella cache o richiesta di nuovo tentativo.
Offuscamento dati
(facoltativo)
Offuscamento Interfaccia da implementare se utilizzi un Policy (ad esempio ServerManagedPolicy) che memorizza nella cache i dati delle risposte relative alla licenza in un archivio permanente. Applica un algoritmo di offuscamento per codificare e decodificare i dati scritti o letti.
Offuscamento AES Implementazione dell'offuscamento predefinita che utilizza l'algoritmo di crittografia/decrittografia AES per offuscare/non offuscare i dati.
Limitazione dei dispositivi
(facoltativo)
Limitatore di dispositivi Interfaccia da implementare per limitare l'utilizzo di un'applicazione a un dispositivo specifico. Chiamato da LicenseValidator. L'implementazione DeviceLimiter non è consigliata per la maggior parte delle applicazioni poiché richiede un server di backend e potrebbe causare la perdita dell'accesso alle applicazioni con licenza per l'utente, a meno che non sia stata progettata con attenzione.
NullDeviceLimiter Implementazione predefinita di DeviceLimiter no-op (consente l'accesso a tutti i dispositivi).
Core della libreria, nessuna integrazione necessaria DatiRisposta Classe che contiene i campi di una risposta alla licenza.
Strumento di convalida delle licenze Classe che decripta e verifica una risposta ricevuta dal server di licenze.
Eccezione Validation Classe che indica gli errori che si verificano durante la convalida dell'integrità dei dati gestiti da un offuscato.
Offuscamentopreferenza Classe di utilità che scrive/legge i dati offuscati nell'archivio SharedPreferences del sistema.
Servizio di gestione dei controlli Interfaccia IPC unidirezionale su cui viene passata una richiesta di controllo della licenza al client Google Play.
ILicenseResultListener Implementazione di callback IPC unidirezionale durante la quale l'applicazione riceve una risposta asincrona dal server di licenze.

Risposta del server

La tabella 2 elenca tutti i campi di risposta della licenza restituiti dal server di licenze.

Tabella 2. Riepilogo dei campi di risposta relativi alla licenza restituiti dal server di Google Play.

Campo Descrizione
responseCode Il codice di risposta restituito dal server di licenze. I codici di risposta sono descritti nella sezione Codici di risposta del server.
signedData Una concatenazione di stringhe che contiene i dati restituiti dal server di licenze, come segue: responseCode|nonce|packageName|versionCode|userId|timestamp:extras.
  • responseCode: il codice di risposta restituito dal server di licenze.
  • nonce: identificatore nonce della richiesta.
  • packageName: il nome del pacchetto dell'app di cui controllare la licenza.
  • versionCode: il codice della versione dell'app di cui controllare la licenza.
  • userId: un ID univoco per l'utente per app, in cui lo stesso utente riceve un ID diverso per un'altra app.
  • timestamp: il numero di millisecondi dall'epoca del 1970-01-01 00:00:00 UTC alla richiesta.
  • extras: informazioni aggiuntive per facilitare la gestione delle licenze dell'app. I campi aggiuntivi sono descritti nella sezione Extra per la risposta del server.
signature La firma di signedData che usa una chiave specifica dell'app.

Codici di risposta del server

La tabella 3 elenca tutti i codici di risposta delle licenze supportati dal server di licenze. In generale, un'applicazione dovrebbe gestire tutti questi codici di risposta. Per impostazione predefinita, la classe LicenseValidator nell'LVL ti fornisce tutte le modalità di gestione necessarie di questi codici di risposta.

Tabella 3. Riepilogo dei codici di risposta restituiti dal server di Google Play in una risposta relativa alla licenza.

Codice di risposta Rappresentazione del valore intero Descrizione Firmato? Extra Commenti
LICENSED 0 L'applicazione è concessa in licenza all'utente. L'utente ha acquistato l'applicazione o è autorizzato a scaricare e installare la versione alpha o beta dell'applicazione. VT, GT e GR Consenti l'accesso in base ai vincoli Policy.
LICENSED_OLD_KEY 2 L'applicazione è concessa in licenza all'utente, ma è disponibile una versione aggiornata dell'applicazione che è firmata con una chiave diversa. VT, GT, GR, UT Facoltativamente, consenti l'accesso in base ai vincoli Policy.

Può indicare che la coppia di chiavi utilizzata dalla versione dell'applicazione installata non è valida o è compromessa. L'applicazione può consentire l'accesso, se necessario, o informare l'utente che è disponibile un upgrade e limitarne l'utilizzo fino a quando non viene eseguito.

NOT_LICENSED 1 L'applicazione non è concessa in licenza all'utente. No Non consentire l'accesso.
ERROR_CONTACTING_SERVER 257 Errore locale. L'applicazione Google Play non è riuscita a raggiungere il server di licenze, probabilmente a causa di problemi di disponibilità della rete. No Riprova a eseguire il controllo della licenza in base ai limiti di tentativi di Policy.
ERROR_SERVER_FAILURE 4 Errore del server: il server non è riuscito a caricare la coppia di chiavi dell'applicazione per le licenze. No Riprova a eseguire il controllo della licenza in base ai limiti di tentativi di Policy.
ERROR_INVALID_PACKAGE_NAME 258 Errore locale: l'applicazione ha richiesto un controllo della licenza per un pacchetto non installato sul dispositivo. No Non riprovare a eseguire il controllo della licenza.

Generalmente causato da un errore di sviluppo.

ERROR_NON_MATCHING_UID 259 Errore locale: l'applicazione ha richiesto un controllo della licenza per un pacchetto il cui UID (pacchetto, coppia di ID utente) non corrisponde a quello dell'applicazione richiedente. No Non riprovare a eseguire il controllo della licenza.

Generalmente causato da un errore di sviluppo.

ERROR_NOT_MARKET_MANAGED 3 Errore del server. L'applicazione (nome del pacchetto) non è stata riconosciuta da Google Play. No Non riprovare a eseguire il controllo della licenza.

Può indicare che l'applicazione non è stata pubblicata tramite Google Play o che si è verificato un errore di sviluppo nell'implementazione delle licenze.

Nota: come documentato in Configurare l'ambiente di test, il codice di risposta può essere sostituito manualmente per lo sviluppatore dell'applicazione e gli utenti di test registrati tramite Google Play Console.

Nota: in precedenza, potevi testare un'app caricando una versione "bozza" non pubblicata. Questa funzionalità non è più supportata; devi pubblicarla sul canale di distribuzione alpha o beta. Per ulteriori informazioni, vedi Le bozze di app non sono più supportate.

Opzioni aggiuntive per la risposta del server

Per aiutare l'applicazione a gestire l'accesso all'applicazione per tutto il periodo di rimborso dell'applicazione e fornire altre informazioni, il server di licenze include diverse informazioni nelle risposte relative alle licenze. In particolare, il servizio fornisce valori consigliati per il periodo di validità della licenza dell'applicazione, il periodo di tolleranza per i nuovi tentativi, il numero massimo di tentativi consentiti e altre impostazioni. Se l'applicazione utilizza file di espansione APK, la risposta include anche i nomi, le dimensioni e gli URL dei file. Il server aggiunge le impostazioni come coppie chiave-valore nel campo "extra" della risposta della licenza.

Qualsiasi implementazione di Policy può estrarre le impostazioni extra dalla risposta di licenza e utilizzarle in base alle esigenze. L'implementazione predefinita di LVL, Policy, ServerManagedPolicy, funge da implementazione funzionante e da illustrazione di come ottenere, archiviare e utilizzare le impostazioni.

Tabella 4. Riepilogo delle impostazioni di gestione delle licenze fornite dal server di Google Play in una risposta relativa alle licenze.

ExtraDescrizione
VT Timestamp della validità della licenza. Specifica la data e l'ora di scadenza della risposta per la licenza attuale (memorizzata nella cache) e deve essere ricontrollata sul server di licenze. Consulta la sezione di seguito relativa al Periodo di validità della licenza.
GT Timestamp del periodo di tolleranza. Specifica la fine del periodo durante il quale un criterio può consentire l'accesso all'applicazione, anche se lo stato della risposta è RETRY.

Il valore è gestito dal server, ma un valore tipico è di almeno 5 giorni. Consulta la sezione di seguito per informazioni su Periodo di nuovi tentativi e numero massimo di tentativi.

GR Numero massimo di nuovi tentativi. Specifica il numero di controlli consecutivi delle licenze RETRY consentiti da Policy prima di negare l'accesso dell'utente all'applicazione.

Il valore è gestito dal server, tuttavia un valore tipico è "10" o superiore. Consulta la sezione di seguito per informazioni su Periodo di nuovi tentativi e numero massimo di tentativi.

UT Aggiorna timestamp. Specifica il giorno e l'ora in cui è stato caricato e pubblicato l'aggiornamento più recente di questa applicazione.

Il server restituisce questo extra solo per le risposte LICENSED_OLD_KEYS, per consentire a Policy di determinare quanto tempo è trascorso dalla pubblicazione di un aggiornamento con le nuove chiavi di licenza prima di negare l'accesso dell'utente all'applicazione.

FILE_URL1 o FILE_URL2 L'URL di un file di espansione (1 è per il file principale, 2 è il file di patch). Utilizzalo per scaricare il file tramite HTTP.
FILE_NAME1 o FILE_NAME2 Il nome del file di espansione (1 è per il file principale, 2 è il file di patch). Devi utilizzare questo nome per il salvataggio del file sul dispositivo.
FILE_SIZE1 o FILE_SIZE2 La dimensione del file in byte (1 corrisponde al file principale, 2 al file di patch). Utilizza questa opzione per facilitare il download e assicurarti che sia disponibile spazio sufficiente nella posizione di archiviazione condivisa del dispositivo prima del download.

Periodo di validità della licenza

Il server di licenze di Google Play imposta un periodo di validità della licenza per tutte le applicazioni scaricate. Il periodo rappresenta l'intervallo di tempo entro il quale lo stato della licenza di un'applicazione deve essere considerato non modificabile e memorizzabile nella cache da una licenza Policy nell'applicazione. Il server di licenze include il periodo di validità nella risposta a tutti i controlli delle licenze, aggiungendo alla risposta un timestamp di fine validità come extra sotto la chiave VT. Un Policy può estrarre il valore chiave VT e utilizzarlo per consentire l'accesso all'applicazione in modo condizionale senza controllare nuovamente la licenza, fino alla scadenza del periodo di validità.

La validità della licenza segnala a un Policy di licenza quando deve ricontrollare lo stato delle licenze con il server di licenze. Non intende lasciare intendere se un'applicazione sia effettivamente autorizzata per l'utilizzo. In altre parole, quando il periodo di validità della licenza di un'applicazione scade, non significa che l'applicazione non sia più autorizzata per l'utilizzo, ma indica soltanto che Policy deve ricontrollare lo stato della licenza con il server. Ne consegue che, a condizione che il periodo di validità della licenza non sia scaduto, è accettabile che Policy memorizzi nella cache lo stato iniziale della licenza localmente e restituisca lo stato della licenza memorizzato nella cache, anziché inviare un nuovo controllo della licenza al server.

Il server di licenze gestisce il periodo di validità come mezzo per aiutare l'applicazione ad applicare correttamente le licenze per tutto il periodo di rimborso offerto da Google Play per le applicazioni a pagamento. Imposta il periodo di validità a seconda che l'applicazione sia stata acquistata e, in tal caso, da quanto tempo. Nello specifico, il server imposta un periodo di validità come segue:

  • Per un'applicazione a pagamento, il server imposta il periodo di validità iniziale della licenza in modo che la risposta relativa alla licenza rimanga valida per tutto il tempo in cui la richiesta è rimborsabile. Una licenza Policy nell'applicazione potrebbe memorizzare nella cache il risultato del controllo iniziale della licenza e non sarà necessario ricontrollare la licenza fino alla scadenza del periodo di validità.
  • Quando un'applicazione non è più rimborsabile, il server imposta un periodo di validità più lungo, in genere di alcuni giorni.
  • Per un'applicazione senza costi, il server imposta il periodo di validità su un valore molto alto (long.MAX_VALUE). In questo modo, se Policy ha memorizzato localmente nella cache il timestamp di validità, non dovrà ricontrollare lo stato della licenza dell'applicazione in futuro.

L'implementazione ServerManagedPolicy utilizza il timestamp estratto (mValidityTimestamp) come condizione principale per determinare se verificare nuovamente lo stato della licenza con il server prima di consentire all'utente di accedere all'applicazione.

Periodo di nuovi tentativi e numero massimo di nuovi tentativi

In alcuni casi, le condizioni di sistema o di rete possono impedire al controllo delle licenze di un'applicazione di raggiungere il server di licenze o impedire alla risposta del server di raggiungere l'applicazione client di Google Play. Ad esempio, l'utente potrebbe avviare un'applicazione quando non è disponibile una rete cellulare o una connessione dati, ad esempio in aereo, o quando la connessione di rete è instabile o il segnale cellulare è debole.

Quando i problemi di rete impediscono o interrompono un controllo delle licenze, il client Google Play avvisa l'applicazione restituendo un codice di risposta RETRY al metodo processServerResponse() di Policy. Per problemi di sistema, ad esempio quando l'applicazione non è in grado di associarsi con l'implementazione ILicensingService di Google Play, la libreria LicenseChecker stessa chiama il metodo processServerResponse() dei criteri con un codice di risposta RETRY.

In generale, il codice di risposta RETRY segnala all'applicazione che si è verificato un errore che ha impedito il completamento di un controllo della licenza.

Il server di Google Play consente a un'applicazione di gestire le licenze in caso di errore impostando un "periodo di tolleranza" per i nuovi tentativi e un numero massimo consigliato di nuovi tentativi. Il server include questi valori in tutte le risposte al controllo delle licenze, aggiungendoli come extra nelle chiavi GT e GR.

L'applicazione Policy può estrarre gli extra GT e GR e usarli per consentire in modo condizionale l'accesso all'applicazione, come segue:

  • Per un controllo della licenza che genera una risposta RETRY, Policy deve memorizzare nella cache il codice di risposta RETRY e incrementare il numero di risposte RETRY.
  • Policy deve consentire all'utente di accedere all'applicazione, a condizione che il periodo di tolleranza per i nuovi tentativi sia ancora attivo o che non sia stato raggiunto il numero massimo di nuovi tentativi.

ServerManagedPolicy utilizza i valori GT e GR forniti dal server, come descritto sopra. L'esempio seguente mostra la gestione condizionale delle risposte ai nuovi tentativi nel metodo allow(). Il numero di risposte RETRY viene mantenuto nel metodo processServerResponse(), non visualizzato.

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;
}