2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.settings;
19 import android.app.Activity;
20 import android.app.Dialog;
21 import android.app.DialogFragment;
22 import android.app.Fragment;
23 import android.content.ContentResolver;
24 import android.content.Intent;
25 import android.content.pm.PackageManager;
26 import android.content.res.Resources;
27 import android.os.Bundle;
28 import android.preference.PreferenceActivity;
29 import android.preference.PreferenceFragment;
30 import android.text.TextUtils;
31 import android.util.Log;
32 import android.view.View;
33 import android.view.View.OnClickListener;
34 import android.widget.Button;
37 * Letting the class, assumed to be Fragment, create a Dialog on it. Should be useful
38 * you want to utilize some capability in {@link SettingsPreferenceFragment} but don't want
39 * the class inherit the class itself (See {@link ProxySelector} for example).
41 interface DialogCreatable {
42 public Dialog onCreateDialog(int dialogId);
46 * Base class for Settings fragments, with some helper functions and dialog management.
48 public class SettingsPreferenceFragment extends PreferenceFragment
49 implements DialogCreatable {
51 private static final String TAG = "SettingsPreferenceFragment";
53 // Originally from PreferenceActivity.
54 private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
55 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
56 private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
57 private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
59 private SettingsDialogFragment mDialogFragment;
61 private int mResultCode = Activity.RESULT_CANCELED;
62 private Intent mResultData;
64 private Button mNextButton;
67 public void onResume() {
70 final Fragment f = getTargetFragment();
71 final int requestCode = getTargetRequestCode();
73 // TargetFragment becomes invalid when this object is resumed. Notify it to
74 // FragmentManager. Without this code, FragmentManager wrongly take the TargetFragment
75 // as live, and throws IllegalStateException.
76 setTargetFragment(null, -1);
78 if (f != null && (f instanceof SettingsPreferenceFragment)) {
79 final SettingsPreferenceFragment spf = (SettingsPreferenceFragment)f;
80 final int resultCode = spf.getResultCode();
81 final Intent resultData = spf.getResultData();
82 onActivityResult(requestCode, resultCode, resultData);
87 public void onActivityCreated(Bundle savedInstanceState) {
88 super.onActivityCreated(savedInstanceState);
92 public final void setResult(int resultCode) {
93 mResultCode = resultCode;
97 public final void setResult(int resultCode, Intent data) {
98 mResultCode = resultCode;
102 public final int getResultCode() {
106 public final Intent getResultData() {
111 * The name is intentionally made different from Activity#finish(), so that
112 * users won't misunderstand its meaning.
114 public final void finishFragment() {
115 getActivity().onBackPressed();
118 // Some helpers for functions used by the settings fragments when they were activities
121 * Returns the ContentResolver from the owning Activity.
123 protected ContentResolver getContentResolver() {
124 return getActivity().getContentResolver();
128 * Returns the specified system service from the owning Activity.
130 protected Object getSystemService(final String name) {
131 return getActivity().getSystemService(name);
135 * Returns the PackageManager from the owning Activity.
137 protected PackageManager getPackageManager() {
138 return getActivity().getPackageManager();
143 protected void showDialog(int dialogId) {
144 if (mDialogFragment != null) {
145 Log.e(TAG, "Old dialog fragment not null!");
147 mDialogFragment = new SettingsDialogFragment(this, dialogId);
148 mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
151 public Dialog onCreateDialog(int dialogId) {
155 protected void removeDialog(int dialogId) {
156 if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
157 && mDialogFragment.isVisible()) {
158 mDialogFragment.dismiss();
160 mDialogFragment = null;
163 static class SettingsDialogFragment extends DialogFragment {
164 private int mDialogId;
166 private DialogCreatable mFragment;
168 SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
169 mDialogId = dialogId;
170 mFragment = fragment;
174 public Dialog onCreateDialog(Bundle savedInstanceState) {
175 return mFragment.onCreateDialog(mDialogId);
178 public int getDialogId() {
183 protected boolean hasNextButton() {
184 return mNextButton != null;
187 protected Button getNextButton() {
191 public void finish() {
192 getActivity().onBackPressed();
195 public boolean startFragment(
196 Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
197 if (getActivity() instanceof PreferenceActivity) {
198 PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
199 Fragment f = Fragment.instantiate(getActivity(), fragmentClass, extras);
200 caller.setTargetFragment(f, requestCode);
201 preferenceActivity.switchToHeader(fragmentClass, extras);
204 Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the "
205 + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
212 * Sets up Button Bar possibly required in the Fragment. Probably available only in
215 * Previously {@link PreferenceActivity} had the capability as hidden functionality.
217 private void setupButtonBar() {
218 // Originally from PreferenceActivity, which has had button bar inside its layout.
219 final Activity activity = getActivity();
220 final Intent intent = activity.getIntent();
221 final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
222 if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
226 buttonBar.setVisibility(View.VISIBLE);
227 View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
228 if (tmpView != null) {
229 // TODO: Assume this is pressed only in single pane, finishing current Activity.
231 final Button backButton = (Button)tmpView;
232 backButton.setOnClickListener(new OnClickListener() {
233 public void onClick(View v) {
234 activity.setResult(Activity.RESULT_CANCELED);
238 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
239 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
240 if (TextUtils.isEmpty(buttonText)) {
241 backButton.setVisibility(View.GONE);
244 backButton.setText(buttonText);
247 } catch (ClassCastException e) {
248 Log.w(TAG, "The view originally for back_button is used not as Button. " +
253 tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
254 if (tmpView != null) {
256 final Button skipButton = (Button)tmpView;
257 skipButton.setOnClickListener(new OnClickListener() {
258 public void onClick(View v) {
259 activity.setResult(Activity.RESULT_OK);
263 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
264 skipButton.setVisibility(View.VISIBLE);
266 } catch (ClassCastException e) {
267 Log.w(TAG, "The view originally for skip_button is used not as Button. " +
272 tmpView = activity.findViewById(com.android.internal.R.id.next_button);
273 if (tmpView != null) {
275 mNextButton = (Button)tmpView;
276 mNextButton.setOnClickListener(new OnClickListener() {
277 public void onClick(View v) {
278 activity.setResult(Activity.RESULT_OK);
282 // set our various button parameters
283 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
284 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
285 if (TextUtils.isEmpty(buttonText)) {
286 mNextButton.setVisibility(View.GONE);
289 mNextButton.setText(buttonText);
292 } catch (ClassCastException e) {
293 Log.w(TAG, "The view originally for next_button is used not as Button. " +