Doc change: cherry-pick from master. ->Subject: Android application files for the Activity Testing Tutorial
Conflicts: build/sdk.atree Change-Id: I5edb1d4d8a18fbda53a0e78ca6c9d20cf7d3ff4a
This commit is contained in:
@@ -98,6 +98,8 @@ development/samples/Snake samples/${PLATFORM_NAME}/Snake
|
|||||||
development/samples/SoftKeyboard samples/${PLATFORM_NAME}/SoftKeyboard
|
development/samples/SoftKeyboard samples/${PLATFORM_NAME}/SoftKeyboard
|
||||||
development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy
|
development/samples/JetBoy samples/${PLATFORM_NAME}/JetBoy
|
||||||
development/samples/SearchableDictionary samples/${PLATFORM_NAME}/SearchableDictionaryV2
|
development/samples/SearchableDictionary samples/${PLATFORM_NAME}/SearchableDictionaryV2
|
||||||
|
development/samples/Spinner samples/${PlATFORM_NAME}/Spinner
|
||||||
|
development/samples/SpinnerTest samples/${PLATFORM_NAME}/SpinnerTest
|
||||||
development/samples/ContactManager samples/${PLATFORM_NAME}/ContactManager
|
development/samples/ContactManager samples/${PLATFORM_NAME}/ContactManager
|
||||||
development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
|
development/samples/MultiResolution samples/${PLATFORM_NAME}/MultiResolution
|
||||||
development/samples/Wiktionary samples/${PLATFORM_NAME}/Wiktionary
|
development/samples/Wiktionary samples/${PLATFORM_NAME}/Wiktionary
|
||||||
|
|||||||
53
samples/Spinner/AndroidManifest.xml
Normal file
53
samples/Spinner/AndroidManifest.xml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Declares the contents of this Android application. The "namespace"
|
||||||
|
attribute brings in the Android platform namespace, and the
|
||||||
|
"package" attribute provides a unique Android name for the application.
|
||||||
|
If you use this file as a template in your own application, you must change
|
||||||
|
the package name from "com.android.example" to one that you own or have
|
||||||
|
control over.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.android.example.spinner"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
<!--
|
||||||
|
Sets the application's user-readable label
|
||||||
|
-->
|
||||||
|
<application android:label="@string/app_name">
|
||||||
|
<!--
|
||||||
|
Sets the activity's name and label
|
||||||
|
-->
|
||||||
|
<activity android:name=".SpinnerActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<!--
|
||||||
|
This activity responds to MAIN and LAUNCHER intents
|
||||||
|
-->
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
</application>
|
||||||
|
<!--
|
||||||
|
Requires a minimum platform version of Android-3 (SDK 1.5) to run
|
||||||
|
-->
|
||||||
|
<uses-sdk android:minSdkVersion="3"/>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
22
samples/Spinner/_index.html
Normal file
22
samples/Spinner/_index.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<p>
|
||||||
|
This sample is the application under test for the
|
||||||
|
<a href="../../../resources/tutorials/testing/activity_test.html">Activity
|
||||||
|
Testing Tutorial</a>. It contains a single Activity that displays a
|
||||||
|
Spinner widget backed by an array of strings containing the names of the planets
|
||||||
|
in the Solar System. When an entry is selected from the Spinner, the entry is
|
||||||
|
displayed in a text box.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
An important part of this application is state management. When the application
|
||||||
|
is first run, the spinner widget displays a default selection of
|
||||||
|
"Earth". Thereafter, the application saves a selection as soon as it
|
||||||
|
is made. The application remembers the selection from invocation to invocation, even
|
||||||
|
if the device reboots.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For more information about this application, see the Activity Testing Tutorial.
|
||||||
|
The test application for this application is in the <a
|
||||||
|
href="../SpinnerTest/index.html">SpinnerTest</a> sample application.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<img alt="The Spinner application" src="../images/testing/spinner_main_screen.png" />
|
||||||
48
samples/Spinner/res/layout/main.xml
Normal file
48
samples/Spinner/res/layout/main.xml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Creates a Linear Layout View to contain the spinner
|
||||||
|
-->
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Creates a spinner widget called Spinner01, within the Linear Layout
|
||||||
|
The prompt text comes from the string "planet_prompt" in strings.xml
|
||||||
|
-->
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/Spinner01"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:drawSelectorOnTop = "true"
|
||||||
|
android:prompt = "@string/planet_prompt">
|
||||||
|
</Spinner>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Creates a TextView called SpinnerResult, below the spinner.
|
||||||
|
-->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/SpinnerResult" android:text="Result"
|
||||||
|
android:layout_height="fill_parent" android:textSize="10pt"
|
||||||
|
android:textStyle="bold" android:gravity="center"
|
||||||
|
android:layout_width="fill_parent">
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
37
samples/Spinner/res/values/strings.xml
Normal file
37
samples/Spinner/res/values/strings.xml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The string named "app_name" defines the application's visible name.
|
||||||
|
The string array "Planets" defines an array of 9 strings. The application loads
|
||||||
|
this array into the spinner's array adapter.
|
||||||
|
The string "planet_prompt" defines the prompt for the result text box.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Spinner</string>
|
||||||
|
<string-array name="Planets">
|
||||||
|
<item>Mercury</item>
|
||||||
|
<item>Venus</item>
|
||||||
|
<item>Earth</item>
|
||||||
|
<item>Mars</item>
|
||||||
|
<item>Jupiter</item>
|
||||||
|
<item>Saturn</item>
|
||||||
|
<item>Uranus</item>
|
||||||
|
<item>Neptune</item>
|
||||||
|
<item>Pluto</item>
|
||||||
|
</string-array>
|
||||||
|
<string name="planet_prompt">Select a planet</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,374 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 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.example.spinner;
|
||||||
|
|
||||||
|
import com.android.example.spinner.R;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays an Android spinner widget backed by data in an array. The
|
||||||
|
* array is loaded from the strings.xml resources file.
|
||||||
|
*/
|
||||||
|
public class SpinnerActivity extends Activity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fields to contain the current position and display contents of the spinner
|
||||||
|
*/
|
||||||
|
protected int mPos;
|
||||||
|
protected String mSelection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArrayAdapter connects the spinner widget to array-based data.
|
||||||
|
*/
|
||||||
|
protected ArrayAdapter<CharSequence> mAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The initial position of the spinner when it is first installed.
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_POSITION = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of a properties file that stores the position and
|
||||||
|
* selection when the activity is not loaded.
|
||||||
|
*/
|
||||||
|
public static final String PREFERENCES_FILE = "SpinnerPrefs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These values are used to read and write the properties file.
|
||||||
|
* PROPERTY_DELIMITER delimits the key and value in a Java properties file.
|
||||||
|
* The "marker" strings are used to write the properties into the file
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_DELIMITER = "=";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key or label for "position" in the preferences file
|
||||||
|
*/
|
||||||
|
public static final String POSITION_KEY = "Position";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key or label for "selection" in the preferences file
|
||||||
|
*/
|
||||||
|
public static final String SELECTION_KEY = "Selection";
|
||||||
|
|
||||||
|
public static final String POSITION_MARKER =
|
||||||
|
POSITION_KEY + PROPERTY_DELIMITER;
|
||||||
|
|
||||||
|
public static final String SELECTION_MARKER =
|
||||||
|
SELECTION_KEY + PROPERTY_DELIMITER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the application and the activity.
|
||||||
|
* 1) Sets the view
|
||||||
|
* 2) Reads the spinner's backing data from the string resources file
|
||||||
|
* 3) Instantiates a callback listener for handling selection from the
|
||||||
|
* spinner
|
||||||
|
* Notice that this method includes code that can be uncommented to force
|
||||||
|
* tests to fail.
|
||||||
|
*
|
||||||
|
* This method overrides the default onCreate() method for an Activity.
|
||||||
|
*
|
||||||
|
* @see android.app.Activity#onCreate(android.os.Bundle)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* derived classes that use onCreate() overrides must always call the super constructor
|
||||||
|
*/
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.main);
|
||||||
|
|
||||||
|
Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a backing mLocalAdapter for the Spinner from a list of the
|
||||||
|
* planets. The list is defined by XML in the strings.xml file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.mAdapter = ArrayAdapter.createFromResource(this, R.array.Planets,
|
||||||
|
android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach the mLocalAdapter to the spinner.
|
||||||
|
*/
|
||||||
|
|
||||||
|
spinner.setAdapter(this.mAdapter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a listener that is triggered when Android detects the
|
||||||
|
* user has selected an item in the Spinner.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OnItemSelectedListener spinnerListener = new myOnItemSelectedListener(this,this.mAdapter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach the listener to the Spinner.
|
||||||
|
*/
|
||||||
|
|
||||||
|
spinner.setOnItemSelectedListener(spinnerListener);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To demonstrate a failure in the preConditions test,
|
||||||
|
* uncomment the following line.
|
||||||
|
* The test will fail because the selection listener for the
|
||||||
|
* Spinner is not set.
|
||||||
|
*/
|
||||||
|
// spinner.setOnItemSelectedListener(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback listener that implements the
|
||||||
|
* {@link android.widget.AdapterView.OnItemSelectedListener} interface
|
||||||
|
* For views based on adapters, this interface defines the methods available
|
||||||
|
* when the user selects an item from the View.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class myOnItemSelectedListener implements OnItemSelectedListener {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* provide local instances of the mLocalAdapter and the mLocalContext
|
||||||
|
*/
|
||||||
|
|
||||||
|
ArrayAdapter<CharSequence> mLocalAdapter;
|
||||||
|
Activity mLocalContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param c - The activity that displays the Spinner.
|
||||||
|
* @param ad - The Adapter view that
|
||||||
|
* controls the Spinner.
|
||||||
|
* Instantiate a new listener object.
|
||||||
|
*/
|
||||||
|
public myOnItemSelectedListener(Activity c, ArrayAdapter<CharSequence> ad) {
|
||||||
|
|
||||||
|
this.mLocalContext = c;
|
||||||
|
this.mLocalAdapter = ad;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the user selects an item in the spinner, this method is invoked by the callback
|
||||||
|
* chain. Android calls the item selected listener for the spinner, which invokes the
|
||||||
|
* onItemSelected method.
|
||||||
|
*
|
||||||
|
* @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(
|
||||||
|
* android.widget.AdapterView, android.view.View, int, long)
|
||||||
|
* @param parent - the AdapterView for this listener
|
||||||
|
* @param v - the View for this listener
|
||||||
|
* @param pos - the 0-based position of the selection in the mLocalAdapter
|
||||||
|
* @param row - the 0-based row number of the selection in the View
|
||||||
|
*/
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View v, int pos, long row) {
|
||||||
|
|
||||||
|
SpinnerActivity.this.mPos = pos;
|
||||||
|
SpinnerActivity.this.mSelection = parent.getItemAtPosition(pos).toString();
|
||||||
|
/*
|
||||||
|
* Set the value of the text field in the UI
|
||||||
|
*/
|
||||||
|
TextView resultText = (TextView)findViewById(R.id.SpinnerResult);
|
||||||
|
resultText.setText(SpinnerActivity.this.mSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The definition of OnItemSelectedListener requires an override
|
||||||
|
* of onNothingSelected(), even though this implementation does not use it.
|
||||||
|
* @param parent - The View for this Listener
|
||||||
|
*/
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
|
||||||
|
// do nothing
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the current state of the spinner (which item is selected, and the value
|
||||||
|
* of that item).
|
||||||
|
* Since onResume() is always called when an Activity is starting, even if it is re-displaying
|
||||||
|
* after being hidden, it is the best place to restore state.
|
||||||
|
*
|
||||||
|
* Attempts to read the state from a preferences file. If this read fails,
|
||||||
|
* assume it was just installed, so do an initialization. Regardless, change the
|
||||||
|
* state of the spinner to be the previous position.
|
||||||
|
*
|
||||||
|
* @see android.app.Activity#onResume()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* an override to onResume() must call the super constructor first.
|
||||||
|
*/
|
||||||
|
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to read the preferences file. If not found, set the state to the desired initial
|
||||||
|
* values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!readInstanceState(this)) setInitialState();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the spinner to the current state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Spinner restoreSpinner = (Spinner)findViewById(R.id.Spinner01);
|
||||||
|
restoreSpinner.setSelection(getSpinnerPosition());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store the current state of the spinner (which item is selected, and the value of that item).
|
||||||
|
* Since onPause() is always called when an Activity is about to be hidden, even if it is about
|
||||||
|
* to be destroyed, it is the best place to save state.
|
||||||
|
*
|
||||||
|
* Attempt to write the state to the preferences file. If this fails, notify the user.
|
||||||
|
*
|
||||||
|
* @see android.app.Activity#onPause()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* an override to onPause() must call the super constructor first.
|
||||||
|
*/
|
||||||
|
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the state to the preferences file. If it fails, display a Toast, noting the failure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!writeInstanceState(this)) {
|
||||||
|
Toast.makeText(this,
|
||||||
|
"Failed to write state!", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the initial state of the spinner when the application is first run.
|
||||||
|
*/
|
||||||
|
public void setInitialState() {
|
||||||
|
|
||||||
|
this.mPos = DEFAULT_POSITION;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the previous state of the spinner from the preferences file
|
||||||
|
* @param c - The Activity's Context
|
||||||
|
*/
|
||||||
|
public boolean readInstanceState(Context c) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The preferences are stored in a SharedPreferences file. The abstract implementation of
|
||||||
|
* SharedPreferences is a "file" containing a hashmap. All instances of an application
|
||||||
|
* share the same instance of this file, which means that all instances of an application
|
||||||
|
* share the same preference settings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the SharedPreferences object for this application
|
||||||
|
*/
|
||||||
|
|
||||||
|
SharedPreferences p = c.getSharedPreferences(PREFERENCES_FILE, MODE_WORLD_READABLE);
|
||||||
|
/*
|
||||||
|
* Get the position and value of the spinner from the file, or a default value if the
|
||||||
|
* key-value pair does not exist.
|
||||||
|
*/
|
||||||
|
this.mPos = p.getInt(POSITION_KEY, SpinnerActivity.DEFAULT_POSITION);
|
||||||
|
this.mSelection = p.getString(SELECTION_KEY, "");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SharedPreferences doesn't fail if the code tries to get a non-existent key. The
|
||||||
|
* most straightforward way to indicate success is to return the results of a test that
|
||||||
|
* SharedPreferences contained the position key.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return (p.contains(POSITION_KEY));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the application's current state to a properties repository.
|
||||||
|
* @param c - The Activity's Context
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public boolean writeInstanceState(Context c) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the SharedPreferences object for this application
|
||||||
|
*/
|
||||||
|
|
||||||
|
SharedPreferences p =
|
||||||
|
c.getSharedPreferences(SpinnerActivity.PREFERENCES_FILE, MODE_WORLD_READABLE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the editor for this object. The editor interface abstracts the implementation of
|
||||||
|
* updating the SharedPreferences object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
SharedPreferences.Editor e = p.edit();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Write the keys and values to the Editor
|
||||||
|
*/
|
||||||
|
|
||||||
|
e.putInt(POSITION_KEY, this.mPos);
|
||||||
|
e.putString(SELECTION_KEY, this.mSelection);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Commit the changes. Return the result of the commit. The commit fails if Android
|
||||||
|
* failed to commit the changes to persistent storage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return (e.commit());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSpinnerPosition() {
|
||||||
|
return this.mPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpinnerPosition(int pos) {
|
||||||
|
this.mPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSpinnerSelection() {
|
||||||
|
return this.mSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSpinnerSelection(String selection) {
|
||||||
|
this.mSelection = selection;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
samples/SpinnerTest/AndroidManifest.xml
Normal file
45
samples/SpinnerTest/AndroidManifest.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Declare the contents of this Android application. The "namespace"
|
||||||
|
attribute brings in the Android platform namespace, and the
|
||||||
|
"package" attribute provides a unique Android name for the application.
|
||||||
|
If you use this file as a template in your own application, you must change
|
||||||
|
the package name from "com.android.example" to one that you own or have
|
||||||
|
control over.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.android.example.spinner.test"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
<application android:label="@string/app_name">
|
||||||
|
<!--
|
||||||
|
this package needs to link against the android.test library,
|
||||||
|
which is needed when building test cases.
|
||||||
|
-->
|
||||||
|
<uses-library android:name="android.test.runner"/>
|
||||||
|
</application>
|
||||||
|
<!--
|
||||||
|
This declares that this application uses the instrumentation test runner targeting
|
||||||
|
the package of com.android.example.spinner. To run the tests use the command:
|
||||||
|
"adb shell am instrument -w \
|
||||||
|
com.android.example.spinner.test/android.test.InstrumentationTestRunner"
|
||||||
|
-->
|
||||||
|
<instrumentation android:name="android.test.InstrumentationTestRunner"
|
||||||
|
android:targetPackage="com.android.example.spinner"
|
||||||
|
android:label="Tests for com.android.example.spinner"/>
|
||||||
|
</manifest>
|
||||||
9
samples/SpinnerTest/_index.html
Normal file
9
samples/SpinnerTest/_index.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<p>
|
||||||
|
This sample is the test application for the
|
||||||
|
<a href="../../../resources/tutorials/testing/activity_test.html">Activity
|
||||||
|
Testing Tutorial</a>. Refer to the tutorial text for a full explanation
|
||||||
|
of this sample code.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This application does not have an Android GUI.
|
||||||
|
</p>
|
||||||
22
samples/SpinnerTest/res/values/strings.xml
Normal file
22
samples/SpinnerTest/res/values/strings.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2007 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This defines the test application's name
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">SpinnerTest</string>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,345 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 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.example.spinner.test;
|
||||||
|
|
||||||
|
import com.android.example.spinner.SpinnerActivity;
|
||||||
|
|
||||||
|
import android.app.Instrumentation;
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.test.UiThreadTest;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.SpinnerAdapter;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the example application Spinner. Uses the instrumentation test class
|
||||||
|
* {@link ActivityInstrumentationTestCase2} as its base class. The tests include
|
||||||
|
* <ol>
|
||||||
|
* <li>test initial conditions</li>
|
||||||
|
* <li>test the UI</li>
|
||||||
|
* <li>state management - preserving state after the app is shut down and restarted, preserving
|
||||||
|
* state after the app is hidden (paused) and re-displayed (resumed)</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* Demonstrates the use of JUnit setUp() and assert() methods.
|
||||||
|
*/
|
||||||
|
public class SpinnerActivityTest extends ActivityInstrumentationTestCase2<SpinnerActivity> {
|
||||||
|
|
||||||
|
// Number of items in the spinner's backing mLocalAdapter
|
||||||
|
|
||||||
|
public static final int ADAPTER_COUNT = 9;
|
||||||
|
|
||||||
|
// The location of Saturn in the backing mLocalAdapter array (0-based)
|
||||||
|
|
||||||
|
public static final int TEST_POSITION = 5;
|
||||||
|
|
||||||
|
// Set the initial position of the spinner to zero
|
||||||
|
|
||||||
|
public static final int INITIAL_POSITION = 0;
|
||||||
|
|
||||||
|
// The initial position corresponds to Mercury
|
||||||
|
|
||||||
|
public static final String INITIAL_SELECTION = "Mercury";
|
||||||
|
|
||||||
|
// Test values of position and selection for the testStateDestroy test
|
||||||
|
|
||||||
|
public static final int TEST_STATE_DESTROY_POSITION = 2;
|
||||||
|
public static final String TEST_STATE_DESTROY_SELECTION = "Earth";
|
||||||
|
|
||||||
|
// Test values of position and selection for the testStatePause test
|
||||||
|
|
||||||
|
public static final int TEST_STATE_PAUSE_POSITION = 4;
|
||||||
|
public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter";
|
||||||
|
|
||||||
|
// The Application object for the application under test
|
||||||
|
|
||||||
|
private SpinnerActivity mActivity;
|
||||||
|
|
||||||
|
// String displayed in the spinner in the app under test
|
||||||
|
|
||||||
|
private String mSelection;
|
||||||
|
|
||||||
|
// The currently selected position in the spinner in the app under test
|
||||||
|
|
||||||
|
private int mPos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Spinner object in the app under test. Used with instrumentation to control the
|
||||||
|
* app under test.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private Spinner mSpinner;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The data backing the Spinner in the app under test.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private SpinnerAdapter mPlanetData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the test class. Required by Android test classes. The constructor
|
||||||
|
* must call the super constructor, providing the Android package name of the app under test
|
||||||
|
* and the Java class name of the activity in that application that handles the MAIN intent.
|
||||||
|
*/
|
||||||
|
public SpinnerActivityTest() {
|
||||||
|
|
||||||
|
super("com.android.example.spinner", SpinnerActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the test environment before each test.
|
||||||
|
* @see android.test.ActivityInstrumentationTestCase2#setUp()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the super constructor (required by JUnit)
|
||||||
|
*/
|
||||||
|
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prepare to send key events to the app under test by turning off touch mode.
|
||||||
|
* Must be done before the first call to getActivity()
|
||||||
|
*/
|
||||||
|
|
||||||
|
setActivityInitialTouchMode(false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the app under test by starting its main activity. The test runner already knows
|
||||||
|
* which activity this is from the call to the super constructor, as mentioned
|
||||||
|
* previously. The tests can now use instrumentation to directly access the main
|
||||||
|
* activity through mActivity.
|
||||||
|
*/
|
||||||
|
mActivity = getActivity();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get references to objects in the application under test. These are
|
||||||
|
* tested to ensure that the app under test has initialized correctly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);
|
||||||
|
|
||||||
|
mPlanetData = mSpinner.getAdapter();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the initial values of key objects in the app under test, to ensure the initial
|
||||||
|
* conditions make sense. If one of these is not initialized correctly, then subsequent
|
||||||
|
* tests are suspect and should be ignored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void testPreconditions() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An example of an initialization test. Assert that the item select listener in
|
||||||
|
* the main Activity is not null (has been set to a valid callback)
|
||||||
|
*/
|
||||||
|
assertTrue(mSpinner.getOnItemSelectedListener() != null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that the spinner's backing mLocalAdapter was initialized correctly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
assertTrue(mPlanetData != null);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also ensure that the backing mLocalAdapter has the correct number of entries.
|
||||||
|
*/
|
||||||
|
|
||||||
|
assertEquals(mPlanetData.getCount(), ADAPTER_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests the UI of the main activity. Sends key events (keystrokes) to the UI, then checks
|
||||||
|
* if the resulting spinner state is consistent with the attempted selection.
|
||||||
|
*/
|
||||||
|
public void testSpinnerUI() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request focus for the spinner widget in the application under test,
|
||||||
|
* and set its initial position. This code interacts with the app's View
|
||||||
|
* so it has to run on the app's thread not the test's thread.
|
||||||
|
*
|
||||||
|
* To do this, pass the necessary code to the application with
|
||||||
|
* runOnUiThread(). The parameter is an anonymous Runnable object that
|
||||||
|
* contains the Java statements put in it by its run() method.
|
||||||
|
*/
|
||||||
|
mActivity.runOnUiThread(
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
mSpinner.requestFocus();
|
||||||
|
mSpinner.setSelection(INITIAL_POSITION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Activate the spinner by clicking the center keypad key
|
||||||
|
|
||||||
|
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
|
||||||
|
|
||||||
|
// send 5 down arrow keys to the spinner
|
||||||
|
|
||||||
|
for (int i = 1; i <= TEST_POSITION; i++) {
|
||||||
|
|
||||||
|
this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
// select the item at the current spinner position
|
||||||
|
|
||||||
|
this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
|
||||||
|
|
||||||
|
// get the position of the selected item
|
||||||
|
|
||||||
|
mPos = mSpinner.getSelectedItemPosition();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* from the spinner's data mLocalAdapter, get the object at the selected position
|
||||||
|
* (this is a String value)
|
||||||
|
*/
|
||||||
|
|
||||||
|
mSelection = (String)mSpinner.getItemAtPosition(mPos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the TextView widget that displays the result of selecting an item from the spinner
|
||||||
|
*/
|
||||||
|
|
||||||
|
TextView resultView =
|
||||||
|
(TextView) mActivity.findViewById(com.android.example.spinner.R.id.SpinnerResult);
|
||||||
|
|
||||||
|
// Get the String value in the EditText object
|
||||||
|
|
||||||
|
String resultText = (String) resultView.getText();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Confirm that the EditText contains the same value as the data in the mLocalAdapter
|
||||||
|
*/
|
||||||
|
|
||||||
|
assertEquals(resultText,mSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests that the activity under test maintains the spinner state when the activity halts
|
||||||
|
* and then restarts (for example, if the device reboots). Sets the spinner to a
|
||||||
|
* certain state, calls finish() on the activity, restarts the activity, and then
|
||||||
|
* checks that the spinner has the same state.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void testStateDestroy() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the position and value of the spinner in the Activity. The test runner's
|
||||||
|
* instrumentation enables this by running the test app and the main app in the same
|
||||||
|
* process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
|
||||||
|
|
||||||
|
mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
|
||||||
|
|
||||||
|
// Halt the Activity by calling Activity.finish() on it
|
||||||
|
|
||||||
|
mActivity.finish();
|
||||||
|
|
||||||
|
// Restart the activity by calling ActivityInstrumentationTestCase2.getActivity()
|
||||||
|
|
||||||
|
mActivity = this.getActivity();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the current position and selection from the activity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int currentPosition = mActivity.getSpinnerPosition();
|
||||||
|
String currentSelection = mActivity.getSpinnerSelection();
|
||||||
|
|
||||||
|
// test that they are the same.
|
||||||
|
|
||||||
|
assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
|
||||||
|
|
||||||
|
assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests that the activity under test maintains the spinner's state when the activity is
|
||||||
|
* paused and then resumed.
|
||||||
|
*
|
||||||
|
* Calls the activity's onResume() method. Changes the spinner's state by
|
||||||
|
* altering the activity's View. This means the test must run
|
||||||
|
* on the UI Thread. All the statements in the test method may be run on
|
||||||
|
* that thread, so instead of using the runOnUiThread() method, the
|
||||||
|
* @UiThreadTest is used.
|
||||||
|
*/
|
||||||
|
@UiThreadTest
|
||||||
|
|
||||||
|
public void testStatePause() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the instrumentation object for this application. This object
|
||||||
|
* does all the instrumentation work for the test runner
|
||||||
|
*/
|
||||||
|
|
||||||
|
Instrumentation instr = this.getInstrumentation();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the activity's fields for the position and value of the spinner
|
||||||
|
*/
|
||||||
|
|
||||||
|
mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
|
||||||
|
|
||||||
|
mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use the instrumentation to onPause() on the currently running Activity.
|
||||||
|
* This analogous to calling finish() in the testStateDestroy() method.
|
||||||
|
* This way demonstrates using the test class' instrumentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
instr.callActivityOnPause(mActivity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the spinner to a test position
|
||||||
|
*/
|
||||||
|
|
||||||
|
mActivity.setSpinnerPosition(0);
|
||||||
|
|
||||||
|
mActivity.setSpinnerSelection("");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the activity's onResume() method. This forces the activity
|
||||||
|
* to restore its state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
instr.callActivityOnResume(mActivity);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the current state of the spinner
|
||||||
|
*/
|
||||||
|
|
||||||
|
int currentPosition = mActivity.getSpinnerPosition();
|
||||||
|
|
||||||
|
String currentSelection = mActivity.getSpinnerSelection();
|
||||||
|
|
||||||
|
assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition);
|
||||||
|
assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user