Android 101: Guardar e ler as preferências do utilizador

Permitir aos utilizadores configurar a aplicação ao seu gosto é uma das funcionalidades básicas de uma aplicação. Neste artigo vou descrever como construir um ecrã de preferências para uma aplicação Android e como guardar e ler as preferências do utilizador.

Como criar um ecrã de preferências no Android

Um ecrã de preferências cria-se da seguinte forma:

  • Criar uma pasta xml na pasta res.
  • Criar um ficheiro preferences.xml (especificar que é um recurso do tipo Preference).

O elemento raiz das preferências deve ser um PreferenceScreen. Agora é necessário adicionar as diferentes opções.

  • Usa-se uma PreferenceCategory para separar as opções em determinados grupos.
  • Existem diferentes widgets de preferências como CheckBoxPreference, ListPreference e EditTextPreference, entre outros.

Para cada preferência é necessário especificar uma chave, um título e uma descrição. Também é possível especificar valores padrão, opções de persistência e outras propriedades específicas a cada widget.

Eis um exemplo de um ficheiro de preferências da aplicação Honeybuzz:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="@string/pref_category_design">
        <ListPreference
            android:title="@string/pref_theme_title"
            android:summary="@string/pref_theme_summary"
            android:key="honeybuzz.theme"
            android:persistent="true"
            android:defaultValue="AppTheme.Light"
            android:entries="@array/themeNames"
            android:entryValues="@array/themeValues" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/pref_category_service">
        <ListPreference
            android:title="@string/pref_interval_title"
            android:summary="@string/pref_interval_summary"
            android:key="honeybuzz.interval"
            android:persistent="true"
            android:defaultValue="30"
            android:entries="@array/intervalNames"
            android:entryValues="@array/intervalValues" />
    </PreferenceCategory>
    <PreferenceCategory android:title="@string/pref_category_error">
        <CheckBoxPreference android:key="acra.enable"
            android:persistent="true"
            android:title="@string/pref_disable_acra"
            android:summaryOn="@string/pref_acra_enabled"
            android:summaryOff="@string/pref_acra_disabled"
            android:defaultValue="true"/>
        <CheckBoxPreference android:key="acra.syslog.enable"
            android:persistent="true"
            android:title="@string/pref_acra_syslog"
            android:summaryOn="@string/pref_acra_syslog_enabled"
            android:summaryOff="@string/pref_acra_syslog_disabled"
            android:defaultValue="true"/>
        <CheckBoxPreference android:key="acra.alwaysaccept"
            android:persistent="true"
            android:title="@string/pref_acra_alwaysaccept"
            android:summaryOn="@string/pref_acra_alwaysaccept_enabled"
            android:summaryOff="@string/pref_acra_alwaysaccept_disabled"
            android:defaultValue="false"/>
    </PreferenceCategory>
</PreferenceScreen>

Nota: A ListPreferences só funciona com vectores de strings. Não é possível usar vectores de inteiros (ou de outro tipo qualquer) com a ListPreferences, caso contrário será gerado um erro.

Criar uma Activity para as preferências

Agora que as preferências foram definidas, é necessário criar uma Activy para as mostrar, devendo ser uma sub-classe da PreferenceActivity e adicionar as preferências partir de um ficheiro de recurso.

package com.quasibit.honeybuzz;

import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;

public class HoneybuzzPreferences extends PreferenceActivity {
      @Override 
      public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 

        PreferenceManager prefMgr = getPreferenceManager();
        prefMgr.setSharedPreferencesName(HoneybuzzApplication.PREFERENCES_NAME);
        prefMgr.setSharedPreferencesMode(HoneybuzzApplication.PREFERENCES_MODE);
        
        addPreferencesFromResource(R.xml.preferences); 
      }
}

Especificamos também o nome e o modo das preferências.

Na classe principal da aplicação definimos as constantes das preferências e estabelecemos os valores padrão do PreferenceManager.

public class HoneybuzzApplication extends Application {
    public static final String PREFERENCES_NAME = "HoneybuzzPrefs";
    public static final int PREFERENCES_MODE = MODE_PRIVATE;

    public static final String PREFERENCE_THEME = "honeybuzz.theme";
    public static final String PREFERENCE_ISFIRSTUSE = "honeybuzz.firstuse";
    public static final String PREFERENCE_INTERVAL = "honeybuzz.interval";
    
    @Override
    public void onCreate() {
        ...

        PreferenceManager.setDefaultValues(this, PREFERENCES_NAME, PREFERENCES_MODE, R.xml.preferences, false); // set default preferences
        super.onCreate();
    }

    public static SharedPreferences getSharedPreferences() {
        return getInstance().getSharedPreferences(PREFERENCES_NAME, PREFERENCES_MODE);
    }
}

Para iniciar a Activity das preferências adicionamos uma opção ao menu da aplicação e chamamos o ecrã desta forma:

startActivity(new Intent(this, HoneybuzzPreferences.class));

O resultado final é o seguinte:

Como ler as preferências do utilizador

Como adicionamos um método auxiliar à classe principal da aplicação, vamos usá-lo para ir buscar as preferências do utilizador.

Neste exemplo lemos o theme seleccionado pelo utilizador:

SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
String themeName = prefs.getString(HoneybuzzApplication.PREFERENCE_THEME, "AppTheme.Light");

Desta forma torna-se fácil ler as preferências do utilizador.

SeekBarPreference

Cedo descobre-se que não há um widget SeekBarPreference. Este é um tipo comum que é útil em muitas situações diferentes. Uma SeekBarPreference é no fundo um slider, útil para preferências numéricas ou de outros tipos.

Felizmente já várias pessoas passaram por isto e decidiram partilhar os seus widgets.

Encontrei vários exemplos e cada um deles diferente, por isso verifiquem-nos e escolham o mais apropriado:

Mais recursos

Artigos relacionados