summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/settings/utils')
-rw-r--r--src/com/android/settings/utils/VoiceSelection.java74
-rw-r--r--src/com/android/settings/utils/VoiceSelectionAdapter.java63
-rw-r--r--src/com/android/settings/utils/VoiceSelectionFragment.java133
-rw-r--r--src/com/android/settings/utils/VoiceSettingsActivity.java74
4 files changed, 344 insertions, 0 deletions
diff --git a/src/com/android/settings/utils/VoiceSelection.java b/src/com/android/settings/utils/VoiceSelection.java
new file mode 100644
index 0000000..997d2cc
--- /dev/null
+++ b/src/com/android/settings/utils/VoiceSelection.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.utils;
+
+import android.app.VoiceInteractor.PickOptionRequest.Option;
+import android.os.Bundle;
+import android.text.TextUtils;
+
+/**
+ * Model for a single item that can be selected by a {@link VoiceSelectionFragment}.
+ * Each item consists of a visual label and several alternative synonyms for the item
+ * that can be used to identify the item by voice.
+ */
+public class VoiceSelection {
+ final CharSequence mLabel;
+ final CharSequence[] mSynonyms;
+
+ /**
+ * Created a new selectable item with a visual label and a set of synonyms.
+ */
+ public VoiceSelection(CharSequence label, CharSequence synonyms) {
+ mLabel = label;
+ mSynonyms = TextUtils.split(synonyms.toString(), ",");
+ }
+
+ /**
+ * Created a new selectable item with a visual label and no synonyms.
+ */
+ public VoiceSelection(CharSequence label) {
+ mLabel = label;
+ mSynonyms = null;
+ }
+
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public CharSequence[] getSynonyms() {
+ return mSynonyms;
+ }
+
+ Option toOption(int index) {
+ Option result = new Option(mLabel);
+ Bundle extras = new Bundle();
+ extras.putInt("index", index);
+ result.setExtras(extras);
+
+ for (CharSequence synonym : mSynonyms) {
+ result.addSynonym(synonym);
+ }
+ return result;
+ }
+
+ /**
+ * Listener interface for when an item is selected.
+ */
+ public interface OnItemSelectedListener {
+ abstract void onItemSelected(int position, VoiceSelection selection);
+ };
+}
diff --git a/src/com/android/settings/utils/VoiceSelectionAdapter.java b/src/com/android/settings/utils/VoiceSelectionAdapter.java
new file mode 100644
index 0000000..2c060c2
--- /dev/null
+++ b/src/com/android/settings/utils/VoiceSelectionAdapter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.utils;
+
+import android.content.Context;
+import android.widget.ArrayAdapter;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import android.app.Activity;
+import com.android.settings.R;
+
+import java.util.List;
+import android.util.Log;
+
+/**
+ * Array adapter for selecting an item by voice interaction. Each row includes a visual
+ * indication of the 1-indexed position of the item so that a user can easily say
+ * "number 4" to select it.
+ */
+public class VoiceSelectionAdapter extends ArrayAdapter<VoiceSelection> {
+ public VoiceSelectionAdapter(Context context, int resource, List<VoiceSelection> objects) {
+ super(context, resource, objects);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ VoiceSelection item = getItem(position);
+ View row = convertView;
+ if (row == null) {
+ LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
+ row = inflater.inflate(R.layout.voice_item_row, parent, false);
+ }
+
+ TextView label = (TextView) row.findViewById(R.id.voice_item_label);
+ if (label != null) {
+ label.setText(item.getLabel());
+ }
+
+ TextView positionLabel = (TextView) row.findViewById(R.id.voice_item_position);
+ if (positionLabel != null) {
+ positionLabel.setText(Integer.toString(position + 1));
+ }
+
+ return row;
+ }
+};
diff --git a/src/com/android/settings/utils/VoiceSelectionFragment.java b/src/com/android/settings/utils/VoiceSelectionFragment.java
new file mode 100644
index 0000000..c2e80d3
--- /dev/null
+++ b/src/com/android/settings/utils/VoiceSelectionFragment.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.utils;
+
+import android.app.ListFragment;
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.PickOptionRequest;
+import android.app.VoiceInteractor.PickOptionRequest.Option;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+import java.util.List;
+
+/**
+ * An Activity fragment that presents a set of options as a visual list and also allows
+ * items to be selected by the users voice.
+ */
+public class VoiceSelectionFragment extends ListFragment {
+ private static final String EXTRA_SELECTION_PROMPT = "selection_prompt";
+
+ private CharSequence mPrompt = null;
+ private VoiceInteractor.Request mRequest = null;
+ private VoiceInteractor mVoiceInteractor = null;
+ private VoiceSelection.OnItemSelectedListener mOnItemSelectedListener = null;
+
+ /**
+ * No-args ctor required for fragment.
+ */
+ public VoiceSelectionFragment() {}
+
+ @Override
+ public void onCreate(Bundle args) {
+ super.onCreate(args);
+ mPrompt = getArguments().getCharSequence(EXTRA_SELECTION_PROMPT);
+ }
+
+ /**
+ * Set the prompt spoken when the fragment is presented.
+ */
+ static public Bundle createArguments(CharSequence prompt) {
+ Bundle args = new Bundle();
+ args.putCharSequence(EXTRA_SELECTION_PROMPT, prompt);
+ return args;
+ }
+
+ private VoiceSelection getSelectionAt(int position) {
+ return ((ArrayAdapter<VoiceSelection>) getListAdapter()).getItem(position);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+
+ final int numItems = getListAdapter().getCount();
+ if (numItems <= 0) {
+ return;
+ }
+
+ Option[] options = new Option[numItems];
+ for (int idx = 0; idx < numItems; idx++) {
+ options[idx] = getSelectionAt(idx).toOption(idx);
+ }
+ mRequest = new PickOptionRequest(mPrompt, options, null) {
+ @Override
+ public void onPickOptionResult(boolean isComplete, Option[] options, Bundle args) {
+ if (!isComplete || options == null) {
+ return;
+ }
+ if (options.length == 1 && mOnItemSelectedListener != null) {
+ int idx = options[0].getExtras().getInt("index", -1);
+ mOnItemSelectedListener.onItemSelected(idx, getSelectionAt(idx));
+ } else {
+ onCancel();
+ }
+ }
+ };
+ mVoiceInteractor = getActivity().getVoiceInteractor();
+ if (mVoiceInteractor != null) {
+ mVoiceInteractor.submitRequest(mRequest);
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mVoiceInteractor = null;
+ }
+
+ @Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ if (mRequest != null) {
+ mRequest.cancel();
+ mRequest = null;
+ }
+
+ if (mOnItemSelectedListener != null) {
+ mOnItemSelectedListener.onItemSelected(position, getSelectionAt(position));
+ }
+ }
+
+
+ /**
+ * Sets the selection handler for an item either by voice or by touch.
+ */
+ public void setOnItemSelectedHandler(VoiceSelection.OnItemSelectedListener listener) {
+ mOnItemSelectedListener = listener;
+ }
+
+ /**
+ * Called when the user cancels the interaction. The default implementation is to
+ * finish the activity.
+ */
+ public void onCancel() {
+ getActivity().finish();
+ }
+};
diff --git a/src/com/android/settings/utils/VoiceSettingsActivity.java b/src/com/android/settings/utils/VoiceSettingsActivity.java
new file mode 100644
index 0000000..ac5b8be
--- /dev/null
+++ b/src/com/android/settings/utils/VoiceSettingsActivity.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.utils;
+
+import android.app.Activity;
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.CompleteVoiceRequest;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity for modifying a setting using the Voice Interaction API. This activity
+ * will only allow modifying the setting if the intent was sent using
+ * {@link android.service.voice.VoiceInteractionSession#startVoiceActivity startVoiceActivity}
+ * by the current Voice Interaction Service.
+ */
+abstract public class VoiceSettingsActivity extends Activity {
+
+ private static final String TAG = "VoiceSettingsActivity";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (isVoiceInteraction() || savedInstanceState == null) {
+ // Only permit if this is a voice interaction.
+ if (onVoiceSettingInteraction(getIntent())) {
+ // If it's complete, finish.
+ finish();
+ }
+ } else {
+ Log.v(TAG, "Cannot modify settings without voice interaction");
+ finish();
+ }
+ }
+
+ /**
+ * Modify the setting as a voice interaction. Should return true if the
+ * voice interaction is complete or false if more interaction is required.
+ */
+ abstract protected boolean onVoiceSettingInteraction(Intent intent);
+
+ /**
+ * Send a notification that the interaction was successful. If {@link prompt} is
+ * not null, then it will be read to the user.
+ */
+ protected void notifySuccess(CharSequence prompt) {
+ if (getVoiceInteractor() != null) {
+ getVoiceInteractor().submitRequest(new CompleteVoiceRequest(prompt, null));
+ }
+ }
+
+ /**
+ * Indicates when the setting could not be changed.
+ */
+ protected void notifyFailure(String reason) {
+ getVoiceInteractor().submitRequest(new VoiceInteractor.AbortVoiceRequest(reason, null));
+ }
+}