每一个程序都很可能会有系统参数需要根据用户的偏好进行设置,android应用程序开发也一样是必不可少的,Android为我们提供了一个很方便的Activity类PreferenceActivity,专门用于系统参数设置。本文将使用“移动商旅”中的参数设置页面对PreferenceActivity进行讲解。最终效果如下图所示:


第一步,在res/xml/目录下新建preferences.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
	<!--
   Copyright (C) 2010 ideasandroid
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- PreferenceCategory为分组标签,把不同类型的参数设置进行分组 -->
	<PreferenceCategory android:title="@string/mbt_preference_weather_catalog">
		<!-- ListPreference为下拉列表参数设置标签,可以通过选择下拉列表中的项进行参数设置 -->
		<ListPreference android:key="mbt.weathercountry"
			android:title="@string/mbt_preference_weather_country"
			android:dialogTitle="@string/mbt_preference_weather_countryselect" />
		<ListPreference android:key="mbt.weathercity"
			android:title="@string/mbt_preference_weather_city"
			android:dialogTitle="@string/mbt_preference_weather_cityselect" />
	</PreferenceCategory>
 
	<PreferenceCategory android:title="@string/mbt_preference_hotel_catalog">
		<!-- CheckBoxPreference为选择框,分开关两种状态,反映为参数为true和false -->
		<CheckBoxPreference android:key="mbt.hotel.guide"
			android:title="@string/mbt_preference_hotel_guide" 
			android:summaryOn="@string/mbt_preference_hotel_guide_on"
			android:summaryOff="@string/mbt_preference_hotel_guide_off"
			android:defaultValue="true" />
	</PreferenceCategory>
	<!--
		除以上参数设置标签外,还有EditTextPreference(文本输入框)、RingtonePreference(铃声选择列表)等
	-->
</PreferenceScreen>

第二步,新建一个Activity,名称为SettingsActivity,继承PreferenceActivity。代码如下所示:

package com.ideasandroid.mbt;
 
import java.util.List;
import com.ideasandroid.mbt.dao.GoogleWeatherCountryDAO;
import com.ideasandroid.mbt.service.GoogleWeatherCityService;
import com.ideasandroid.mbt.vo.GoogleWeatherCity;
import com.ideasandroid.mbt.vo.GoogleWeatherCountry;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.view.KeyEvent;
 
public class SettingsActivity extends PreferenceActivity implements
		Preference.OnPreferenceChangeListener {
	private final int SEARCH_REQUEST_CODE = 0;
	private Cursor countryCursor = null;
	private SharedPreferences settings;
	private GoogleWeatherCityService gwcService = null;
	private ListPreference countryPreference;
	private ListPreference cityPreference;
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 设置对应需要修改的配置文件
		getPreferenceManager().setSharedPreferencesName("mbt");
		// 引用配置内容xml文件
		addPreferencesFromResource(R.xml.preferences);
		// 得到SharedPreferences对象,用于获取一些参数
		settings = getPreferenceManager().getSharedPreferences();
		countryPreference = (ListPreference) findPreference("mbt.weathercountry");
		cityPreference = (ListPreference) findPreference("mbt.weathercity");
		String weatherCountryStr = settings.getString("mbt.weathercountry",
				"中国:CN");
		CharSequence[] wcArray = weatherCountryStr.split(":");
		// 设置摘要信息
		countryPreference.setSummary(getString(R.string.mbt_preference_weather_ccountry)
						+ wcArray[0]);
		String weatherCityStr = settings.getString("mbt.weathercity",
				"北京:39930000:116279998");
		String[] cityInfo = weatherCityStr.split(":");
		cityPreference.setSummary(getString(R.string.mbt_preference_weather_ccity)
						+ cityInfo[0]);
		countryPreference.setOnPreferenceChangeListener(this);
		cityPreference.setOnPreferenceChangeListener(this);
		GoogleWeatherCountryDAO countrydao = new GoogleWeatherCountryDAO(this);
		//以下代码主要完成的功能是:在数据库中查询国家信息,放到设置国家参数的List中
		//同时向服务器请求当前国家的城市信息
		countryCursor = countrydao.findAll();
		int countryCount = countryCursor.getCount();
		final CharSequence[] countryValues = new CharSequence[countryCount];
		final CharSequence[] countryLabels = new CharSequence[countryCount];
		countryCursor.moveToFirst();
		for (int i = 0; i < countryCount; i++) {
			countryLabels[i] = countryCursor.getString(countryCursor.getColumnIndex(GoogleWeatherCountry.NAME));
			countryValues[i] = countryLabels[i]
					+ ":"
					+ countryCursor.getString(countryCursor.getColumnIndex(GoogleWeatherCountry.ISO_CODE));
			countryCursor.moveToNext();
		}
		countryPreference.setEntries(countryLabels);
		countryPreference.setEntryValues(countryValues);
		gwcService = new GoogleWeatherCityService();
		gwcService.request(this, this, getText(R.string.mbt_gweather_searching).toString(),
				wcArray[1].toString(), cityHandler);
	}
 
 
	/* 在设置参数发生变化时调用本方法
	 * 本例中在选择了一个国家后,加载这个国家的所有城市,同时重新设置摘要信息
	 * 在选择了一个城市后,重新设置摘要信息
	 */
	public boolean onPreferenceChange(Preference preference, Object newValue) {
		if (preference.getKey().equals("mbt.weathercountry")) {
			String[] countryInfo = ((String) newValue).split(":");
			preference.setSummary(getString(R.string.mbt_preference_weather_ccountry)
							+ countryInfo[0]);
			gwcService = new GoogleWeatherCityService();
			gwcService.request(this, this, getText(
					R.string.mbt_gweather_searching).toString(),
					countryInfo[1], cityHandler);
		} else if (preference.getKey().equals("mbt.weathercity")) {
			String[] cityInfo = ((String) newValue).split(":");
			preference.setSummary(getString(R.string.mbt_preference_weather_ccity)
							+ cityInfo[0]);
		}
		return true;
	}
 
	//处理服务器返回的城市信息,同时将这些信息放到城市选择下拉列表中
	Handler cityHandler = new Handler() {
		public void handleMessage(Message msg) {
			List<GoogleWeatherCity> cityList = gwcService.getCityList();
			final CharSequence[] cityValues = new CharSequence[cityList.size()];
			final CharSequence[] cityLabels = new CharSequence[cityList.size()];
			for (int i = 0; i < cityList.size(); i++) {
				GoogleWeatherCity city = (GoogleWeatherCity) cityList.get(i);
				cityLabels[i] = city.getName();
				cityValues[i] = city.getName() + ":" + city.getLatitude() + ":"
						+ city.getLongitude();
			}
			cityPreference.setEntries(cityLabels);
			cityPreference.setEntryValues(cityValues);
			// cityPreference.getDialog().show();
		}
	};
 
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			setResult(SEARCH_REQUEST_CODE, null);
			this.finish();
		}
		return super.onKeyDown(keyCode, event);
	}
}

在调式时您会看到系统生成的配置文件mbt.xml如下所示:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="mbt.weathercountry">香港:HK</string>
<boolean name="mbt.hotel.guide" value="false" />
<string name="mbt.weathercity">中国香港:22250000:114166702</string>
</map>

这样,在要使用到系统配置参数的地方就可以直接通过下面的代码获取到相应的参数。

SharedPreferences settings=getSharedPreferences("mbt", MODE_PRIVATE);
boolean showguide = settings.getBoolean("mbt.hotel.guide", true)