Конфигурация приложения в Android: быстрая разработка

    imageПри разработке мобильных приложений зачастую возникает необходимость хранить настройки приложения (выбранную пользователем цветовую тему, пароль доступа к приложению, параметры синхронизации с сервером и т.д.). Поскольку такие задачи возникают довольно часто, в Google позаботились о разработчиках и создали механизм для быстрой и легкой реализации данного функционала. Этот механизм позволяет легко создавать, сохранять, отображать и производить разные манипуляции с настройками приложения. Мало того он позволяет автоматически создавать пользовательский интерфейс. При описании типа параметра настроек — автоматически генерируется часть пользовательского интерфейса в зависимости от типа параметра (boolean — чекбокс, String — поле ввода, ...) без написания кода. Звучит неплохо для быстрой разработки, не так ли?

    Первым шагом в реализации механизма настроек приложения является наследования активности экрана вашего приложения от класса PreferenceActivity. Этот класс наследован от класса ListActivity
    и позволяет создавать пользовательский интерфейс по описанию в XML файле ресурсов. Мало того, этот класс позволяет автоматически сохранять настройки в SharedPreferences незаметно для вас. SharedPreferences — интерфейс позволяющий обращаться и манипулировать данными настройки приложения вручную с помощью вызова метода getSharedPreferences из вашего Activity (подробнее Android Essentials: Application Preferences). Для того что бы увязать вместе наш класс унаследованный от PreferenceActivity и XML файл описывающий параметры конфигурации используется метод addPreferencesFromResource:

    1. ...
    2. @Override
    3. public void onCreate(Bundle savedInstanceState) {     
    4.     super.onCreate(savedInstanceState);        
    5.     addPreferencesFromResource(R.xml.preferences);        
    6. }
    7. ...

    Теперь необходимо создать файл res/xml/preferences.xml который является описанием нашего списка параметров конфигурации приложения и будет подхвачен нашим PreferenceActivity. Этот XML файл имеет специфический формат позволяющий описывать типы параметров конфигурации. Все типы вытекают из класса Preference который представляет собой базовый блок пользовательского интерфейса и генерирует View которое в последствии отобразится в нужном месте пользовательского интерфейса и будет ассоциироваться с объектом SharedPreferences который можно будет извлекать и сохранять. Рассмотрим часто используемые подклассы, которые используются для описание типов параметров конфигурации:
    • CheckBoxPreference: чекбокс, представляет параметры типа boolean.
    • RingtonePreference: позволяет выбирать рингтон из доступных на устройстве. URI выбранного файла рингтона будет представлен в виде строки.
    • EditTextPreference: строка ввода текста, представляет параметры типа String.
    • ListPreference: показывает список возможных значений параметра в виде диалога, представляет параметры типа String.

    Также необходимо отметить, что отдельные параметры могут группироваться в категории с помощью класса PreferenceCategory, который группирует объекты Preference и выводит неактивный заголовок группы.

    Теперь опишем, что же мы хотим видеть в нашем XML описании. У нас будет две категории. В первой разместим CheckBoxPreference который будет активировать/дезактивировать синхронизацию данных нашего гипотетического приложения и ListPreference в которым будем задавать частоту синхронизации данных. Как вы уже наверняка заметили, между этими двумя параметрами есть зависимость, если первый не выбран, то второй нужно дезактивировать. Это достигается с помощью использования атрибута android:dependency. Во второй категории мы разместим EditTextPreference с помощью которого будем задавать текст приветствия. Представим все это в виде XML:
    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <PreferenceScreen xmlns:android="schemas.android.com/apk/res/android">
    4.  
    5.     <PreferenceCategory 
    6.         android:title="First Category"
    7.         android:key="first_category">
    8.  
    9.         <CheckBoxPreference 
    10.             android:key="perform_updates"
    11.             android:summary="Enable or disable data updates"
    12.             android:title="Enable updates" 
    13.             android:defaultValue="true"
    14.         />
    15.  
    16.         <ListPreference 
    17.             android:key="updates_interval"
    18.             android:title="Updates interval"
    19.             android:summary="Define how often updates will be performed"
    20.             android:defaultValue="1000" 
    21.             android:entries="@array/updateInterval"
    22.             android:entryValues="@array/updateIntervalValues"
    23.             android:dependency="perform_updates"
    24.         />    
    25.  
    26.     </PreferenceCategory>
    27.  
    28.     <PreferenceCategory 
    29.         android:title="Second Category"
    30.         android:key="second_category">
    31.  
    32.         <EditTextPreference
    33.             android:key="welcome_message"
    34.             android:title="Welcome Message" 
    35.             android:summary="Define the Welcome message to be shown"
    36.             android:dialogTitle="Welcome Message"
    37.             android:dialogMessage="Provide a message"    
    38.             android:defaultValue="Default welcome message" />
    39.  
    40.     </PreferenceCategory>
    41.  
    42. </PreferenceScreen>

    Заметьте, что для ListPreference мы указали атрибут android:entries который указывает на место хранения возможных значений списка. Эти значения хранятся в XML файле res/values/arrays.xml. Значения “updateInterval” and “updateIntervalValue” хранятся в этом файле. На самом деле это просто пары ключ-значение, ключи хранятся в первом массиве, а значения — во втором:
    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <resources>
    4.  
    5.     <string-array name="updateInterval">
    6.         <item name="1000">Every 1 second</item>
    7.         <item name="5000">Every 5 seconds</item>
    8.         <item name="30000">Every 30 seconds</item>
    9.         <item name="60000">Every 1 minute</item>
    10.         <item name="300000">Every 5 minutes</item>
    11.     </string-array>
    12.  
    13.     <string-array name="updateIntervalValues">
    14.         <item name="1000">1000</item>
    15.         <item name="5000">5000</item>
    16.         <item name="30000">30000</item>
    17.         <item name="60000">60000</item>
    18.         <item name="300000">300000</item>
    19.     </string-array>
    20.  
    21. </resources>

    Добавлю еще один полезный момент, который может пригодиться. Очень часто необходимо ограничить доступ к приложению с помощью пароля или PIN кода который задается в конфигурации приложения. Очевидно что для этих целей используется EditTextPreference. Но было бы неплохо в случае пароля или PIN-кода скрывать введенные символы, а для кода еще и ограничить ввод только цифрами. Для этого можно использовать атрибуты android:password и android:inputType соответственно:
    1. <EditTextPreference
    2.             android:key="pin"
    3.             android:title="PIN code" 
    4.             android:summary="If login screen is enabled"
    5.             android:dialogTitle="PIN code"
    6.             android:dialogMessage="Provide a PIN"    
    7.             android:defaultValue=""
    8.             android:inputType="number"
    9.             android:password="true"
    10.             android:dependency="runLoginScreen"
    11. />

    Как говорилось выше, основную часть работы берет на себя сам andriod-фреймворк. Для того чтобы показать как читать уже заданные параметры мы создадим еще одну активность экрана, которая будет запускаться из нашей главной активности. Но вначале посмотрим на код главной:
    1. package com.javacodegeeks.android.preferences;
    2.  
    3. import android.content.Intent;
    4. import android.os.Bundle;
    5. import android.preference.PreferenceActivity;
    6. import android.view.Menu;
    7. import android.view.MenuItem;
    8.  
    9. public class QuickPrefsActivity extends PreferenceActivity {
    10.  
    11.     @Override
    12.     public void onCreate(Bundle savedInstanceState) {        
    13.         super.onCreate(savedInstanceState);        
    14.         addPreferencesFromResource(R.xml.preferences);        
    15.     }
    16.  
    17.     @Override
    18.     public boolean onCreateOptionsMenu(Menu menu) {
    19.         menu.add(Menu.NONE00"Show current settings");
    20.         return super.onCreateOptionsMenu(menu);
    21.     }
    22.  
    23.     @Override
    24.     public boolean onOptionsItemSelected(MenuItem item) {
    25.         switch (item.getItemId()) {
    26.             case 0:
    27.                 startActivity(new Intent(this, ShowSettingsActivity.class));
    28.                 return true;
    29.         }
    30.         return false;
    31.     }
    32.  
    33. }

    Мы создали опционное меню с одним элементом MenuItem с помощью метода onCreateOptionsMenu. Когда пользователь кликает на элемент меню, мы обрабатываем это событие в методе onOptionsItemSelected и запускаем новую активность используя метод startActivity. (подробнее Using options menus and customized dialogs for user interaction, Launching new activities with intents).

    Теперь создадим вторую активность ShowSettingsActivity для отображения параметров конфигурации приложения. Но вначале мы должны описать новую активность в manifest файле AndroidManifest.xml:
    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <manifest xmlns:android="schemas.android.com/apk/res/android"
    4.       package="com.javacodegeeks.android.preferences"
    5.       android:versionCode="1"
    6.       android:versionName="1.0">
    7.  
    8.     <application android:icon="@drawable/icon" android:label="@string/app_name">
    9.  
    10.         <activity android:name=".QuickPrefsActivity" android:label="@string/app_name">
    11.             <intent-filter>
    12.                 <action android:name="android.intent.action.MAIN" />
    13.                 <category android:name="android.intent.category.LAUNCHER" />
    14.             </intent-filter>
    15.         </activity>
    16.  
    17.         <activity android:name=".ShowSettingsActivity" />
    18.  
    19.     </application>
    20.  
    21.     <uses-sdk android:minSdkVersion="3" />
    22.  
    23. </manifest> 

    Код второй активности выглядит так:
    1. package com.javacodegeeks.android.preferences;
    2.  
    3. import android.app.Activity;
    4. import android.content.SharedPreferences;
    5. import android.os.Bundle;
    6. import android.preference.PreferenceManager;
    7. import android.widget.TextView;
    8.  
    9. public class ShowSettingsActivity extends Activity {
    10.  
    11.     @Override
    12.     protected void onCreate(Bundle savedInstanceState) {
    13.  
    14.         super.onCreate(savedInstanceState);
    15.         setContentView(R.layout.show_settings_layout);
    16.  
    17.         SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
    18.  
    19.         StringBuilder builder = new StringBuilder();
    20.  
    21.         builder.append("n" + sharedPrefs.getBoolean("perform_updates"false));
    22.         builder.append("n" + sharedPrefs.getString("updates_interval""-1"));
    23.         builder.append("n" + sharedPrefs.getString("welcome_message""NULL"));
    24.  
    25.         TextView settingsTextView = (TextView) findViewById(R.id.settings_text_view);
    26.         settingsTextView.setText(builder.toString());
    27.  
    28.     }
    29.  
    30. }

    Здесь мы извлекаем параметры конфигурации приложения в виде класса SharedPreferences с помощью статического метода getDefaultSharedPreferences класса PreferenceManager. Далее, в зависимости от типа данных параметра, мы используем соответствующий метод извлечения данных (например getBoolean или getString). Второй аргумент в методе извлечения данных — значение по умолчанию, на тот случай если параметр с таким именем еще не был задан. В качестве имен параметров мы используем ключи заданные в XML файле preferences.xml. Значения параметров конкатенируются и выводятся в TextView.

    Вот описание простого пользовательского интерфейса для второй активности:
    1. <?xml version="1.0" encoding="utf-8"?>
    2.  
    3. <LinearLayout 
    4.     xmlns:android="schemas.android.com/apk/res/android"
    5.     android:orientation="vertical"
    6.     android:layout_width="fill_parent"
    7.     android:layout_height="fill_parent"
    8.     >
    9.  
    10.     <TextView
    11.         android:id="@+id/settings_text_view"
    12.         android:layout_width="fill_parent" 
    13.         android:layout_height="wrap_content"
    14.     />
    15.  
    16. </LinearLayout>

    Давайте запустим приложение, мы увидим список наших параметров:

    image

    Кликаем на “Updates Interval” и видим список возможных значений:

    Список возможных значений параметра

    Кликаем на “Welcome Message” и видим редактирование текста приветствия:

    Редактирования текста приветствия

    Посмотрим на заданные параметры. Кликнете на кнопке меню и выберете единственный элемент “Show current settings”. Запуститься вторая активность в которой мы увидим значения наших параметров конфигурации:

    image

    Это все. Как видите, это действительно просто. Удачи!

    Оригинал: Android Quick Preferences Tutorial
    Поделиться публикацией

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое