Merge "Add the variable speed tests to the test runner."
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
index 5d89957..ba6d567 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
@@ -50,6 +50,7 @@
private static final String TAG = "MonkeyStub";
/* The version of the monkey network protocol */
public static final int MONKEY_NETWORK_VERSION = 2;
+ private static DeferredReturn deferredReturn;
/**
* ReturnValue from the MonkeyCommand that indicates whether the
@@ -378,6 +379,52 @@
}
/**
+ * Command to defer the return of another command until the given event occurs.
+ * deferreturn takes three arguments. It takes an event to wait for (e.g. waiting for the
+ * device to display a different activity would the "screenchange" event), a
+ * timeout, which is the number of microseconds to wait for the event to occur, and it takes
+ * a command. The command can be any other Monkey command that can be issued over the network
+ * (e.g. press KEYCODE_HOME). deferreturn will then run this command, return an OK, wait for
+ * the event to occur and return the deferred return value when either the event occurs or
+ * when the timeout is reached (whichever occurs first). Note that there is no difference
+ * between an event occurring and the timeout being reached; the client will have to verify
+ * that the change actually occured.
+ *
+ * Example:
+ * deferreturn screenchange 1000 press KEYCODE_HOME
+ * This command will press the home key on the device and then wait for the screen to change
+ * for up to one second. Either the screen will change, and the results fo the key press will
+ * be returned to the client, or the timeout will be reached, and the results for the key
+ * press will be returned to the client.
+ */
+ private static class DeferReturnCommand implements MonkeyCommand {
+ // deferreturn [event] [timeout (ms)] [command]
+ // deferreturn screenchange 100 tap 10 10
+ public MonkeyCommandReturn translateCommand(List<String> command,
+ CommandQueue queue) {
+ if (command.size() > 3) {
+ String event = command.get(1);
+ int eventId;
+ if (event.equals("screenchange")) {
+ eventId = DeferredReturn.ON_WINDOW_STATE_CHANGE;
+ } else {
+ return EARG;
+ }
+ long timeout = Long.parseLong(command.get(2));
+ MonkeyCommand deferredCommand = COMMAND_MAP.get(command.get(3));
+ if (deferredCommand != null) {
+ List<String> parts = command.subList(3, command.size());
+ MonkeyCommandReturn ret = deferredCommand.translateCommand(parts, queue);
+ deferredReturn = new DeferredReturn(eventId, ret, timeout);
+ return OK;
+ }
+ }
+ return EARG;
+ }
+ }
+
+
+ /**
* Force the device to wake up.
*
* @return true if woken up OK.
@@ -415,6 +462,7 @@
COMMAND_MAP.put("getrootview", new MonkeySourceNetworkViews.GetRootViewCommand());
COMMAND_MAP.put("getviewswithtext",
new MonkeySourceNetworkViews.GetViewsWithTextCommand());
+ COMMAND_MAP.put("deferreturn", new DeferReturnCommand());
}
// QUIT command
@@ -458,6 +506,40 @@
}
};
+ // A holder class for a deferred return value. This allows us to defer returning the success of
+ // a call until a given event has occurred.
+ private static class DeferredReturn {
+ public static final int ON_WINDOW_STATE_CHANGE = 1;
+
+ private int event;
+ private MonkeyCommandReturn deferredReturn;
+ private long timeout;
+
+ public DeferredReturn(int event, MonkeyCommandReturn deferredReturn, long timeout) {
+ this.event = event;
+ this.deferredReturn = deferredReturn;
+ this.timeout = timeout;
+ }
+
+ /**
+ * Wait until the given event has occurred before returning the value.
+ * @return The MonkeyCommandReturn from the command that was deferred.
+ */
+ public MonkeyCommandReturn waitForEvent() {
+ switch(event) {
+ case ON_WINDOW_STATE_CHANGE:
+ try {
+ synchronized(MonkeySourceNetworkViews.sConnection) {
+ MonkeySourceNetworkViews.sConnection.wait(timeout);
+ }
+ } catch(InterruptedException e) {
+ Log.d(TAG, "Deferral interrupted: " + e.getMessage());
+ }
+ }
+ return deferredReturn;
+ }
+ };
+
private final CommandQueueImpl commandQueue = new CommandQueueImpl();
private BufferedReader input;
@@ -571,23 +653,28 @@
MonkeyCommand command = COMMAND_MAP.get(parts.get(0));
if (command != null) {
MonkeyCommandReturn ret = command.translateCommand(parts, commandQueue);
- if (ret.wasSuccessful()) {
- if (ret.hasMessage()) {
- returnOk(ret.getMessage());
- } else {
- returnOk();
- }
- } else {
- if (ret.hasMessage()) {
- returnError(ret.getMessage());
- } else {
- returnError();
- }
- }
+ handleReturn(ret);
}
}
}
+ private void handleReturn(MonkeyCommandReturn ret) {
+ if (ret.wasSuccessful()) {
+ if (ret.hasMessage()) {
+ returnOk(ret.getMessage());
+ } else {
+ returnOk();
+ }
+ } else {
+ if (ret.hasMessage()) {
+ returnError(ret.getMessage());
+ } else {
+ returnError();
+ }
+ }
+ }
+
+
public MonkeyEvent getNextEvent() {
if (!started) {
try {
@@ -611,6 +698,16 @@
return queuedEvent;
}
+ // Check to see if we have any returns that have been deferred. If so, now that
+ // we've run the queued commands, wait for the given event to happen (or the timeout
+ // to be reached), and handle the deferred MonkeyCommandReturn.
+ if (deferredReturn != null) {
+ Log.d(TAG, "Waiting for event");
+ MonkeyCommandReturn ret = deferredReturn.waitForEvent();
+ deferredReturn = null;
+ handleReturn(ret);
+ }
+
String command = input.readLine();
if (command == null) {
Log.d(TAG, "Connection dropped.");
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
index f96f133..a32b8a5 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
@@ -111,7 +111,11 @@
public void onInterrupt() {}
public void onAccessibilityEvent(AccessibilityEvent event) {
- sLastAccessibilityEvent.set(AccessibilityEvent.obtain(event));
+ Log.d(TAG, "Accessibility Event");
+ sLastAccessibilityEvent.set(AccessibilityEvent.obtain(event));
+ synchronized(sConnection) {
+ sConnection.notifyAll();
+ }
}
};
IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
@@ -402,6 +406,11 @@
if (node.isPassword()){
return new MonkeyCommandReturn(false, "Node contains a password");
}
+ /* Occasionally we get a null from the accessibility API, rather than an empty
+ * string */
+ if (node.getText() == null) {
+ return new MonkeyCommandReturn(true, "");
+ }
return new MonkeyCommandReturn(true, node.getText().toString());
}
return EARG;
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index 470c584..4d00c06 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -35,7 +35,6 @@
<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
<classpathentry kind="src" path="frameworks/base/core/java"/>
- <classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
<classpathentry kind="src" path="frameworks/base/drm/java"/>
<classpathentry kind="src" path="frameworks/base/graphics/java"/>
<classpathentry kind="src" path="frameworks/base/icu4j/java"/>
@@ -56,6 +55,7 @@
<classpathentry kind="src" path="frameworks/ex/carousel/java"/>
<classpathentry kind="src" path="frameworks/ex/chips/src"/>
<classpathentry kind="src" path="frameworks/ex/common/java"/>
+ <classpathentry kind="src" path="frameworks/ex/variablespeed/src"/>
<classpathentry kind="src" path="frameworks/opt/calendar/src"/>
<classpathentry kind="src" path="frameworks/opt/vcard/java"/>
<classpathentry kind="src" path="frameworks/support/v13/java"/>
@@ -74,7 +74,6 @@
<classpathentry kind="src" path="development/samples/SkeletonApp/tests/src"/>
<classpathentry kind="src" path="development/samples/Snake/src"/>
<classpathentry kind="src" path="development/samples/Snake/tests/src"/>
- <classpathentry kind="src" path="development/apps/Term/src"/>
<classpathentry kind="src" path="libcore/dalvik/src/main/java"/>
<classpathentry kind="src" path="libcore/json/src/main/java"/>
<classpathentry kind="src" path="libcore/junit/src/main/java"/>
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 1fcf7ee..b70ed4d 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -263,6 +263,15 @@
</intent-filter>
</activity>
+ <activity android:name=".app.FragmentCustomAnimations"
+ android:label="@string/fragment_custom_animations"
+ android:enabled="@bool/atLeastHoneycombMR2">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".app.FragmentHideShow"
android:label="@string/fragment_hide_show"
android:windowSoftInputMode="stateUnchanged"
@@ -480,6 +489,14 @@
</intent-filter>
</activity>
+ <activity android:name=".app.RemoteService$BindingOptions"
+ android:label="@string/activity_remote_service_binding_options">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<service android:name=".app.ServiceStartArguments" />
<activity android:name=".app.ServiceStartArguments$Controller"
@@ -2003,6 +2020,16 @@
android:value=".app.SearchQueryResults" />
</activity>
+ <activity android:name=".view.SearchViewAlwaysVisible" android:label="Views/Search View/Always Expanded"
+ android:theme="@android:style/Theme.Holo">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.SAMPLE_CODE" />
+ </intent-filter>
+ <meta-data android:name="android.app.default_searchable"
+ android:value=".app.SearchQueryResults" />
+ </activity>
+
<activity android:name=".view.SearchViewFilterMode" android:label="Views/Search View/Filter"
android:theme="@android:style/Theme.Holo">
<intent-filter>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml b/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml
new file mode 100644
index 0000000..11f1ee6
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="100dp" android:valueTo="0dp"
+ android:valueType="floatType"
+ android:propertyName="translationX"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="0.0" android:valueTo="1.0"
+ android:valueType="floatType"
+ android:propertyName="alpha"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml b/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml
new file mode 100644
index 0000000..096f04a
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="0dp" android:valueTo="-100dp"
+ android:valueType="floatType"
+ android:propertyName="translationX"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="1.0" android:valueTo="0.0"
+ android:valueType="floatType"
+ android:propertyName="alpha"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml b/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml
new file mode 100644
index 0000000..86f53be
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="-100dp" android:valueTo="0dp"
+ android:valueType="floatType"
+ android:propertyName="translationX"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="0.0" android:valueTo="1.0"
+ android:valueType="floatType"
+ android:propertyName="alpha"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml b/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml
new file mode 100644
index 0000000..7d02956
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="0dp" android:valueTo="100dp"
+ android:valueType="floatType"
+ android:propertyName="translationX"
+ android:duration="@android:integer/config_mediumAnimTime" />
+ <objectAnimator
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:valueFrom="1.0" android:valueTo="0.0"
+ android:valueType="floatType"
+ android:propertyName="alpha"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/layout/remote_binding_options.xml b/samples/ApiDemos/res/layout/remote_binding_options.xml
new file mode 100644
index 0000000..aec33f8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/remote_binding_options.xml
@@ -0,0 +1,82 @@
+<?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.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+ See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent" android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:paddingBottom="4dip"
+ android:text="Demonstrates various options that can be used when binding to a service to modify its process management."/>
+
+ <TextView android:id="@+id/callback"
+ android:layout_width="match_parent" android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:gravity="center_horizontal" android:paddingBottom="4dip"/>
+
+ <ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
+ <LinearLayout android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:layout_width="match_parent" android:layout_height="wrap_content">
+ <Button android:id="@+id/bind_normal"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Normal">
+ <requestFocus />
+ </Button>
+
+ <Button android:id="@+id/bind_not_foreground"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Not Foreground">
+ </Button>
+
+ <Button android:id="@+id/bind_above_client"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Above Client">
+ </Button>
+
+ <Button android:id="@+id/bind_allow_oom"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Allow OOM Management">
+ </Button>
+
+ <Button android:id="@+id/bind_waive_priority"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Waive Priority">
+ </Button>
+
+ <Button android:id="@+id/bind_important"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Important">
+ </Button>
+
+ <Button android:id="@+id/bind_with_activity"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="Adjust With Activity">
+ </Button>
+
+ <Button android:id="@+id/unbind"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:text="@string/unbind_service">
+ </Button>
+ </LinearLayout>
+ </ScrollView>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index c87c563..1aaff9a 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -114,6 +114,8 @@
<string name="fragment_arguments_embedded">From Attributes</string>
<string name="fragment_arguments_embedded_land">Landscape Only</string>
+ <string name="fragment_custom_animations">App/Fragment/Custom Animations</string>
+
<string name="fragment_hide_show">App/Fragment/Hide and Show</string>
<string name="fragment_context_menu">App/Fragment/Context Menu</string>
@@ -206,8 +208,11 @@
<string name="kill_process">Kill Process</string>
<string name="remote_service_connected">Connected to remote service</string>
<string name="remote_service_disconnected">Disconnected from remote service</string>
+ <string name="remote_service_unbind_disconn">Unbinding due to disconnect</string>
<string name="remote_call_failed">Failure calling remote service</string>
+ <string name="activity_remote_service_binding_options">App/Service/Remote Service Binding Options</string>
+
<string name="service_start_arguments_label">Sample Service Start Arguments
</string>
diff --git a/samples/ApiDemos/res/xml/searchable.xml b/samples/ApiDemos/res/xml/searchable.xml
index df4ef7a..a2d048a 100644
--- a/samples/ApiDemos/res/xml/searchable.xml
+++ b/samples/ApiDemos/res/xml/searchable.xml
@@ -19,8 +19,7 @@
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
- android:hint="@string/search_hint"
- android:searchMode="showSearchLabelAsBadge"
+ android:hint="@string/search_hint"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:voiceLanguageModel="free_form"
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java
new file mode 100644
index 0000000..157b624
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java
@@ -0,0 +1,131 @@
+/*
+ * 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.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstrates the use of custom animations in a FragmentTransaction when
+ * pushing and popping a stack.
+ */
+public class FragmentCustomAnimations extends Activity {
+ int mStackLevel = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.fragment_stack);
+
+ // Watch for button clicks.
+ Button button = (Button)findViewById(R.id.new_fragment);
+ button.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ addFragmentToStack();
+ }
+ });
+
+ if (savedInstanceState == null) {
+ // Do first time initialization -- add initial fragment.
+ Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ ft.add(R.id.simple_fragment, newFragment).commit();
+ } else {
+ mStackLevel = savedInstanceState.getInt("level");
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt("level", mStackLevel);
+ }
+
+//BEGIN_INCLUDE(add_stack)
+ void addFragmentToStack() {
+ mStackLevel++;
+
+ // Instantiate a new fragment.
+ Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+ // Add the fragment to the activity, pushing this transaction
+ // on to the back stack.
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ ft.setCustomAnimations(R.animator.fragment_slide_left_enter,
+ R.animator.fragment_slide_left_exit,
+ R.animator.fragment_slide_right_enter,
+ R.animator.fragment_slide_right_exit);
+ ft.replace(R.id.simple_fragment, newFragment);
+ ft.addToBackStack(null);
+ ft.commit();
+ }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+ public static class CountingFragment extends Fragment {
+ int mNum;
+
+ /**
+ * Create a new instance of CountingFragment, providing "num"
+ * as an argument.
+ */
+ static CountingFragment newInstance(int num) {
+ CountingFragment f = new CountingFragment();
+
+ // Supply num input as an argument.
+ Bundle args = new Bundle();
+ args.putInt("num", num);
+ f.setArguments(args);
+
+ return f;
+ }
+
+ /**
+ * When creating, retrieve this instance's number from its arguments.
+ */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+ }
+
+ /**
+ * The Fragment's UI is just a simple text view showing its
+ * instance number.
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.hello_world, container, false);
+ View tv = v.findViewById(R.id.text);
+ ((TextView)tv).setText("Fragment #" + mNum);
+ tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+ return v;
+ }
+ }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
index aade659..76458f4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
@@ -461,4 +461,192 @@
};
}
// END_INCLUDE(calling_a_service)
+
+ // ----------------------------------------------------------------------
+
+ /**
+ * Examples of behavior of different bind flags.</p>
+ */
+ // BEGIN_INCLUDE(calling_a_service)
+ public static class BindingOptions extends Activity {
+ ServiceConnection mCurConnection;
+ TextView mCallbackText;
+
+ class MyServiceConnection implements ServiceConnection {
+ final boolean mUnbindOnDisconnect;
+
+ public MyServiceConnection() {
+ mUnbindOnDisconnect = false;
+ }
+
+ public MyServiceConnection(boolean unbindOnDisconnect) {
+ mUnbindOnDisconnect = unbindOnDisconnect;
+ }
+
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ if (mCurConnection != this) {
+ return;
+ }
+ mCallbackText.setText("Attached.");
+ Toast.makeText(BindingOptions.this, R.string.remote_service_connected,
+ Toast.LENGTH_SHORT).show();
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ if (mCurConnection != this) {
+ return;
+ }
+ mCallbackText.setText("Disconnected.");
+ Toast.makeText(BindingOptions.this, R.string.remote_service_disconnected,
+ Toast.LENGTH_SHORT).show();
+ if (mUnbindOnDisconnect) {
+ unbindService(this);
+ mCurConnection = null;
+ Toast.makeText(BindingOptions.this, R.string.remote_service_unbind_disconn,
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+ /**
+ * Standard initialization of this activity. Set up the UI, then wait
+ * for the user to poke it before doing anything.
+ */
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.remote_binding_options);
+
+ // Watch for button clicks.
+ Button button = (Button)findViewById(R.id.bind_normal);
+ button.setOnClickListener(mBindNormalListener);
+ button = (Button)findViewById(R.id.bind_not_foreground);
+ button.setOnClickListener(mBindNotForegroundListener);
+ button = (Button)findViewById(R.id.bind_above_client);
+ button.setOnClickListener(mBindAboveClientListener);
+ button = (Button)findViewById(R.id.bind_allow_oom);
+ button.setOnClickListener(mBindAllowOomListener);
+ button = (Button)findViewById(R.id.bind_waive_priority);
+ button.setOnClickListener(mBindWaivePriorityListener);
+ button = (Button)findViewById(R.id.bind_important);
+ button.setOnClickListener(mBindImportantListener);
+ button = (Button)findViewById(R.id.bind_with_activity);
+ button.setOnClickListener(mBindWithActivityListener);
+ button = (Button)findViewById(R.id.unbind);
+ button.setOnClickListener(mUnbindListener);
+
+ mCallbackText = (TextView)findViewById(R.id.callback);
+ mCallbackText.setText("Not attached.");
+ }
+
+ private OnClickListener mBindNormalListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindNotForegroundListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindAboveClientListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_ABOVE_CLIENT)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindAllowOomListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindWaivePriorityListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection(true);
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindImportantListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mBindWithActivityListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ ServiceConnection conn = new MyServiceConnection();
+ if (bindService(new Intent(IRemoteService.class.getName()),
+ conn, Context.BIND_AUTO_CREATE | Context.BIND_ADJUST_WITH_ACTIVITY
+ | Context.BIND_WAIVE_PRIORITY)) {
+ mCurConnection = conn;
+ }
+ }
+ };
+
+ private OnClickListener mUnbindListener = new OnClickListener() {
+ public void onClick(View v) {
+ if (mCurConnection != null) {
+ unbindService(mCurConnection);
+ mCurConnection = null;
+ }
+ }
+ };
+ }
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/_index.html b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
index e9d1cf5..4333d57 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
@@ -101,6 +101,10 @@
<dd>Demonstrates how to display and respond to a context menu that is
display from a fragment's view hierarchy.</dd>
+ <dt><a href="FragmentCustomAnimation.html">Fragment Custom Animation</a></dt>
+ <dd>Demonstrates the use of a custom animation for pushing and popping fragments
+ on the back stack.</dd>
+
<dt><a href="FragmentDialog.html">Fragment Dialog</a></dt>
<dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>
@@ -156,6 +160,10 @@
default Honeycomb theme includes the Action Bar by default and a menu resource is used to populate
the menu data itself. If you'd like to see how these things work under the hood, see
Mechanics.</dd>
+ <dt><a href="ActionBarActionProviderActivity.html">ActionProvider</a></dt>
+ <dd>Shows how to use an ActionProvider to supply a menu item with a specialized action view and
+ handle standard menu item clicks in one place. Demonstrated using the streamlined sharing UI
+ added in ICS. </dd>
<dt><a href="ActionBarDisplayOptions.html">Display Options</a></dt>
<dd>Shows how various Action Bar display option flags can be combined and their effects.</dd>
</dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
index 7488fcc..8ffa3b9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
@@ -25,8 +25,10 @@
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
import android.view.Window;
+import android.view.MenuItem.OnActionExpandListener;
import android.widget.Button;
import android.widget.SearchView;
import android.widget.TextView;
@@ -65,15 +67,21 @@
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.searchview_in_menu, menu);
- mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
- setupSearchView();
+ MenuItem searchItem = menu.findItem(R.id.action_search);
+ mSearchView = (SearchView) searchItem.getActionView();
+ setupSearchView(searchItem);
return true;
}
- private void setupSearchView() {
+ private void setupSearchView(MenuItem searchItem) {
- mSearchView.setIconifiedByDefault(true);
+ if (isAlwaysExpanded()) {
+ mSearchView.setIconifiedByDefault(false);
+ } else {
+ searchItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM
+ | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
+ }
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
if (searchManager != null) {
@@ -116,4 +124,8 @@
mSearchView.setIconified(false);
}
}
+
+ protected boolean isAlwaysExpanded() {
+ return false;
+ }
}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java
new file mode 100644
index 0000000..8c67563
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.app.SearchableInfo;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.SearchView;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * This demonstrates the usage of SearchView in an ActionBar as a menu item.
+ * It sets a SearchableInfo on the SearchView for suggestions and submitting queries to.
+ */
+public class SearchViewAlwaysVisible extends SearchViewActionBar {
+
+ @Override
+ protected boolean isAlwaysExpanded() {
+ return true;
+ }
+}
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
index f94e3e2..d61557c 100644
--- a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
@@ -68,7 +68,7 @@
bc.dimX = rsAllocationGetDimX(bc.ain);
bc.dt = 1.f / 30.f;
- rsForEach(physics_script, bc.ain, bc.aout, &bc);
+ rsForEach(physics_script, bc.ain, bc.aout, &bc, sizeof(bc));
for (uint32_t ct=0; ct < bc.dimX; ct++) {
point[ct].position = bout[ct].position;
diff --git a/samples/SampleSyncAdapter/AndroidManifest.xml b/samples/SampleSyncAdapter/AndroidManifest.xml
index fd53a16..ec8b779 100644
--- a/samples/SampleSyncAdapter/AndroidManifest.xml
+++ b/samples/SampleSyncAdapter/AndroidManifest.xml
@@ -47,7 +47,7 @@
android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
-
+
<application
android:icon="@drawable/icon"
android:label="@string/label">
@@ -112,6 +112,16 @@
<data
android:mimeType="vnd.android.cursor.item/raw_contact" />
</intent-filter>
+ <!--
+ We use the INVITE intent to add a raw contact to an existing contact.
+ It always comes with a lookup URI.
+ -->
+ <intent-filter>
+ <action
+ android:name="com.android.contacts.action.INVITE_CONTACT" />
+ <data
+ android:mimeType="vnd.android.cursor.item/contact" />
+ </intent-filter>
</activity>
</application>
</manifest>
diff --git a/samples/SampleSyncAdapter/res/values/strings.xml b/samples/SampleSyncAdapter/res/values/strings.xml
index 3b5ac58..7ac95f5 100644
--- a/samples/SampleSyncAdapter/res/values/strings.xml
+++ b/samples/SampleSyncAdapter/res/values/strings.xml
@@ -102,4 +102,11 @@
name="menu_done">Done</string>
<string
name="menu_cancel">Cancel</string>
+
+ <!-- Strings for contacts.xml -->
+ <skip />
+
+ <!-- The label of the button to add contact to this contact provider -->
+ <string name="invite_action_label">Add to Sample SyncAdaper</string>
+
</resources>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/xml-v14/contacts.xml b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
new file mode 100644
index 0000000..09b9e8f
--- /dev/null
+++ b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2011, 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.
+ */
+-->
+
+<ContactsAccountType
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+ createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+ inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+ inviteContactActionLabel="@string/invite_action_label"
+>
+
+ <ContactsDataKind
+ android:mimeType="vnd.android.cursor.item/vnd.samplesyncadapter.profile"
+ android:icon="@drawable/icon"
+ android:summaryColumn="data2"
+ android:detailColumn="data3"
+ android:detailSocialSummary="true" />
+
+</ContactsAccountType>
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
index 2e30be7..efda0cc 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
@@ -15,12 +15,16 @@
*/
package com.example.android.samplesync.editor;
+import com.example.android.samplesync.Constants;
import com.example.android.samplesync.R;
import com.example.android.samplesync.client.RawContact;
import com.example.android.samplesync.platform.BatchOperation;
import com.example.android.samplesync.platform.ContactManager;
+import com.example.android.samplesync.platform.ContactManager.ContactQuery;
import com.example.android.samplesync.platform.ContactManager.EditorQuery;
+import android.accounts.Account;
+import android.accounts.AccountManager;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
@@ -29,6 +33,7 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
@@ -86,8 +91,8 @@
mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
mEmailEditText = (EditText)findViewById(R.id.editor_email);
- // Figure out whether we're creating a new contact (ACTION_INSERT) or editing
- // an existing contact.
+ // Figure out whether we're creating a new contact (ACTION_INSERT), editing
+ // an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
Intent intent = getIntent();
String action = intent.getAction();
if (Intent.ACTION_INSERT.equals(action)) {
@@ -100,6 +105,24 @@
finish();
}
setAccountName(accountName);
+ } else if (ContactsContract.Intents.INVITE_CONTACT.equals(action)) {
+ // Adding to an existing contact.
+ mIsInsert = true;
+ // Use the first account found.
+ Account[] myAccounts = AccountManager.get(this).getAccountsByType(
+ Constants.ACCOUNT_TYPE);
+ if (myAccounts.length == 0) {
+ Log.e(TAG, "Account not configured");
+ finish();
+ }
+ setAccountName(myAccounts[0].name);
+
+ Uri lookupUri = intent.getData();
+ if (lookupUri == null) {
+ Log.e(TAG, "Contact lookup URI is required");
+ finish();
+ }
+ startLoadContactEntity(lookupUri);
} else {
// We're editing an existing contact. Load in the data from the contact
// so that the user can edit it.
@@ -163,7 +186,7 @@
* successfully loaded from the Contacts data provider.
*/
public void onRawContactEntityLoaded(Cursor cursor) {
- while (cursor.moveToNext()) {
+ if (cursor.moveToFirst()) {
String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
@@ -185,6 +208,23 @@
}
/**
+ * Create an AsyncTask to load the contact from the Contacts data provider
+ */
+ private void startLoadContactEntity(Uri lookupUri) {
+ new LoadContactTask().execute(lookupUri);
+ }
+
+ /**
+ * Called by the LoadContactTask when the contact information has been
+ * successfully loaded from the Contacts data provider.
+ */
+ public void onContactEntityLoaded(Cursor cursor) {
+ if (cursor.moveToFirst()) {
+ mNameEditText.setText(cursor.getString(ContactQuery.COLUMN_DISPLAY_NAME));
+ }
+ }
+
+ /**
* Save the updated contact data. We actually take two different actions
* depending on whether we are creating a new contact or editing an
* existing contact.
@@ -212,6 +252,7 @@
*/
private void setAccountName(String accountName) {
mAccountName = accountName;
+ Log.i(TAG, "account=" + mAccountName);
if (accountName != null) {
TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
if (accountNameLabel != null) {
@@ -286,12 +327,11 @@
@Override
protected void onPostExecute(Cursor cursor) {
+ if (cursor == null) return;
// After we've successfully loaded the contact, call back into
// the ContactEditorActivity so we can update the UI
try {
- if (cursor != null) {
- onRawContactEntityLoaded(cursor);
- }
+ onRawContactEntityLoaded(cursor);
} finally {
cursor.close();
}
@@ -366,4 +406,25 @@
onContactSaved(result);
}
}
+
+ /**
+ * Loads contact information by a lookup URI.
+ */
+ public class LoadContactTask extends AsyncTask<Uri, Void, Cursor> {
+
+ @Override
+ protected Cursor doInBackground(Uri... params) {
+ return getContentResolver().query(params[0], ContactQuery.PROJECTION, null, null, null);
+ }
+
+ @Override
+ protected void onPostExecute(Cursor cursor) {
+ if (cursor == null) return;
+ try {
+ onContactEntityLoaded(cursor);
+ } finally {
+ cursor.close();
+ }
+ }
+ }
}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
index 2335d38..035c976 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
@@ -32,6 +32,7 @@
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.Settings;
@@ -751,4 +752,18 @@
public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
}
+
+ /**
+ * Constants for a query to read basic contact columns
+ */
+ final public static class ContactQuery {
+ private ContactQuery() {
+ }
+
+ public static final String[] PROJECTION =
+ new String[] {Contacts._ID, Contacts.DISPLAY_NAME};
+
+ public static final int COLUMN_ID = 0;
+ public static final int COLUMN_DISPLAY_NAME = 1;
+ }
}
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index 4719268..6a05b73 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -67,6 +67,14 @@
</intent-filter>
</activity>
+ <activity android:name=".app.FragmentCustomAnimationSupport"
+ android:label="@string/fragment_custom_animation_support">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".app.FragmentHideShowSupport"
android:label="@string/fragment_hide_show_support"
android:windowSoftInputMode="stateUnchanged">
diff --git a/samples/Support4Demos/res/anim/decelerate_quint.xml b/samples/Support4Demos/res/anim/decelerate_quint.xml
new file mode 100644
index 0000000..ff2d5a9
--- /dev/null
+++ b/samples/Support4Demos/res/anim/decelerate_quint.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:factor="2.5" />
diff --git a/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml b/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml
new file mode 100644
index 0000000..6bbf6a2
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_quint">
+ <translate android:fromXDelta="33%" android:toXDelta="0%p"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml b/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml
new file mode 100644
index 0000000..0affbc7
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_quint">
+ <translate android:fromXDelta="0%" android:toXDelta="-33%p"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml b/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml
new file mode 100644
index 0000000..e2e1168
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_quint">
+ <translate android:fromXDelta="-33%" android:toXDelta="0%p"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml b/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml
new file mode 100644
index 0000000..c8e6e7c
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@anim/decelerate_quint">
+ <translate android:fromXDelta="0%" android:toXDelta="33%p"
+ android:duration="@android:integer/config_mediumAnimTime"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index 5fa5af7..4e8d9de 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -41,6 +41,8 @@
<string name="fragment_arguments_embedded">From Attributes</string>
<string name="fragment_arguments_embedded_land">Landscape Only</string>
+ <string name="fragment_custom_animation_support">Fragment/Custom Animation</string>
+
<string name="fragment_hide_show_support">Fragment/Hide and Show</string>
<string name="fragment_context_menu_support">Fragment/Context Menu</string>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java
new file mode 100644
index 0000000..5893521
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 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.example.android.supportv4.app;
+
+import com.example.android.supportv4.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentCustomAnimationSupport extends FragmentActivity {
+ int mStackLevel = 1;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.fragment_stack);
+
+ // Watch for button clicks.
+ Button button = (Button)findViewById(R.id.new_fragment);
+ button.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ addFragmentToStack();
+ }
+ });
+
+ if (savedInstanceState == null) {
+ // Do first time initialization -- add initial fragment.
+ Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.add(R.id.simple_fragment, newFragment).commit();
+ } else {
+ mStackLevel = savedInstanceState.getInt("level");
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt("level", mStackLevel);
+ }
+
+//BEGIN_INCLUDE(add_stack)
+ void addFragmentToStack() {
+ mStackLevel++;
+
+ // Instantiate a new fragment.
+ Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+ // Add the fragment to the activity, pushing this transaction
+ // on to the back stack.
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.setCustomAnimations(R.anim.fragment_slide_left_enter,
+ R.anim.fragment_slide_left_exit,
+ R.anim.fragment_slide_right_enter,
+ R.anim.fragment_slide_right_exit);
+ ft.replace(R.id.simple_fragment, newFragment);
+ ft.addToBackStack(null);
+ ft.commit();
+ }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+ public static class CountingFragment extends Fragment {
+ int mNum;
+
+ /**
+ * Create a new instance of CountingFragment, providing "num"
+ * as an argument.
+ */
+ static CountingFragment newInstance(int num) {
+ CountingFragment f = new CountingFragment();
+
+ // Supply num input as an argument.
+ Bundle args = new Bundle();
+ args.putInt("num", num);
+ f.setArguments(args);
+
+ return f;
+ }
+
+ /**
+ * When creating, retrieve this instance's number from its arguments.
+ */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+ }
+
+ /**
+ * The Fragment's UI is just a simple text view showing its
+ * instance number.
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.hello_world, container, false);
+ View tv = v.findViewById(R.id.text);
+ ((TextView)tv).setText("Fragment #" + mNum);
+ tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+ return v;
+ }
+ }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html b/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
index fa9af5a..d203ffb 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
@@ -23,6 +23,10 @@
<dd>Demonstrates how to display and respond to a context menu that is
display from a fragment's view hierarchy.</dd>
+ <dt><a href="FragmentCustomAnimationSupport.html">Fragment Custom Animation</a></dt>
+ <dd>Demonstrates the use of a custom animation for pushing and popping fragments
+ on the back stack.</dd>
+
<dt><a href="FragmentDialogSupport.html">Fragment Dialog</a></dt>
<dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>