Browse through more Android tutorials. If you'd like to see a tutorial on any particular topic, do leave a comment in the wishlist page. We frequently post new tutorials along with app releases. You may subscribe to our newsletter to get all updates in your inbox.
Now you can get the latest Java source bundled with each app update. Install the app from Google Play and go to Settings > Extras.

«  Create Flappy Bird in Android Create an instant messaging app  »

Create an App Widget in Android with Text-to-Speech (TTS)

DownloadDownload

Keywords: AppWidgetProvider RemoteViews AppWidgetManager BroadcastReceiver Widget Configuration Activity AlarmManager TextToSpeech Service PreferenceActivity OnPreferenceChangeListener

Contents

3 « Prev Page

8. The Widget Configuration activity

We can (optionally) specify a configuration screen to be displayed to the user when the widget is added to the Home screen. We had opted for a configuration screen in the wizard so ADT has generated a default activity and layout.




	public class VocabWidgetConfigureActivity extends Activity {

		int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
		Spinner mRefreshIntervalSpn;
		
		public VocabWidgetConfigureActivity() {
			super();
		}

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

			// Set the result to CANCELED. This will cause the widget host to cancel
			// out of the widget placement if the user presses the back button.
			setResult(RESULT_CANCELED);

			setContentView(R.layout.vocab_widget_configure);
			mRefreshIntervalSpn = (Spinner) findViewById(R.id.refresh_interval_spinner);
			findViewById(R.id.add_button).setOnClickListener(mOnClickListener);

			// Find the widget id from the intent.
			Intent intent = getIntent();
			Bundle extras = intent.getExtras();
			if (extras != null) {
				mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
			}

			// If this activity was started with an intent without an app widget ID,
			// finish with an error.
			if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
				finish();
				return;
			}

			mRefreshIntervalSpn.setSelection(getSelectedPosition(loadIntervalPref(this, mAppWidgetId)));
		}
		
		private int getSelectedPosition(String interval) {
			String[] values = getResources().getStringArray(R.array.refresh_interval_values);
			for (int i=0; i<values.length; i++) {
				if (values[i].equals(interval)) return i;
			}
			return 0;
		}

		View.OnClickListener mOnClickListener = new View.OnClickListener() {
			public void onClick(View v) {
				final Context context = VocabWidgetConfigureActivity.this;

				// When the button is clicked, store the string locally
				String[] values = getResources().getStringArray(R.array.refresh_interval_values);
				String widgetText = values[mRefreshIntervalSpn.getSelectedItemPosition()];
				saveIntervalPref(context, mAppWidgetId, widgetText);
				
				// Make sure we pass back the original appWidgetId
				Intent resultValue = new Intent();
				resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
				setResult(RESULT_OK, resultValue);
				finish();
			}
		};

		// Write the prefix to the SharedPreferences object for this widget
		static void saveIntervalPref(Context context, int appWidgetId, String text) {
			SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
			prefs.putString(SettingsActivity.INTERVAL_PREF, text);
			prefs.commit();
		}

		// Read the prefix from the SharedPreferences object for this widget.
		// If there is no preference saved, get the default from a resource
		static String loadIntervalPref(Context context, int appWidgetId) {
			SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
			String interval = prefs.getString(SettingsActivity.INTERVAL_PREF, SettingsActivity.DEFAULT_INTERVAL);
			return interval;
		}
			
	}
					
The configuration activity is launched by the App Widget host so we need to pass back RESULT_OK with appWidgetId so that the widget gets added.
The code is straight-forward and due to simplicity of the screen we have set a Dialog theme for the activity in the manifest.
        <activity android:name=".VocabWidgetConfigureActivity"
            android:theme="@style/AppTheme.Dialog" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </intent-filter>
        </activity>
						
Here is the styles for AppTheme.Dialog theme. Add the following snippet to res/values/styles.xml
	<style name="AppTheme.Dialog" parent="android:Theme.Light">
	    <item name="android:windowNoTitle">true</item>
	    <item name="android:windowFrame">@null</item>
	    <item name="android:windowIsFloating">true</item>
	    <item name="android:windowContentOverlay">@null</item>
	    <item name="android:windowBackground">@android:color/white</item>
	    <item name="android:maxWidth">600dp</item>
	    <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
	</style>
						
And the following snippet to res/values-v11/styles.xml
	<style name="AppTheme.Dialog" parent="android:Theme.Holo.Light.Dialog">
	    <item name="android:windowNoTitle">true</item>
	    <item name="android:windowCloseOnTouchOutside">true</item>
	</style>
						

9. The Widget Configuration layout

Modify vocab_widget.xml in res/layout as follows.
	<?xml version="1.0" encoding="utf-8"?>
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		android:layout_width="match_parent"
		android:layout_height="wrap_content"
		android:orientation="vertical"
		android:padding="16dp"
		android:gravity="center_horizontal" >

		<TextView
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_marginBottom="8dp"
			android:textStyle="bold"
			android:text="@string/configure" />

		<Spinner
			android:id="@+id/refresh_interval_spinner"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:entries="@array/refresh_interval_titles"
			android:entryValues="@array/refresh_interval_values" />

		<Button
			android:id="@+id/add_button"
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_marginTop="8dp"
			android:text="@string/add_widget" />

	</LinearLayout>
						
The entries and values for refresh interval spinner is defined as string arrays in res/values/strings.xml resource file.
    <string-array name="refresh_interval_titles">
        <item>15 minutes</item>
        <item>30 minutes</item>
        <item>1 hour</item>
        <item>3 hours</item>
        <item>6 hours</item>
    </string-array>
    
    <string-array name="refresh_interval_values">
        <item>15</item>
        <item>30</item>
        <item>60</item>
        <item>180</item>
        <item>360</item>
    </string-array>
						
Next, we'll see how to add Text-to-speech (TTS) functionality in an Android app.
Share the love:  

Next Page » 3

App Gen
App Name:
Project Name:
Package:
Screens:
Splash
Login
Help
Main
List  Grid  Pager
Detail
Settings
Options:
Action Bar
Navigation Drawer
Dummy Data
Generate
Free Apps