Settings开发

应用程序经常会包好设置选项,来让用户可以改变应用程序的功能和行为。比如,一些app允许用户指定是否开启通知功能,或者指定同步云端的数据的频率。

如果你想要为你的app提供设置选项,你应该使用Android的Preference APIs来创建一个与其他的Android app中的用户体验相一致的接口(包括系统的 设置 应用)。这份文档描述了如何使用Preference APIs来描述创建你的app的设置选项。

Settings Design:更多关于如何设计你的设置选项的信息,请阅读Settings设计指南。

图 1. 来自于Android 短信 app的设置选项的屏幕截图。选择一个由一个Preference定义的项目将打开一个用于改变设置的接口。

概述

不利用View对象来构建用户接口,设置选项 通过使用你在一个XML文件中声明的Preference类的多种子类来构建。

一个Preference对象是一个单独的设置选项的构建块。每个Preference 看上去就像是一个列表中的一项,它给用户提供适当的UI来修改设置。比如,一个CheckBoxPreference创建一个显示一个checkbox的列表项,一个ListPreference创建一个将打开一个选择列表的对话框的列表项。

你添加的每个Preference都具有一个对应的键-值对,系统使用这个键-值对来为你的app的设置选项在一个默认的SharedPreferences文件中保存设置。当用户改变一个设置时,系统将为你更新SharedPreferences文件中对应的值。你应该与相关的SharedPreferences文件进行直接交互的时间只是当你需要读取值来基于用户的设置决定你app的行为的时候。

保存在SharedPreferences中的每种设置可以是下面的数据类型中的一种:

  • Boolean
  • Float
  • Int
  • Long
  • String
  • StringSet

由于你app的设置选项的UI是使用Preference对象创建的,而不是View对象,则你需要使用一个专门的ActivityFragment子类来显示设置的列表:

  • 如果你的app支持的Android版本比3.0更早(API level 10及更低),你必须创建一个PreferenceActivity 类的子类。
  • 在Android 3.0及其后版本上,则你应该使用一个传统的Activity,其中寄居一个显示你的app的设置选项的PreferenceFragment。然而,当你具有多组设置选项时,你也可以使用PreferenceActivity来为大屏幕创建一个two-pane布局。

如何设置你的PreferenceActivityPreferenceFragment的实例,将在关于创建一个Preference Activity使用Preference Fragments的小节讨论。

Preferences

你app的每一项设置由一个特定的Preference类的子类来描绘。每个子类都包含一个核心属性的集合,以允许你指定一些事情,比如设置项的一个标题和默认值。每个子类也提供了它自己的专门的属性和用户接口。例如,图1显示了一个来自于短信app的设置选项的屏幕截图。设置选项屏幕中的每个列表项都由一个不同的Preference对象支持。

一些最常见的preferences有:

CheckBoxPreference  为一个设置显示一个具有一个checkbox的项,它是激活的或未激活的。保存的值是一个 boolean值(如果选中,则为true)。

ListPreference 打开一个具有一个radio buttons的列表的对话框。保存的值可以是所支持的值类型中的任何一种(上面所列)。

EditTextPreference 打开一个具有一个EditText widget的对话框。保存的值为一个String

参考Preference类来查看所有的其他子类的列表,及它们对应的属性。

当然,内建的类不能满足每一种需求,你的应用程序也许需要一些更特别的东西。比如,当前平台不提供一个用于撷取一个数字或一个日期的Preference 类。因而,也许你会需要定义你自己的Preference子类。要获取这方面的帮助的话,请参考关于构建一个定制的Preference一节。

在XML中定义Preferences

尽管你可以在运行时实例化新的Preference 对象,但你应该在XML文件通过一个Preference对象的层次结构来定义你的设置项列表。使用一个XML文件来定义你的设置项集合是首选的,因为该文件提供了一个方便阅读、更新简便的结构。而且,你app的设置选项通常是预先确定好的,尽管你仍然可以在运行时修改这个集合。

每个Preference子类可以通过与其类名匹配的一个XML元素来声明,比如<CheckBoxPreference>。

你必须将XML文件保存在res/xml/目录下。尽管你可以随意命名该文件,但它传统上都被命名为preferences.xml。你通常只需要一个文件,因为层次结构中的分支(那些打开它们自己的设置项列表的)使用嵌套的PreferenceScreen实例来声明。

注意:如果你想要为你的设置选项创建一个multi-pane的布局,则你需要为每个fragment定义分开的XML文件。

XML文件的根节点必须是一个<PreferenceScreen>元素。你在这个元素内添加每个Preference。在设置项列表中,你在<PreferenceScreen>元素中添加的每个子元素看起来将是一个单独的列表项。

比如:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="pref_sync"
        android:title="@string/pref_sync"
        android:summary="@string/pref_sync_summ"
        android:defaultValue="true" />
    <ListPreference
        android:dependency="pref_sync"
        android:key="pref_syncConnectionType"
        android:title="@string/pref_syncConnectionType"
        android:dialogTitle="@string/pref_syncConnectionType"
        android:entries="@array/pref_syncConnectionTypes_entries"
        android:entryValues="@array/pref_syncConnectionTypes_values"
        android:defaultValue="@string/pref_syncConnectionTypes_default" />
</PreferenceScreen>

在这个例子中,有一个CheckBoxPreference和一个ListPreference。两个列表项都包含如下三种属性:

android:key

保存一个数据值的preferences会需要这个属性。它指定了唯一的键(一个字符串),系统在SharedPreferences中保存设置项的值时会用到。

只有一些情况下是不需要这个属性的,当preference是一个PreferenceCategoryPreferenceScreen时,或者preference指定了一个Intent来调用(通过一个<intent>元素)或者一个Fragment来显示(通过一个android:fragment属性)。

android:title

它为设置项提供了一个用户可见的名字。

android:defaultValue

它指定了系统应该在SharedPreferences文件中设置的初始值。你应该为所有的设置项提供一个默认值。

关于所支持的所有其他属性的信息,请参考Preference (及各个子类)的文档。

图 2. 具有标题的设置项类别
1. 类别由<PreferenceCategory>元素指定
2. 标题由android:title属性指定

当你的设置项列表超出了大约10个项目的时候,你可能想要添加标题来定义设置项组或者将那些组在一个不同的屏幕中显示。这些选项将在后面的小节中描述。

创建设置项组

如果你呈现了一个具有10个或更多设置项的列表,用户可能会很难查读、理解并处理他们。你可以通过将部分或全部设置项分成几组,有效的将一个长列表变成多个短一些的列表来补救。一组相关的设置项可以通过两种方式中的一种来呈现:

这些分组的技术,你可以使用一种或两种都用来组织你app的设置项。当要决定使用哪种及如何将你的设置项分组时,你应该遵循Android Design's Settings指南的指导。

使用标题

如果你想要在设置项组之间提供具有标题的分割线(如图2所示的那样),可以将每组Preference对象放置在一个PreferenceCategory中。

例如:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory 
        android:title="@string/pref_sms_storage_title"
        android:key="pref_key_storage_settings">
        <CheckBoxPreference
            android:key="pref_key_auto_delete"
            android:summary="@string/pref_summary_auto_delete"
            android:title="@string/pref_title_auto_delete"
            android:defaultValue="false"... />
        <Preference 
            android:key="pref_key_sms_delete_limit"
            android:dependency="pref_key_auto_delete"
            android:summary="@string/pref_summary_delete_limit"
            android:title="@string/pref_title_sms_delete"... />
        <Preference 
            android:key="pref_key_mms_delete_limit"
            android:dependency="pref_key_auto_delete"
            android:summary="@string/pref_summary_delete_limit"
            android:title="@string/pref_title_mms_delete" ... />
    </PreferenceCategory>
    ...
</PreferenceScreen>
使用subscreens

如果你想要将设置项组放置在一个subscreen中(如图3所示的那样),你可以将Preference对象组放进一个PreferenceScreen中。

图 3. Setting subscreens. <PreferenceScreen>元素创建一个列表项,当它被选中时,将打开一个分开的列表来显示嵌套的设置项。

例如:

<PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- opens a subscreen of settings -->
    <PreferenceScreen
        android:key="button_voicemail_category_key"
        android:title="@string/voicemail"
        android:persistent="false">
        <ListPreference
            android:key="button_voicemail_provider_key"
            android:title="@string/voicemail_provider" ... />
        <!-- opens another nested subscreen -->
        <PreferenceScreen
            android:key="button_voicemail_setting_key"
            android:title="@string/voicemail_settings"
            android:persistent="false">
            ...
        </PreferenceScreen>
        <RingtonePreference
            android:key="button_voicemail_ringtone_key"
            android:title="@string/voicemail_ringtone_title"
            android:ringtoneType="notification" ... />
        ...
    </PreferenceScreen>
    ...
</PreferenceScreen>

使用intents

在某些情况下,也许你会想要让一个preference项打开一个不同的activity,而不是一个设置屏幕,比如一个网页浏览器要查看一个网页。为了在用户选择一个preference项时调用一个Intent,可以给对应的<Preference>元素添加一个<intent>元素作为它的子元素。

比如,下面是你如何使用一个preference项来打开一个网页的方法:

<Preference android:title="@string/prefs_web_page" >
    <intent android:action="android.intent.action.VIEW"
            android:data="http://www.example.com" />
</Preference>

在创建显式的和隐式的intent时,你可以使用下面的属性:

android:action

分配的action,与setAction()方法一样。

android:data

分配的data,与setData()方法一样。

android:mimeType

分配的MIME type,与setType()方法一样。

android:targetClass

Component name的类部分,与setComponent()方法一样。

android:targetPackage

component name的包部分,与setComponent()方法一样。

创建一个Preference Activity

为了在一个acitvity中显示你的设置选项,可以扩展PreferenceActivity类。这是一个传统的Activity类的子类,它基于Preference对象的层次结构显示了一个设置项的列表。在用户做出了改动时,PreferenceActivity自动地保存与每个Preference关联的设置项。

注意:如果你在为Android 3.0和之后版本开发应用程序,则你应该使用PreferenceFragment。请到下一节,关于使用Preference Fragments

需要记住的最重要的事情是,不要在onCreate()回调中加载一个views的layout。而要调用addPreferencesFromResource()来给acitvity添加你已经在一个XML文件中声明的preferences。比如,下面是一个功能性的PreferenceActivity所需的最少的代码:

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
}

实际上,对于某些apps来说,这些code已经足够了,因为一旦用户修改了一个preference,系统就会在一个默认的SharedPreferences文件中保存改动,而在你需要检查用户的设置时,其他的应用程序组件将可以读取内容。然而,对于许多apps,则需要多一点的代码来监听preferences的改动。关于监听SharedPreferences文件的改动的信息,请参考关于读取Preferences的小节。

使用Preference Fragments

如果你在为Android 3.0(API level 11)和更高版本做开发,你应该使用一个PreferenceFragment来显示你的Preference对象列表。你可以给任何activity添加一个PreferenceFragment——你不需要使用PreferenceActivity

相对于只使用activities,Fragments为你的应用程序提供了一个更加灵活的架构,无论你正在构建的是什麽种类的activity。因而,我们建议你尽可能使用PreferenceFragment来控制你的设置选项的显示,而不是PreferenceActivity

你的PreferenceFragment实现可以简单的只定义onCreate()方法来通过addPreferencesFromResource()加载一个preferences文件。比如:

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
    ...
}

就像对任何其他的Fragment所做的那样,你可以将这个fragment添加给一个Activity。比如:

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
    }
}

注意:一个PreferenceFragment没有它自己的Context对象。如果你需要一个Context对象,你可以调用getActivity()。然而,要小心只在fragment已经被attached到一个activity时调用getActivity()。当fragment还没有被attached,或者在它的生命周期的末尾已经被detached,则getActivity()将返回null。

设置默认值

你创建的preferences可能为你的应用程序定义了一些重要的行为,因此,当用户第一次打开你的应用时,用默认值为每个Preference初始化相关的SharedPreferences文件是必须的。

你所必须做的第一件事,就是在你的XML文件中,使用android:defaultValue属性为每个Preference指定一个默认值。该值可以是适用于相应的Preference对象的任何数据类型。比如:

<!-- default value is a boolean -->
<CheckBoxPreference
    android:defaultValue="true"
    ... />

<!-- default value is a string -->
<ListPreference
    android:defaultValue="@string/pref_syncConnectionTypes_default"
    ... />

然后,在你的应用的主activity的onCreate()方法中——和用户进第一次入你的应用可能会借助的任何其他的activity中——调用setDefaultValues()

PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);

onCreate()期间调用这个方法确保你的应用以默认设置适当的初始化了,你的应用可能需要读取这些设置来决定一些行为(比如,连接2G网络时是否下载数据)。

这个方法接收三个参数:

  • 你的应用Context.
  • 你想要设置其默认值的preference XML文件的资源ID。
  • 一个boolean表明默认值是否应该被设置多次。

    当为false时,系统将只在该方法之前没有被调用过时设置默认值(或者默认值shared preferences文件中的KEY_HAS_SET_DEFAULT_VALUES是false)。

只要你设置第三个参数为false,你就可以在每次你的activity启动时,安全的调用这个方法,而不会覆盖用户通过设置而保存的preferences为默认值。然而,如果你将它设为true,你将覆盖前面的值为默认值。

使用Preference Headers

在一些比较少见的情况下,你也许想要设计你的设置选项,其第一屏只显示subscreens的列表(比如在系统Setting app中,如图4和5中所示的那样)。当你在为Android 3.0或更高版本开发时,你应该使用Android 3.0中一个新的"headers"功能,而不是通过嵌套的PreferenceScreen元素构建subscreens。

为了以headers构建你的设置选项,你需要:

  1. 将各组设置项分开放进不同的PreferenceFragment实例中。即,每组设置项需要一个分开的XML文件。
  2. 创建一个XML headers文件,其列出了每个设置项组,并声明了哪个fragment包含相应的设置项列表。
  3. 扩展PreferenceActivity类来放置你的设置项。
  4. 实现onBuildHeaders()回调来指定headers文件。

使用这种设计一个很大的好处是,当运行在大屏幕上时,将如图4所示的那样,PreferenceActivity会自动的呈现一个two-pane布局。

即使你的应用支持的Android版本比3.0老,你仍然可以在老式设备上支持一个传统的多屏幕层次的同时,为实现一个two-pane的显示而在更新的设备上使用PreferenceFragment来构建你的应用(参考关于Supporting older versions with preference headers的小节)。

图 4. 具有headers的two-pane布局
1. headers由一个XML headers文件定义
2. 每组设置项由一个PreferenceFragment定义,由headers文件中的一个 <header>元素指定。

图 5. 一个具有setting headers的手持设备。当一个项目被选中时,相关的PreferenceFragment替换headers。

创建headers file

你的headers列表中的每个设置项组由一个根<preference-headers>元素内一个单独的<header>元素来描述。比如:

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header 
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one" />
    <header 
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <!-- key/value pairs can be included as arguments for the fragment. -->
        <extra android:name="someKey" android:value="someHeaderValue" />
    </header>
</preference-headers>

通过android:fragment属性,每个header声明一个PreferenceFragment实例,它将在用户选择那个header时打开。

<extras>元素允许你在一个Bundle中给fragment传递键-值对。fragment可以通过调用getArguments()提取参数。你也许会为多种原因给fragment传递参数,但一个很好的原因是为每个组复用相同的PreferenceFragment子类,而使用参数来指定fragment应该要加载哪个preferences XML文件。

例如,这儿有一个fragment,当每个header以“settings”键定义一个<extra>参数时,可以被多个设置项组复用:

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String settings = getArguments().getString("settings");
        if ("notifications".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_wifi);
        } else if ("sync".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_sync);
        }
    }
}

显示headers

为了显示preference headers,你必须实现onBuildHeaders()回调方法并调用loadHeadersFromResource()。比如:

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preference_headers, target);
    }
}

当用户选择了headers列表中的一个项目时,系统会自动的打开相关联的PreferenceFragment

注意:当使用preference headers时,你的PreferenceActivity子类不需要实现onCreate()方法,因为activity唯一需要的任务是加载headers。

以preference headers支持更老的版本

如果你的应用支持的Android版本比3.0更老,当运行在Android 3.0或更高的版本上时,你依然可以使用headers来提供一个two-pane布局。你所需要做的全部即是创建另外一个preferences XML文件,其使用基本的<Preference>元素,而行为则向headers项目一样(将被更老的Android版本使用)。

然而,它不是打开一个新的PreferenceScreen,每个<Preference>元素发送一个Intent给指定了要加载哪个preference XML文件的PreferenceActivity

比如,这儿有一个preference headers所需的XML文件,它被用于Android 3.0及更高版本上(res/xml/preference_headers.xml):

<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header 
        android:fragment="com.example.prefs.SettingsFragmentOne"
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one" />
    <header 
        android:fragment="com.example.prefs.SettingsFragmentTwo"
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" />
</preference-headers>

而下面则是一个preference文件,它为比Android 3.0更老的版本提供了相同的headers(res/xml/preference_headers_legacy.xml):

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <Preference 
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one"  >
        <intent 
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_ONE" />
    </Preference>
    <Preference 
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <intent 
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_TWO" />
    </Preference>
</PreferenceScreen>

由于对<preference-headers>的支持是在Android 3.0中添加的,只有当运行在Android 3.0或更高版本上时,系统才会调用你 PreferenceActivity中的onBuildHeaders()。为了加载"legacy" headers文件(preference_headers_legacy.xml),你必须检查Android版本,并且当版本比Android 3.0(HONEYCOMB)更老时,调用addPreferencesFromResource()来加载legacy header文件。比如:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_headers_legacy);
    }
}

// Called only on Honeycomb and later
@Override
public void onBuildHeaders(List<Header> target) {
   loadHeadersFromResource(R.xml.preference_headers, target);
}

剩下所需要做的事情就是处理传入activity的Intent,来区分所要加载的preference文件。提取intent的action,并将它和你已经用于preference XML的<intent> tags的已知的action字串对比:

final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
...

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String action = getIntent().getAction();
    if (action != null && action.equals(ACTION_PREFS_ONE)) {
        addPreferencesFromResource(R.xml.preferences);
    }
    ...

    else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_headers_legacy);
    }
}

需要了解的是,对addPreferencesFromResource()的连续调用,将会把一个单独的列表中所有的preferences都入栈,因而,请确保通过else-if语句将条件连起来,使得该方法只被调用一次。

读取Preferences

默认情况下,你app的所有preferences会被保存到一个文件中,然后可以在你应用的任何地方通过调用静态方法PreferenceManager.getDefaultSharedPreferences()来访问它。这个方法返回SharedPreferences对象,其包含了所有与你的PreferenceActivity中使用的Preference对象相关联的键-值对。

比如,下面这段code演示了,在你的应用中其他的activity里读取preference值中的一个的方法:

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");

监听preference的改变

出于某些原因,你可能想要在用户改变了preferences中的一个时得到通知。为了在一个对于preferences中的改变发生时接到一个回调,实现SharedPreference.OnSharedPreferenceChangeListener接口,并通过调用registerOnSharedPreferenceChangeListener()SharedPreferences对象注册监听者。

这个接口只有一个回调方法,onSharedPreferenceChanged(),并且,你也许会发现将接口实现成你activity的一部分最为简单。例如:

public class SettingsActivity extends PreferenceActivity
                              implements OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
    ...

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(KEY_PREF_SYNC_CONN)) {
            Preference connectionPref = findPreference(key);
            // Set summary to be the user-description for the selected value
            connectionPref.setSummary(sharedPreferences.getString(key, ""));
        }
    }
}

在这个例子中,该方法检查了发生改变的设置项是否是一个已知的preference键。它调用findPreference()来获取被改变了的Preference,从而使得它可以修改那一项的总结为用户所选择的项的描述。即,当设置项为一个ListPreference或其他的多选择设置项,则当设置项改变时,你应该调用setSummary()来显示当前的状态(如图5中所示的休眠设置项)。

注意: 如关于Settings的Android设计文档中所描述的那样,我们建议你每次用户改变了preferences时,就更新其总结来描述当前的设置。

为了activity中适当的生命周期管理,我们建议你分别在onResume()onPause()回调中注册和注销你的SharedPreferences.OnSharedPreferenceChangeListener

@Override
protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences()
            .registerOnSharedPreferenceChangeListener(this);
}

@Override
protected void onPause() {
    super.onPause();
    getPreferenceScreen().getSharedPreferences()
            .unregisterOnSharedPreferenceChangeListener(this);
}

管理网络使用

自Android 4.0开始,系统的设置应用允许用户来查看他们的应用程序在后台和前台使用了多少网络数据。用户可以为单独的app关闭对后台数据的使用。为了避免用户把你的app在后台对于数据的访问关掉,你应该有效地使用数据连接,并允许用户通过你的应用程序设置选项改善你的app的数据使用。

比如,你也许会允许用户控制你app同步数据的频率,当Wi-Fi打开时你的app是否执行上传/下载,当2G网络连接时你的app是否使用数据,等等。通过为用户提供这些控制选项,当接近他们在系统Settings中设置的限制值时,用户禁掉你的app的数据访问的可能性就会大大降低,因为他们可以精确地控制你的app可以使用多少数据。

一旦你已经在你的PreferenceActivity添加了需要的preferences来控制你的app的数据访问,你应该在你的manifest文件中添加一个intent filter,ACTION_MANAGE_NETWORK_USAGE,比如:

<activity android:name="SettingsActivity" ... >
    <intent-filter>
       <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
       <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

这个intent filter向系统表示,这个activity是用来控制你的应用程序的数据使用的。因而,当用户从系统的Settings中想要了解你的app使用了多少数据时,一个View application settings按钮可以用来启动你的PreferenceActivity,以使得用户可以 改变你的app可以使用多少数据。

Done.

转载于:https://my.oschina.net/wolfcs/blog/164158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值