Usar valores de preferência salvos Parte do Android Jetpack.

Neste documento, descrevemos como armazenar e usar Preference valores salvos por da biblioteca Preference.

Armazenamento de dados de preferências

Esta seção descreve como uma Preference pode manter dados.

SharedPreferences

Por padrão, um Preference usa SharedPreferences para salvar e a distribuição dos valores dos dados. A API SharedPreferences é compatível com leitura e gravação pares de chave-valor de um arquivo que é salvo nas sessões do aplicativo. A A biblioteca Preference usa uma instância particular de SharedPreferences para que apenas sua o aplicativo possa acessá-lo.

Como exemplo, considere o seguinte SwitchPreferenceCompat:

<SwitchPreferenceCompat
        app:key="notifications"
        app:title="Enable message notifications"/>

Quando um usuário ativa essa opção estado, o arquivo SharedPreferences é atualizado com um par de chave-valor de "notifications" : "true". A chave usada é a mesma que a chave definida para a Preference.

Para saber mais sobre a API SharedPreferences, consulte Salvar chave-valor dados.

Para saber mais sobre as diferentes maneiras de armazenar dados no Android, consulte Dados e o armazenamento de arquivos.

PreferenceDataStore

Embora a biblioteca Preference mantenha os dados com SharedPreferences por por padrão, SharedPreferences nem sempre são a solução ideal. Por exemplo, se seu aplicativo exige que um usuário faça login, você pode querer persistir as configurações do aplicativo na nuvem para que elas sejam refletidas em outros dispositivos e plataformas. Da mesma forma, se o aplicativo tiver configurações específicas do dispositivo, cada usuário no dispositivo tem configurações separadas, o que torna SharedPreferences uma solução menos do que ideal.

Uma PreferenceDataStore permite usar um back-end de armazenamento personalizado para manter os valores de Preference. Para mais informações, consulte Usar um repositório de dados personalizado.

Ler valores de preferência

Para recuperar o objeto SharedPreferences que está sendo usado, chame PreferenceManager.getDefaultSharedPreferences(). Embora esse método funcione em qualquer lugar do aplicativo, recomendamos que você divide seu app em camadas. Para mais informações, consulte Dados camada.

Por exemplo, considerando um EditTextPreference com uma chave de "signature", conforme da seguinte forma:

<EditTextPreference
        app:key="signature"
        app:title="Your signature"/>

É possível recuperar o valor salvo para esse Preference globalmente da seguinte maneira:

Kotlin

val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this /* Activity context */)
val name = sharedPreferences.getString("signature", "")

Java

SharedPreferences sharedPreferences =
        PreferenceManager.getDefaultSharedPreferences(this /* Activity context */);
String name = sharedPreferences.getString("signature", "");

Detectar as mudanças nos valores de preferência

Para detectar mudanças em valores de Preference, você pode escolher entre duas interfaces:

A tabela a seguir mostra as diferenças entre as duas interfaces:

OnPreferenceChangeListener OnSharedPreferenceChangeListener
Definido em uma única Preference. Aplicável a todos os objetos Preference.
Chamado quando uma Preference está prestes a mudar o valor salvo. mesmo que o valor pendente seja igual ao salvo. Chamado apenas quando o valor salvo para um Preference muda.
Chamada somente pela biblioteca Preference. Uma parte separada do aplicativo podem alterar o valor salvo. Chamada sempre que o valor salvo é alterado, mesmo que seja de uma origem do aplicativo.
Chamada antes de o valor pendente ser salvo. Chamado depois que o valor é salvo.
Chamado ao usar SharedPreferences ou um PreferenceDataStore. Chamada somente ao usar SharedPreferences.

Implementar OnPreferenceChangeListener

A implementação de um OnPreferenceChangeListener permite detectar um mude para o valor de um Preference. Depois, é possível validar se a mudança de segurança. Por exemplo, o código a seguir mostra como detectar uma mudança no de um EditTextPreference com uma chave de "name":

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    Log.e("preference", "Pending Preference value is: $newValue")
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.e("preference", "Pending Preference value is: " + newValue);
    return true;
}

Em seguida, você precisa definir esse listener diretamente com setOnPreferenceChangeListener(), da seguinte forma:

Kotlin

preference.onPreferenceChangeListener = ...

Java

preference.setOnPreferenceChangeListener(...);

Implementar OnSharedPreferenceChangeListener

Ao manter valores de Preference usando SharedPreferences, você também pode usar um SharedPreferences.OnSharedPreferenceChangeListener para detectar mudanças. Isso permite detectar quando os valores salvos pelo Preference são alterados. como ao sincronizar configurações com um servidor. O exemplo abaixo mostra como detectar uma mudança no valor de uma EditTextPreference com uma chave de "name":

Kotlin

override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
    if (key == "signature") {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""))
    }
}

Java

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    if (key.equals("signature")) {
        Log.i(TAG, "Preference value was updated to: " + sharedPreferences.getString(key, ""));
    }
}

Registre o listener usando registerOnSharedPreferenceChangedListener(), da seguinte forma:

Kotlin

preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(...)

Java

getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(...);

Kotlin

    val listener: SharedPreferences.OnSharedPreferenceChangeListener =
            SharedPreferences.OnSharedPreferenceChangeListener {...}
    

Java

    SharedPreferences.OnSharedPreferenceChangeListener listener =
            new SharedPreferences.OnSharedPreferenceChangeListener() {...}
    

Para um gerenciamento adequado do ciclo de vida no Activity ou no Fragment, registre e Cancele o registro desse listener nos callbacks onResume() e onPause(), conforme mostrado. no exemplo a seguir:

Kotlin

override fun onResume() {
    super.onResume()
    preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}

override fun onPause() {
    super.onPause()
    preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
}

Java

@Override
public void onResume() {
    super.onResume();
    getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

Usar um repositório de dados personalizado

Embora seja recomendado manter objetos Preference usando SharedPreferences, também é possível usar um repositório de dados personalizado. Um repositório de dados personalizado pode ser útil se seus mantém os valores em um banco de dados ou se os valores são específicos do dispositivo, como como mostrado nos exemplos a seguir.

Implementar o repositório de dados

Para implementar um repositório de dados personalizado, crie uma classe que estenda PreferenceDataStore: O exemplo a seguir cria um repositório de dados que manipula Valores String:

Kotlin

class DataStore : PreferenceDataStore() {
    override fun putString(key: String, value: String?) {
        // Save the value somewhere.
    }

    override fun getString(key: String, defValue: String?): String? {
        // Retrieve the value.
    }
}

Java

public class DataStore extends PreferenceDataStore {
    @Override
    public void putString(String key, @Nullable String value) {
        // Save the value somewhere.
    }
    @Override
    @Nullable
    public String getString(String key, @Nullable String defValue) {
        // Retrieve the value.
    }
}

Execute operações demoradas fora da linha de execução principal para evitar o bloqueio do usuário interface gráfica do usuário. Como é possível que Fragment ou Activity que contenham o armazenamento de dados seja destruído enquanto um valor persiste, serialize os dados para não perca os valores alterados pelo usuário.

Ativar o repositório de dados

Depois de implementar seu repositório de dados, defina o novo repositório de dados em onCreatePreferences() para que objetos Preference mantenham os valores com o em vez de usar o SharedPreferences padrão. É possível ativar repositório de dados para cada Preference ou para toda a hierarquia.

Para ativar um repositório de dados personalizado para um Preference específico, chame setPreferenceDataStore() no Preference, conforme mostrado no exemplo a seguir:

Kotlin

val preference: Preference? = findPreference("key")
preference?.preferenceDataStore = dataStore

Java

Preference preference = findPreference("key");
if (preference != null) {
    preference.setPreferenceDataStore(dataStore);
}

Para ativar um repositório de dados personalizado para uma hierarquia inteira, chame setPreferenceDataStore() no PreferenceManager:

Kotlin

val preferenceManager = preferenceManager
preferenceManager.preferenceDataStore = dataStore

Java

PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setPreferenceDataStore(dataStore);

Um repositório de dados definido para uma Preference específica substitui qualquer repositório de dados que para a hierarquia correspondente. Na maioria dos casos, você define um repositório de dados para em toda a hierarquia.