- PVSM.RU - https://www.pvsm.ru -

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

imageПри разработке мобильных приложений зачастую возникает необходимость хранить настройки приложения (выбранную пользователем цветовую тему, пароль доступа к приложению, параметры синхронизации с сервером и т.д.). Поскольку такие задачи возникают довольно часто, в Google позаботились о разработчиках и создали механизм для быстрой и легкой реализации данного функционала. Этот механизм позволяет легко создавать, сохранять, отображать и производить разные манипуляции с настройками приложения. Мало того он позволяет автоматически создавать пользовательский интерфейс. При описании типа параметра настроек — автоматически генерируется часть пользовательского интерфейса в зависимости от типа параметра (boolean — чекбокс, String — поле ввода, ...) без написания кода. Звучит неплохо для быстрой разработки, не так ли?
PreferenceActivity [1]. Этот класс наследован от класса ListActivity
[2] и позволяет создавать пользовательский интерфейс по описанию в XML файле ресурсов. Мало того, этот класс позволяет автоматически сохранять настройки в SharedPreferences [3] незаметно для вас. SharedPreferences [3] — интерфейс позволяющий обращаться и манипулировать данными настройки приложения вручную с помощью вызова метода getSharedPreferences [4] из вашего Activity [5] (подробнее Android Essentials: Application Preferences [6]). Для того что бы увязать вместе наш класс унаследованный от PreferenceActivity и XML файл описывающий параметры конфигурации используется метод addPreferencesFromResource [7]:

  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 [1]. Этот XML файл имеет специфический формат позволяющий описывать типы параметров конфигурации. Все типы вытекают из класса Preference [8] который представляет собой базовый блок пользовательского интерфейса и генерирует View [9] которое в последствии отобразится в нужном месте пользовательского интерфейса и будет ассоциироваться с объектом SharedPreferences [3] который можно будет извлекать и сохранять. Рассмотрим часто используемые подклассы, которые используются для описание типов параметров конфигурации:

  • CheckBoxPreference [10]: чекбокс, представляет параметры типа boolean [11].
  • RingtonePreference [12]: позволяет выбирать рингтон из доступных на устройстве. URI выбранного файла рингтона будет представлен в виде строки.
  • EditTextPreference [13]: строка ввода текста, представляет параметры типа String [14].
  • ListPreference [15]: показывает список возможных значений параметра в виде диалога, представляет параметры типа String [14].

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

Теперь опишем, что же мы хотим видеть в нашем XML описании. У нас будет две категории. В первой разместим CheckBoxPreference [10] который будет активировать/дезактивировать синхронизацию данных нашего гипотетического приложения и ListPreference [15] в которым будем задавать частоту синхронизации данных. Как вы уже наверняка заметили, между этими двумя параметрами есть зависимость, если первый не выбран, то второй нужно дезактивировать. Это достигается с помощью использования атрибута android:dependency [17]. Во второй категории мы разместим EditTextPreference [13] с помощью которого будем задавать текст приветствия. Представим все это в виде XML:

  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <PreferenceScreen xmlns:android="schemas.android.com/apk/res/android" [18]>
  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 [15] мы указали атрибут android:entries [19] который указывает на место хранения возможных значений списка. Эти значения хранятся в 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 [13]. Но было бы неплохо в случае пароля или PIN-кода скрывать введенные символы, а для кода еще и ограничить ввод только цифрами. Для этого можно использовать атрибуты android:password [20] и android:inputType [21] соответственно:

  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 [22] с помощью метода onCreateOptionsMenu [23]. Когда пользователь кликает на элемент меню, мы обрабатываем это событие в методе onOptionsItemSelected [24] и запускаем новую активность используя метод startActivity [25]. (подробнее Using options menus and customized dialogs for user interaction [26], Launching new activities with intents [27]).

Теперь создадим вторую активность ShowSettingsActivity для отображения параметров конфигурации приложения. Но вначале мы должны описать новую активность в manifest файле AndroidManifest.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <manifest xmlns:android="schemas.android.com/apk/res/android" [18]
  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 [3] с помощью статического метода getDefaultSharedPreferences [28] класса PreferenceManager [29]. Далее, в зависимости от типа данных параметра, мы используем соответствующий метод извлечения данных (например getBoolean [30] или getString [31]). Второй аргумент в методе извлечения данных — значение по умолчанию, на тот случай если параметр с таким именем еще не был задан. В качестве имен параметров мы используем ключи заданные в XML файле preferences.xml. Значения параметров конкатенируются и выводятся в TextView [32].

Вот описание простого пользовательского интерфейса для второй активности:

  1. <?xml version="1.0" encoding="utf-8"?>
  2.  
  3. <LinearLayout 
  4.     xmlns:android="schemas.android.com/apk/res/android" [18]
  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 [33]

Автор: dzarezenko


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/andorid/2965

Ссылки в тексте:

[1] PreferenceActivity: http://developer.android.com/reference/android/preference/PreferenceActivity.html

[2] ListActivity
: http://developer.android.com/reference/android/app/ListActivity.html

[3] SharedPreferences: http://developer.android.com/reference/android/content/SharedPreferences.html

[4] getSharedPreferences: http://developer.android.com/reference/android/content/Context.html#getSharedPreferences%28java.lang.String,%20int%29

[5] Activity: http://developer.android.com/reference/android/app/Activity.html

[6] Android Essentials: Application Preferences: http://mobile.tutsplus.com/tutorials/android/android-application-preferences/

[7] addPreferencesFromResource: http://developer.android.com/reference/android/preference/PreferenceActivity.html#addPreferencesFromResource%28int%29

[8] Preference: http://developer.android.com/reference/android/preference/Preference.html

[9] View: http://developer.android.com/reference/android/view/View.html

[10] CheckBoxPreference: http://developer.android.com/reference/android/preference/CheckBoxPreference.html

[11] boolean: http://www.google.com.ua/url?sa=t&rct=j&q=java%20boolean&source=web&cd=1&ved=0CC4QFjAA&url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F1.4.2%2Fdocs%2Fapi%2Fjava%2Flang%2FBoolean.html&ei=SutRT4HOIoK08QOJq_3vBQ&usg=AFQjCNEItnyiARRHW-iORD1RYAqUjixjWg

[12] RingtonePreference: http://developer.android.com/reference/android/preference/RingtonePreference.html

[13] EditTextPreference: http://developer.android.com/reference/android/preference/EditTextPreference.html

[14] String: http://www.google.com.ua/url?sa=t&rct=j&q=java%20string&source=web&cd=1&ved=0CDcQFjAA&url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Flang%2FString.html&ei=D-tRT97IJcie8gPYg-DvBQ&usg=AFQjCNGrFpLCfU6By2h_hQEglavyHN-E1w

[15] ListPreference: http://developer.android.com/reference/android/preference/ListPreference.html

[16] PreferenceCategory: http://developer.android.com/reference/android/preference/PreferenceCategory.html

[17] android:dependency: http://developer.android.com/reference/android/preference/Preference.html#attr_android:dependency

[18] schemas.android.com/apk/res/android": http://schemas.android.com/apk/res/android"

[19] android:entries: http://developer.android.com/reference/android/preference/ListPreference.html#attr_android:entries

[20] android:password: http://developer.android.com/reference/android/widget/TextView.html#attr_android:password

[21] android:inputType: http://developer.android.com/reference/android/widget/TextView.html#attr_android:inputType

[22] MenuItem: http://developer.android.com/reference/android/view/MenuItem.html

[23] onCreateOptionsMenu: http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu%28android.view.Menu%29

[24] onOptionsItemSelected: http://developer.android.com/reference/android/app/Activity.html#onOptionsItemSelected%28android.view.MenuItem%29

[25] startActivity: http://developer.android.com/reference/android/app/Activity.html#startActivity%28android.content.Intent%29

[26] Using options menus and customized dialogs for user interaction: http://www.javacodegeeks.com/2010/12/android-full-app-part-7-options-menus.html

[27] Launching new activities with intents: http://www.javacodegeeks.com/2010/11/android-full-app-part-5-launch-activity.html

[28] getDefaultSharedPreferences: http://developer.android.com/reference/android/preference/PreferenceManager.html#getDefaultSharedPreferences%28android.content.Context%29

[29] PreferenceManager: http://developer.android.com/reference/android/preference/PreferenceManager.html

[30] getBoolean: http://developer.android.com/reference/android/content/SharedPreferences.html#getBoolean%28java.lang.String,%20boolean%29

[31] getString: http://developer.android.com/reference/android/content/SharedPreferences.html#getString%28java.lang.String,%20java.lang.String%29

[32] TextView: http://developer.android.com/reference/android/widget/TextView.html

[33] Android Quick Preferences Tutorial: http://www.javacodegeeks.com/2011/01/android-quick-preferences-tutorial.html