Merge commit 'bf91ce9f' into klp-ub-dev
Forgot to add DO NOT MERGE to the original CL
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ba5f04a..da90a41 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -15,4 +15,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/build.gradle b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/build.gradle
new file mode 100644
index 0000000..21cf70b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/build.gradle
@@ -0,0 +1,60 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 7
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile "com.android.support:appcompat-v7:18.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..332c055
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.basic"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- ActionBarCompat provides an Action Bar from API v7 onwards -->
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat"
+ android:allowBackup="true">
+
+ <activity android:name=".MainActivity">
+ <!-- Launcher Intent filter -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/java/com/example/android/actionbarcompat/basic/MainActivity.java b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/java/com/example/android/actionbarcompat/basic/MainActivity.java
new file mode 100644
index 0000000..8d3506f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/java/com/example/android/actionbarcompat/basic/MainActivity.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.basic;
+
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * This sample shows you how to use ActionBarCompat to create a basic Activity which displays
+ * action items. It covers inflating items from a menu resource, as well as adding an item in code.
+ *
+ * This Activity extends from {@link ActionBarActivity}, which provides all of the function
+ * necessary to display a compatible Action Bar on devices running Android v2.1+.
+ */
+public class MainActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+ }
+
+ // BEGIN_INCLUDE(create_menu)
+ /**
+ * Use this method to instantiate your menu, and add your items to it. You
+ * should return true if you have added items to it and want the menu to be displayed.
+ */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate our menu from the resources by using the menu inflater.
+ getMenuInflater().inflate(R.menu.main, menu);
+
+ // It is also possible add items here. Use a generated id from
+ // resources (ids.xml) to ensure that all menu ids are distinct.
+ MenuItem locationItem = menu.add(0, R.id.menu_location, 0, R.string.menu_location);
+ locationItem.setIcon(R.drawable.ic_action_location);
+
+ // Need to use MenuItemCompat methods to call any action item related methods
+ MenuItemCompat.setShowAsAction(locationItem, MenuItem.SHOW_AS_ACTION_IF_ROOM);
+
+ return true;
+ }
+ // END_INCLUDE(create_menu)
+
+ // BEGIN_INCLUDE(menu_item_selected)
+ /**
+ * This method is called when one of the menu items to selected. These items
+ * can be on the Action Bar, the overflow menu, or the standard options menu. You
+ * should return true if you handle the selection.
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_refresh:
+ // Here we might start a background refresh task
+ return true;
+
+ case R.id.menu_location:
+ // Here we might call LocationManager.requestLocationUpdates()
+ return true;
+
+ case R.id.menu_settings:
+ // Here we would open up our settings activity
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+ // END_INCLUDE(menu_item_selected)
+}
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_location.png
new file mode 100644
index 0000000..a42b3ea
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_refresh.png
new file mode 100644
index 0000000..c9d295d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_settings.png
new file mode 100644
index 0000000..d3f981d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..5bb19fb
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_location.png
new file mode 100644
index 0000000..eaf9774
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_refresh.png
new file mode 100644
index 0000000..eef97e9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_settings.png
new file mode 100644
index 0000000..fc2bf8c
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..5737b36
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_location.png
new file mode 100644
index 0000000..5f11cce
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
new file mode 100644
index 0000000..1027c9a
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644
index 0000000..1b9acf2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..31df043
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..5087435
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..ff589e1
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp"
+ android:text="@string/intro_message"
+ android:gravity="center" />
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/menu/main.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..a4dc5d1
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/menu/main.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<!--
+ As we're using ActionBarCompat, any action item attributes come from ActionBarCompat's XML
+ namespace instead of the android namespace. Here we've added a new support namespace added to
+ the menu element allowing us to use the 'showAsAction' attribute in a backwards compatible way.
+ Any other action item attributes used should be referenced from this namespace too
+ (actionProviderClass, actionViewClass, actionLayout).
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:support="http://schemas.android.com/apk/res-auto" >
+
+ <!--
+ Here we create an item, setting support:showAsAction to display the item as an action if
+ there's room on the compatible Action Bar.
+ -->
+ <item
+ android:id="@+id/menu_refresh"
+ android:icon="@drawable/ic_action_refresh"
+ android:title="@string/menu_refresh"
+ support:showAsAction="ifRoom"/>
+
+ <!-- Location item is added in onCreateOptionsMenu() -->
+
+ <!--
+ Here we set the settings item to always be in the overflow menu, by setting
+ support:showAsAction to never, so it is never displayed as an action item on the compatible
+ Action Bar.
+ -->
+ <item
+ android:id="@+id/menu_settings"
+ android:icon="@drawable/ic_action_settings"
+ android:title="@string/menu_settings"
+ support:showAsAction="never"/>
+
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..8edd1b2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ActionBarCompat-Basic</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample shows you how to use ActionBarCompat to create a basic Activity which
+ displays action items. It covers inflating items from a menu resource, as well as adding
+ an item in code. Items that are not shown as action items on the Action Bar are
+ displayed in the action bar overflow.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/ids.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/ids.xml
new file mode 100644
index 0000000..0269815
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/ids.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+
+ <!--
+ Generate an id which can be used when the location menu item is added in MainActivity
+ -->
+ <item name="menu_location" type="id"/>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/strings.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..7867410
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="menu_refresh">Refresh</string>
+ <string name="menu_location">Location</string>
+ <string name="menu_settings">Settings</string>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..a2f7cfc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.basic.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.actionbarcompat.basic"
+ android:label="Tests for com.example.android.actionbarcompat.basic" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/src/com/example/android/actionbarcompat/basic/tests/SampleTests.java b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/src/com/example/android/actionbarcompat/basic/tests/SampleTests.java
new file mode 100644
index 0000000..8c1b2be
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/ActionBarCompat-BasicSample/tests/src/com/example/android/actionbarcompat/basic/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.actionbarcompat.basic.tests;
+
+import com.example.android.actionbarcompat.basic.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for Basic sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/README.txt b/prebuilts/gradle/ActionBarCompat-Basic/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/build.gradle b/prebuilts/gradle/ActionBarCompat-Basic/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/gradlew b/prebuilts/gradle/ActionBarCompat-Basic/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/gradlew.bat b/prebuilts/gradle/ActionBarCompat-Basic/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ActionBarCompat-Basic/settings.gradle b/prebuilts/gradle/ActionBarCompat-Basic/settings.gradle
new file mode 100644
index 0000000..21d2b41
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Basic/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ActionBarCompat-BasicSample'
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/build.gradle b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/build.gradle
new file mode 100644
index 0000000..35302c0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/build.gradle
@@ -0,0 +1,60 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 7
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile "com.android.support:appcompat-v7:+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..114053e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.listpopupmenu"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- ActionBarCompat provides an implementation of Popup Menu from API v7 onwards -->
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat"
+ android:allowBackup="true">
+
+ <activity android:name=".MainActivity">
+ <!-- Launcher Intent filter -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/Cheeses.java b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/Cheeses.java
new file mode 100644
index 0000000..5ef1161
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/Cheeses.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2013 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.actionbarcompat.listpopupmenu;
+
+/**
+ * Dummy data.
+ */
+public class Cheeses {
+ public static final String[] CHEESES = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+ "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+ "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+ "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+ "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+ "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+ "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+ "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+ "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+ "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+ "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+ "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+ "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+ "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+ "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+ "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+ "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+ "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+ "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+ "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+ "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+ "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+ "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+ "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+ "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+ "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+ "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+ "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+ "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+ "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+ "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+ "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+ "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+ "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+ "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+ "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+ "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+ "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+ "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+ "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+ "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+ "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+ "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+ "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+ "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+ "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+ "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+ "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+ "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+ "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+ "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+ "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+ "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+ "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+ "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+ "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+ "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+ "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+ "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+ "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+ "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+ "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+ "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+ "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+ "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+ "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+ "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+ "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+ "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+ "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+ "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+ "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+ "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+ "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+ "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+ "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+ "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+ "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+ "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+ "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+ "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+ "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+ "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+ "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+ "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+ "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+ "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+ "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+ "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+ "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+ "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+ "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+ "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+ "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+ "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+ "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+ "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+ "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+ "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+ "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+ "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+ "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+ "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+ "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+ "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+ "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+ "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+ "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+ "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+ "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+ "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+ "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+ "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+ "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+ "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+ "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+ "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+ "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+ "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+ "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+ "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+ "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+ "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+ "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+ "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+ "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+ "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+ "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+ "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+ "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+ };
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/MainActivity.java b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/MainActivity.java
new file mode 100644
index 0000000..13a77f3
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/MainActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.listpopupmenu;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBarActivity;
+
+/**
+ * This sample shows you how to use {@link android.support.v7.widget.PopupMenu PopupMenu} from
+ * ActionBarCompat to create a list, with each item having a dropdown menu.
+ * <p>
+ * The interesting part of this sample is in {@link PopupListFragment}.
+ *
+ * This Activity extends from {@link ActionBarActivity}, which provides all of the function
+ * necessary to display a compatible Action Bar on devices running Android v2.1+.
+ */
+public class MainActivity extends ActionBarActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set content view (which contains a PopupListFragment)
+ setContentView(R.layout.sample_main);
+ }
+
+}
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/PopupListFragment.java b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/PopupListFragment.java
new file mode 100644
index 0000000..754bf22
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/java/com/example/android/actionbarcompat/listpopupmenu/PopupListFragment.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.listpopupmenu;
+
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v7.widget.PopupMenu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+/**
+ * This ListFragment displays a list of cheeses, with a clickable view on each item whichs displays
+ * a {@link android.support.v7.widget.PopupMenu PopupMenu} when clicked, allowing the user to
+ * remove the item from the list.
+ */
+public class PopupListFragment extends ListFragment implements View.OnClickListener {
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ // We want to allow modifications to the list so copy the dummy data array into an ArrayList
+ ArrayList<String> items = new ArrayList<String>();
+ for (int i = 0, z = Cheeses.CHEESES.length ; i < z ; i++) {
+ items.add(Cheeses.CHEESES[i]);
+ }
+
+ // Set the ListAdapter
+ setListAdapter(new PopupAdapter(items));
+ }
+
+ @Override
+ public void onListItemClick(ListView listView, View v, int position, long id) {
+ String item = (String) listView.getItemAtPosition(position);
+
+ // Show a toast if the user clicks on an item
+ Toast.makeText(getActivity(), "Item Clicked: " + item, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onClick(final View view) {
+ // We need to post a Runnable to show the popup to make sure that the PopupMenu is
+ // correctly positioned. The reason being that the view may change position before the
+ // PopupMenu is shown.
+ view.post(new Runnable() {
+ @Override
+ public void run() {
+ showPopupMenu(view);
+ }
+ });
+ }
+
+ // BEGIN_INCLUDE(show_popup)
+ private void showPopupMenu(View view) {
+ final PopupAdapter adapter = (PopupAdapter) getListAdapter();
+
+ // Retrieve the clicked item from view's tag
+ final String item = (String) view.getTag();
+
+ // Create a PopupMenu, giving it the clicked view for an anchor
+ PopupMenu popup = new PopupMenu(getActivity(), view);
+
+ // Inflate our menu resource into the PopupMenu's Menu
+ popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());
+
+ // Set a listener so we are notified if a menu item is clicked
+ popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem menuItem) {
+ switch (menuItem.getItemId()) {
+ case R.id.menu_remove:
+ // Remove the item from the adapter
+ adapter.remove(item);
+ return true;
+ }
+ return false;
+ }
+ });
+
+ // Finally show the PopupMenu
+ popup.show();
+ }
+ // END_INCLUDE(show_popup)
+
+ /**
+ * A simple array adapter that creates a list of cheeses.
+ */
+ class PopupAdapter extends ArrayAdapter<String> {
+
+ PopupAdapter(ArrayList<String> items) {
+ super(getActivity(), R.layout.list_item, android.R.id.text1, items);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ // Let ArrayAdapter inflate the layout and set the text
+ View view = super.getView(position, convertView, container);
+
+ // BEGIN_INCLUDE(button_popup)
+ // Retrieve the popup button from the inflated view
+ View popupButton = view.findViewById(R.id.button_popup);
+
+ // Set the item as the button's tag so it can be retrieved later
+ popupButton.setTag(getItem(position));
+
+ // Set the fragment instance as the OnClickListener
+ popupButton.setOnClickListener(PopupListFragment.this);
+ // END_INCLUDE(button_popup)
+
+ // Finally return the view to be displayed
+ return view;
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a7365b9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_overflow.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_overflow.png
new file mode 100644
index 0000000..2abc458
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/ic_overflow.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..3fd5593
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_overflow.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_overflow.png
new file mode 100644
index 0000000..ba704b6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-mdpi/ic_overflow.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..204f861
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_overflow.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_overflow.png
new file mode 100644
index 0000000..a92fb1d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xhdpi/ic_overflow.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ada8266
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/list_item.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..3eabda0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/list_item.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/listPreferredItemHeight">
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_height="match_parent"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:gravity="center_vertical"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <ImageView
+ android:id="@+id/button_popup"
+ android:layout_height="match_parent"
+ android:layout_width="56dip"
+ android:background="?attr/selectableItemBackground"
+ android:src="@drawable/ic_overflow"
+ android:contentDescription="@string/content_open_popup"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..bfc7ad0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:name="com.example.android.actionbarcompat.listpopupmenu.PopupListFragment" />
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/menu/popup.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/menu/popup.xml
new file mode 100644
index 0000000..0329e9e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/menu/popup.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/menu_remove"
+ android:title="@string/menu_remove" />
+
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..130e2da
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ActionBarCompat-ListPopupMenu</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample shows you how to use {@link android.support.v7.widget.PopupMenu PopupMenu}
+ from ActionBarCompat to create a list, with each item having a dropdown menu.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/strings.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e5784a9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+
+ <string name="menu_remove">Remove</string>
+ <string name="content_open_popup">Open Popup Menu</string>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..d23ab10
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.listpopupmenu.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.actionbarcompat.listpopupmenu"
+ android:label="Tests for com.example.android.actionbarcompat.listpopupmenu" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/src/com/example/android/actionbarcompat/listpopupmenu/tests/SampleTests.java b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/src/com/example/android/actionbarcompat/listpopupmenu/tests/SampleTests.java
new file mode 100644
index 0000000..c91ae2e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/ActionBarCompat-ListPopupMenuSample/tests/src/com/example/android/actionbarcompat/listpopupmenu/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.actionbarcompat.listpopupmenu.tests;
+
+import com.example.android.actionbarcompat.listpopupmenu.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for ListPopupMenu sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private ListPopupMenuFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (ListPopupMenuFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.txt b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/build.gradle b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew.bat b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ActionBarCompat-ListPopupMenu/settings.gradle b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/settings.gradle
new file mode 100644
index 0000000..2b794b6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ListPopupMenu/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ActionBarCompat-ListPopupMenuSample'
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/build.gradle b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/build.gradle
new file mode 100644
index 0000000..21cf70b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/build.gradle
@@ -0,0 +1,60 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 7
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile "com.android.support:appcompat-v7:18.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..be1ed49
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/AndroidManifest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.shareactionprovider"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!--
+ ActionBarCompat provides an Action Bar from API v7 onwards
+ -->
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.AppCompat"
+ android:allowBackup="true">
+
+ <activity
+ android:name=".MainActivity">
+ <!-- Launcher Intent filter -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- ContentProvider which serves files from this application's asset folder -->
+ <provider
+ android:name=".content.AssetProvider"
+ android:authorities="com.example.android.actionbarcompat.shareactionprovider"
+ android:grantUriPermissions="true"
+ android:exported="true" />
+
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_1.jpg b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_1.jpg
new file mode 100644
index 0000000..cd365c7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_1.jpg
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_2.jpg b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_2.jpg
new file mode 100644
index 0000000..f088c11
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_2.jpg
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_3.jpg b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_3.jpg
new file mode 100644
index 0000000..d4cff6a
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/assets/photo_3.jpg
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/MainActivity.java b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/MainActivity.java
new file mode 100644
index 0000000..b8cc900
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/MainActivity.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.shareactionprovider;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.ShareActionProvider;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.example.android.actionbarcompat.shareactionprovider.content.ContentItem;
+
+import java.util.ArrayList;
+
+/**
+ * This sample shows you how a provide a {@link ShareActionProvider} with ActionBarCompat,
+ * backwards compatible to API v7.
+ * <p>
+ * The sample contains a {@link ViewPager} which displays content of differing types: image and
+ * text. When a new item is selected in the ViewPager, the ShareActionProvider is updated with
+ * a share intent specific to that content.
+ * <p>
+ * This Activity extends from {@link ActionBarActivity}, which provides all of the function
+ * necessary to display a compatible Action Bar on devices running Android v2.1+.
+ */
+public class MainActivity extends ActionBarActivity {
+
+ // The items to be displayed in the ViewPager
+ private final ArrayList<ContentItem> mItems = getSampleContent();
+
+ // Keep reference to the ShareActionProvider from the menu
+ private ShareActionProvider mShareActionProvider;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set content view (which contains a CheeseListFragment)
+ setContentView(R.layout.sample_main);
+
+ // Retrieve the ViewPager from the content view
+ ViewPager vp = (ViewPager) findViewById(R.id.viewpager);
+
+ // Set an OnPageChangeListener so we are notified when a new item is selected
+ vp.setOnPageChangeListener(mOnPageChangeListener);
+
+ // Finally set the adapter so the ViewPager can display items
+ vp.setAdapter(mPagerAdapter);
+ }
+
+ // BEGIN_INCLUDE(get_sap)
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu resource
+ getMenuInflater().inflate(R.menu.main_menu, menu);
+
+ // Retrieve the share menu item
+ MenuItem shareItem = menu.findItem(R.id.menu_share);
+
+ // Now get the ShareActionProvider from the item
+ mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
+
+ return super.onCreateOptionsMenu(menu);
+ }
+ // END_INCLUDE(get_sap)
+
+ /**
+ * A PagerAdapter which instantiates views based on the ContentItem's content type.
+ */
+ private final PagerAdapter mPagerAdapter = new PagerAdapter() {
+ LayoutInflater mInflater;
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object o) {
+ return view == o;
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ // Just remove the view from the ViewPager
+ container.removeView((View) object);
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ // Ensure that the LayoutInflater is instantiated
+ if (mInflater == null) {
+ mInflater = LayoutInflater.from(MainActivity.this);
+ }
+
+ // Get the item for the requested position
+ final ContentItem item = mItems.get(position);
+
+ // The view we need to inflate changes based on the type of content
+ switch (item.contentType) {
+ case ContentItem.CONTENT_TYPE_TEXT: {
+ // Inflate item layout for text
+ TextView tv = (TextView) mInflater
+ .inflate(R.layout.item_text, container, false);
+
+ // Set text content using it's resource id
+ tv.setText(item.contentResourceId);
+
+ // Add the view to the ViewPager
+ container.addView(tv);
+ return tv;
+ }
+ case ContentItem.CONTENT_TYPE_IMAGE: {
+ // Inflate item layout for images
+ ImageView iv = (ImageView) mInflater
+ .inflate(R.layout.item_image, container, false);
+
+ // Load the image from it's content URI
+ iv.setImageURI(item.getContentUri());
+
+ // Add the view to the ViewPager
+ container.addView(iv);
+ return iv;
+ }
+ }
+
+ return null;
+ }
+ };
+
+ /**
+ * A OnPageChangeListener used to update the ShareActionProvider's share intent when a new item
+ * is selected in the ViewPager.
+ */
+ private final ViewPager.OnPageChangeListener mOnPageChangeListener
+ = new ViewPager.OnPageChangeListener() {
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ // NO-OP
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ // BEGIN_INCLUDE(update_sap)
+ if (mShareActionProvider != null) {
+ // Get the currently selected item, and retrieve it's share intent
+ ContentItem item = mItems.get(position);
+ Intent shareIntent = item.getShareIntent(MainActivity.this);
+
+ // Now update the ShareActionProvider with the new share intent
+ mShareActionProvider.setShareIntent(shareIntent);
+ }
+ // END_INCLUDE(update_sap)
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ // NO-OP
+ }
+ };
+
+ /**
+ * @return An ArrayList of ContentItem's to be displayed in this sample
+ */
+ static ArrayList<ContentItem> getSampleContent() {
+ ArrayList<ContentItem> items = new ArrayList<ContentItem>();
+
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_IMAGE, "photo_1.jpg"));
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_TEXT, R.string.quote_1));
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_TEXT, R.string.quote_2));
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_IMAGE, "photo_2.jpg"));
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_TEXT, R.string.quote_3));
+ items.add(new ContentItem(ContentItem.CONTENT_TYPE_IMAGE, "photo_3.jpg"));
+
+ return items;
+ }
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/AssetProvider.java b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/AssetProvider.java
new file mode 100644
index 0000000..b60f7d7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/AssetProvider.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.shareactionprovider.content;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * A simple ContentProvider which can serve files from this application's assets. The majority of
+ * functionality is in {@link #openAssetFile(android.net.Uri, String)}.
+ */
+public class AssetProvider extends ContentProvider {
+
+ public static String CONTENT_URI = "com.example.android.actionbarcompat.shareactionprovider";
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ // Do not support delete requests.
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ // Do not support returning the data type
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ // Do not support insert requests.
+ return null;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ // Do not support query requests.
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ // Do not support update requests.
+ return 0;
+ }
+
+ @Override
+ public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
+ // The asset file name should be the last path segment
+ final String assetName = uri.getLastPathSegment();
+
+ // If the given asset name is empty, throw an exception
+ if (TextUtils.isEmpty(assetName)) {
+ throw new FileNotFoundException();
+ }
+
+ try {
+ // Try and return a file descriptor for the given asset name
+ AssetManager am = getContext().getAssets();
+ return am.openFd(assetName);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return super.openAssetFile(uri, mode);
+ }
+ }
+}
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/ContentItem.java b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/ContentItem.java
new file mode 100644
index 0000000..756a9e6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/java/com/example/android/actionbarcompat/shareactionprovider/content/ContentItem.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.shareactionprovider.content;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.text.TextUtils;
+
+/**
+ * This class encapsulates a content item. Referencing the content's type, and the differing way
+ * to reference the content (asset URI or resource id).
+ */
+public class ContentItem {
+ // Used to signify an image content type
+ public static final int CONTENT_TYPE_IMAGE = 0;
+ // Used to signify a text/string content type
+ public static final int CONTENT_TYPE_TEXT = 1;
+
+ public final int contentType;
+ public final int contentResourceId;
+ public final String contentAssetFilePath;
+
+ /**
+ * Creates a ContentItem with the specified type, referencing a resource id.
+ *
+ * @param type - One of {@link #CONTENT_TYPE_IMAGE} or {@link #CONTENT_TYPE_TEXT}
+ * @param resourceId - Resource ID to use for this item's content
+ */
+ public ContentItem(int type, int resourceId) {
+ contentType = type;
+ contentResourceId = resourceId;
+ contentAssetFilePath = null;
+ }
+
+ /**
+ * Creates a ContentItem with the specified type, referencing an asset file path.
+ *
+ * @param type - One of {@link #CONTENT_TYPE_IMAGE} or {@link #CONTENT_TYPE_TEXT}
+ * @param assetFilePath - File path from the application's asset for this item's content
+ */
+ public ContentItem(int type, String assetFilePath) {
+ contentType = type;
+ contentAssetFilePath = assetFilePath;
+ contentResourceId = 0;
+ }
+
+ /**
+ * @return Uri to the content
+ */
+ public Uri getContentUri() {
+ if (!TextUtils.isEmpty(contentAssetFilePath)) {
+ // If this content has an asset, then return a AssetProvider Uri
+ return Uri.parse("content://" + AssetProvider.CONTENT_URI + "/" + contentAssetFilePath);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns an {@link android.content.Intent} which can be used to share this item's content with other
+ * applications.
+ *
+ * @param context - Context to be used for fetching resources if needed
+ * @return Intent to be given to a ShareActionProvider.
+ */
+ public Intent getShareIntent(Context context) {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+
+ switch (contentType) {
+ case CONTENT_TYPE_IMAGE:
+ intent.setType("image/jpg");
+ // Bundle the asset content uri as the EXTRA_STREAM uri
+ intent.putExtra(Intent.EXTRA_STREAM, getContentUri());
+ break;
+
+ case CONTENT_TYPE_TEXT:
+ intent.setType("text/plain");
+ // Get the string resource and bundle it as an intent extra
+ intent.putExtra(Intent.EXTRA_TEXT, context.getString(contentResourceId));
+ break;
+ }
+
+ return intent;
+ }
+
+}
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..48db73f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..674b1ee
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e76105d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..67605d8
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_image.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_image.xml
new file mode 100644
index 0000000..f7940e7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_image.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="fitCenter" />
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_text.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_text.xml
new file mode 100644
index 0000000..00c6a38
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/item_text.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="16dp"
+ android:textAppearance="?android:textAppearanceLarge"
+ android:lineSpacingMultiplier="1.1"
+ android:gravity="center"/>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..902e8ab
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/viewpager"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_message"
+ android:padding="16dp"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:lineSpacingMultiplier="1.1"
+ android:background="#fb3"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/menu/main_menu.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/menu/main_menu.xml
new file mode 100644
index 0000000..acd2134
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/menu/main_menu.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<!--
+ As we're using ActionBarCompat, any action item attributes come from ActionBarCompat's XML
+ namespace instead of the android namespace. Here we've added a new support namespace added to
+ the menu element allowing us to use the 'showAsAction' attribute in a backwards compatible way.
+ Any other action item attributes used should be referenced from this namespace too
+ (actionProviderClass, actionViewClass, actionLayout).
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:support="http://schemas.android.com/apk/res-auto">
+
+ <!--
+ To use ShareActionProvider provided by ActionBarCompat, we reference the class by set the
+ support:actionProviderClass attribute with the full class name of ShareActionProvider.
+ -->
+ <item
+ android:id="@+id/menu_share"
+ android:title="@string/menu_share"
+ support:actionProviderClass="android.support.v7.widget.ShareActionProvider"
+ support:showAsAction="always" />
+
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..904f4f1
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ActionBarCompat-ShareActionProvider</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample shows you how a provide a context-sensitive ShareActionProvider with
+ ActionBarCompat, backwards compatible to API v7.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/strings.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..298596f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="menu_share">Share</string>
+ <string name="quote_1">Expectation is the root of all heartache - William Shakespeare</string>
+ <string name="quote_2">The true sign of intelligence is not knowledge but imagination - Albert
+ Einstein</string>
+ <string name="quote_3">As for me, all I know is that I know nothing - Socrates</string>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..c52949c
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.shareactionprovider.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.actionbarcompat.shareactionprovider"
+ android:label="Tests for com.example.android.actionbarcompat.shareactionprovider" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/src/com/example/android/actionbarcompat/shareactionprovider/tests/SampleTests.java b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/src/com/example/android/actionbarcompat/shareactionprovider/tests/SampleTests.java
new file mode 100644
index 0000000..e655bcf
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/ActionBarCompat-ShareActionProviderSample/tests/src/com/example/android/actionbarcompat/shareactionprovider/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.actionbarcompat.shareactionprovider.tests;
+
+import com.example.android.actionbarcompat.shareactionprovider.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for ShareActionProvider sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private ShareActionProviderFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (ShareActionProviderFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/README.txt b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/build.gradle b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew.bat b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ActionBarCompat-ShareActionProvider/settings.gradle b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/settings.gradle
new file mode 100644
index 0000000..343656d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-ShareActionProvider/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ActionBarCompat-ShareActionProviderSample'
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/build.gradle b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/build.gradle
new file mode 100644
index 0000000..21cf70b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/build.gradle
@@ -0,0 +1,60 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 7
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile "com.android.support:appcompat-v7:18.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..06394c7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.styled"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="17" />
+
+ <!--
+ Theme is set on the application so that our custom theme is used by
+ default by all Activities
+ -->
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.Styled" >
+
+ <activity android:name=".MainActivity">
+
+ <!-- Launcher Intent filter -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <!--
+ In this example set the Activity to have a split action bar when the device's
+ display is narrow. In ActionBarCompat this is done by setting the
+ 'android.support.UI_OPTIONS' metadata field to 'splitActionBarWhenNarrow'.
+ -->
+ <meta-data
+ android:name="android.support.UI_OPTIONS"
+ android:value="splitActionBarWhenNarrow" />
+
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/java/com/example/android/actionbarcompat/styled/MainActivity.java b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/java/com/example/android/actionbarcompat/styled/MainActivity.java
new file mode 100644
index 0000000..19fe3a1
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/java/com/example/android/actionbarcompat/styled/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 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.actionbarcompat.styled;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+
+/**
+ * This sample shows you how to use ActionBarCompat with a customized theme. It utilizes a split
+ * action bar when running on a device with a narrow display, and show three tabs.
+ *
+ * This Activity extends from {@link ActionBarActivity}, which provides all of the function
+ * necessary to display a compatible Action Bar on devices running Android v2.1+.
+ *
+ * The interesting bits of this sample start in the theme files
+ * ('res/values/styles.xml' and 'res/values-v14</styles.xml').
+ *
+ * Many of the drawables used in this sample were generated with the
+ * 'Android Action Bar Style Generator': http://jgilfelt.github.io/android-actionbarstylegenerator
+ */
+public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ // Set the Action Bar to use tabs for navigation
+ ActionBar ab = getSupportActionBar();
+ ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+
+ // Add three tabs to the Action Bar for display
+ ab.addTab(ab.newTab().setText("Tab 1").setTabListener(this));
+ ab.addTab(ab.newTab().setText("Tab 2").setTabListener(this));
+ ab.addTab(ab.newTab().setText("Tab 3").setTabListener(this));
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate menu from menu resource (res/menu/main)
+ getMenuInflater().inflate(R.menu.main, menu);
+
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ // Implemented from ActionBar.TabListener
+ @Override
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ // This is called when a tab is selected.
+ }
+
+ // Implemented from ActionBar.TabListener
+ @Override
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ // This is called when a previously selected tab is unselected.
+ }
+
+ // Implemented from ActionBar.TabListener
+ @Override
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ // This is called when a previously selected tab is selected again.
+ }
+}
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_bottom_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_bottom_solid_styled.9.png
new file mode 100644
index 0000000..f1d56b0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_bottom_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_solid_styled.9.png
new file mode 100644
index 0000000..b9790a9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_stacked_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_stacked_solid_styled.9.png
new file mode 100644
index 0000000..caa80ca
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ab_stacked_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_location.png
new file mode 100644
index 0000000..9d75c31
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_refresh.png
new file mode 100644
index 0000000..0216514
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_settings.png
new file mode 100644
index 0000000..8e30d96
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..ba841fa
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/list_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/list_focused_styled.9.png
new file mode 100644
index 0000000..1189239
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/list_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/menu_dropdown_panel_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/menu_dropdown_panel_styled.9.png
new file mode 100644
index 0000000..a114859
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/menu_dropdown_panel_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_bg_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_bg_styled.9.png
new file mode 100644
index 0000000..3b183e0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_bg_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_primary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_primary_styled.9.png
new file mode 100644
index 0000000..d9879bd
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_primary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_secondary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_secondary_styled.9.png
new file mode 100644
index 0000000..7a6ee50
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/progress_secondary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_default_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_default_styled.9.png
new file mode 100644
index 0000000..e518eb7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_default_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_disabled_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_disabled_styled.9.png
new file mode 100644
index 0000000..b6febf9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_disabled_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_focused_styled.9.png
new file mode 100644
index 0000000..c631c2f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_pressed_styled.9.png
new file mode 100644
index 0000000..8e71d1c
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/spinner_ab_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_focused_styled.9.png
new file mode 100644
index 0000000..f4d6f2f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_pressed_styled.9.png
new file mode 100644
index 0000000..2aa7838
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_styled.9.png
new file mode 100644
index 0000000..e2b390a
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_selected_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_focused_styled.9.png
new file mode 100644
index 0000000..5b8b928
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_pressed_styled.9.png
new file mode 100644
index 0000000..18d2053
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tab_unselected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_bottom_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_bottom_solid_styled.9.png
new file mode 100644
index 0000000..79da2b0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_bottom_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_solid_styled.9.png
new file mode 100644
index 0000000..617c08b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_stacked_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_stacked_solid_styled.9.png
new file mode 100644
index 0000000..407382a
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ab_stacked_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_location.png
new file mode 100644
index 0000000..b637f52
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_refresh.png
new file mode 100644
index 0000000..206314b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_settings.png
new file mode 100644
index 0000000..0e65c68
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..2901fa6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/list_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/list_focused_styled.9.png
new file mode 100644
index 0000000..30095e6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/list_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/menu_dropdown_panel_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/menu_dropdown_panel_styled.9.png
new file mode 100644
index 0000000..ea341b5
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/menu_dropdown_panel_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_bg_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_bg_styled.9.png
new file mode 100644
index 0000000..71753a4
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_bg_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_primary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_primary_styled.9.png
new file mode 100644
index 0000000..375aff2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_primary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_secondary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_secondary_styled.9.png
new file mode 100644
index 0000000..d1dbb3b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/progress_secondary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_default_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_default_styled.9.png
new file mode 100644
index 0000000..5e1dd47
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_default_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_disabled_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_disabled_styled.9.png
new file mode 100644
index 0000000..38025ad
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_disabled_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_focused_styled.9.png
new file mode 100644
index 0000000..37b4576
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_pressed_styled.9.png
new file mode 100644
index 0000000..8b99463
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/spinner_ab_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_focused_styled.9.png
new file mode 100644
index 0000000..83daafb
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_pressed_styled.9.png
new file mode 100644
index 0000000..d50ffaf
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_styled.9.png
new file mode 100644
index 0000000..6fdd7f4
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_selected_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_focused_styled.9.png
new file mode 100644
index 0000000..dc77e6d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_pressed_styled.9.png
new file mode 100644
index 0000000..637d22d
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-mdpi/tab_unselected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_bottom_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_bottom_solid_styled.9.png
new file mode 100644
index 0000000..64f17a8
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_bottom_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_solid_styled.9.png
new file mode 100644
index 0000000..c557360
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_stacked_solid_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_stacked_solid_styled.9.png
new file mode 100644
index 0000000..0ef2ec0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ab_stacked_solid_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_location.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_location.png
new file mode 100644
index 0000000..e9bf9f3
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_location.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_refresh.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
new file mode 100644
index 0000000..ccd4b07
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_settings.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644
index 0000000..d0a733e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_action_settings.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..866f146
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/list_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/list_focused_styled.9.png
new file mode 100644
index 0000000..c02fe13
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/list_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/menu_dropdown_panel_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/menu_dropdown_panel_styled.9.png
new file mode 100644
index 0000000..3d9f614
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/menu_dropdown_panel_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_bg_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_bg_styled.9.png
new file mode 100644
index 0000000..5ffc2ac
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_bg_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_primary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_primary_styled.9.png
new file mode 100644
index 0000000..8f66361
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_primary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_secondary_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_secondary_styled.9.png
new file mode 100644
index 0000000..f28f10b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/progress_secondary_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_default_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_default_styled.9.png
new file mode 100644
index 0000000..f738a44
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_default_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_disabled_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_disabled_styled.9.png
new file mode 100644
index 0000000..79d24c9
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_disabled_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_focused_styled.9.png
new file mode 100644
index 0000000..8be8d71
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_pressed_styled.9.png
new file mode 100644
index 0000000..774602c
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/spinner_ab_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_focused_styled.9.png
new file mode 100644
index 0000000..c174424
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_pressed_styled.9.png
new file mode 100644
index 0000000..62cbd04
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_styled.9.png
new file mode 100644
index 0000000..5009ce0
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_selected_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_focused_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_focused_styled.9.png
new file mode 100644
index 0000000..2c2a567
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_focused_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_pressed_styled.9.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_pressed_styled.9.png
new file mode 100644
index 0000000..81eba4c
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xhdpi/tab_unselected_pressed_styled.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..cb301f2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/pressed_background.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/pressed_background.xml
new file mode 100644
index 0000000..9de1ff7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/pressed_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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 drawable is used in our custom selected item background drawable: selectable_background.xml.
+ It is required as selector items need to be drawables, and not a raw color value as we are using.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+
+ <solid android:color="@color/pressed_styled"/>
+
+</shape>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/progress_horizontal.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/progress_horizontal.xml
new file mode 100644
index 0000000..bef8c57
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/progress_horizontal.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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 drawable is used in our custom horizontal Progress Bar style:
+ Widget.Styled.ProgressBar.Horizontal
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@android:id/background"
+ android:drawable="@drawable/progress_bg_styled" />
+
+ <item android:id="@android:id/secondaryProgress">
+ <scale
+ android:drawable="@drawable/progress_secondary_styled"
+ android:scaleWidth="100%" />
+ </item>
+
+ <item android:id="@android:id/progress">
+ <scale
+ android:drawable="@drawable/progress_primary_styled"
+ android:scaleWidth="100%" />
+ </item>
+
+</layer-list>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/selectable_background.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/selectable_background.xml
new file mode 100644
index 0000000..776dbb7
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/selectable_background.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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 drawable is used as the main touch feedback drawable for the Action Bar. By default it is
+ used as the action item button background, amongst other things.
+
+ The different items in this drawable are displayed when their selector state matches the view's
+ state.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@drawable/list_focused_styled" android:state_focused="true"
+ android:state_pressed="false"/>
+ <item android:drawable="@drawable/pressed_background" android:state_pressed="true"/>
+ <item android:drawable="@android:color/transparent"/>
+
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/spinner_background_ab.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/spinner_background_ab.xml
new file mode 100644
index 0000000..a12db6e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/spinner_background_ab.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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 drawable is used to style the list navigation spinner in our custom Action Bar theme.
+
+ The different items in this drawable are displayed when their selector state matches the view's
+ state.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:drawable="@drawable/spinner_ab_disabled_styled" android:state_enabled="false" />
+ <item android:drawable="@drawable/spinner_ab_pressed_styled" android:state_pressed="true" />
+ <item android:drawable="@drawable/spinner_ab_focused_styled" android:state_focused="true"
+ android:state_pressed="false" />
+ <item android:drawable="@drawable/spinner_ab_default_styled" />
+
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/tab_indicator_ab.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/tab_indicator_ab.xml
new file mode 100644
index 0000000..baa6492
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/drawable/tab_indicator_ab.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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 drawable is used as the background drawable for each tab displayed on the Action Bar.
+
+ The different items in this drawable are displayed when their selector state matches the view's
+ state.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!-- Non focused states -->
+ <item android:drawable="@android:color/transparent" android:state_focused="false"
+ android:state_pressed="false" android:state_selected="false" />
+ <item android:drawable="@drawable/tab_selected_styled" android:state_focused="false"
+ android:state_pressed="false" android:state_selected="true" />
+
+ <!-- Focused states -->
+ <item android:drawable="@drawable/tab_unselected_focused_styled" android:state_focused="true"
+ android:state_pressed="false" android:state_selected="false" />
+ <item android:drawable="@drawable/tab_selected_focused_styled" android:state_focused="true"
+ android:state_pressed="false" android:state_selected="true" />
+
+ <!-- Pressed & Non-focused -->
+ <item android:drawable="@drawable/tab_unselected_pressed_styled" android:state_focused="false"
+ android:state_pressed="true" android:state_selected="false" />
+ <item android:drawable="@drawable/tab_selected_pressed_styled" android:state_focused="false"
+ android:state_pressed="true" android:state_selected="true" />
+
+ <!-- Pressed & focused states -->
+ <item android:drawable="@drawable/tab_unselected_pressed_styled" android:state_focused="true"
+ android:state_pressed="true" android:state_selected="false" />
+ <item android:drawable="@drawable/tab_selected_pressed_styled" android:state_focused="true"
+ android:state_pressed="true" android:state_selected="true" />
+
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..a162d3f
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/main_description"
+ android:padding="16dp"
+ android:gravity="center"/>
+
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/menu/main.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..778a443
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/menu/main.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<!--
+ As we're using ActionBarCompat, any action item attributes come from ActionBarCompat's XML
+ namespace instead of the android namespace. Here we've added a new support namespace added to
+ the menu element allowing us to use the 'showAsAction' attribute in a backwards compatible way.
+ Any other action item attributes used should be referenced from this namespace too
+ (actionProviderClass, actionViewClass, actionLayout).
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:support="http://schemas.android.com/apk/res-auto" >
+
+ <!--
+ Here we create all of the items to be displayed in the menu, setting support:showAsAction to
+ define how the item should be displayed on the compatible Action Bar.
+ -->
+ <item
+ android:id="@+id/menu_refresh"
+ android:icon="@drawable/ic_action_refresh"
+ android:title="@string/menu_refresh"
+ support:showAsAction="ifRoom"/>
+
+ <item
+ android:id="@+id/menu_location"
+ android:icon="@drawable/ic_action_location"
+ android:title="@string/menu_location"
+ support:showAsAction="ifRoom"/>
+
+ <item
+ android:id="@+id/menu_settings"
+ android:icon="@drawable/ic_action_settings"
+ android:title="@string/menu_settings"
+ support:showAsAction="never"/>
+
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..4bfec48
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ This is the styled theme.
+
+ It extends from Theme.AppCompat.Light, but it could extend from any of
+ the Theme.AppCompat themes depending on your color scheme. This theme can be applied to
+ your application or individual activities in the AndroidManifest.xml. In this sample it is
+ set on the application.
+
+ This differs from the version of this theme in 'res/values', as we revert back to
+ setting the attributes from the android namespace in ICS+.
+ -->
+
+ <style name="Theme.Styled" parent="@style/Theme.AppCompat.Light">
+ <item name="android:actionBarItemBackground">@drawable/selectable_background</item>
+ <item name="android:actionBarTabStyle">@style/Widget.Styled.ActionBar.TabView</item>
+ <item name="android:actionBarStyle">@style/Widget.Styled.ActionBar</item>
+ <item name="android:actionDropDownStyle">
+ @style/Widget.Styled.Spinner.DropDown.ActionBar
+ </item>
+ <item name="android:dropDownListViewStyle">@style/Widget.Styled.ListView.DropDown</item>
+ <item name="android:popupMenuStyle">@style/Widget.Styled.PopupMenu</item>
+ </style>
+
+ <style name="Widget.Styled.ActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">
+ <item name="android:background">@drawable/ab_solid_styled</item>
+ <item name="android:backgroundStacked">@drawable/ab_stacked_solid_styled</item>
+ <item name="android:backgroundSplit">@drawable/ab_bottom_solid_styled</item>
+ <item name="android:progressBarStyle">@style/Widget.Styled.ProgressBar.Horizontal</item>
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..7adb0c6
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ActionBarCompat-Styled</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample shows you how to use ActionBarCompat with a customized theme. It utilizes a
+ split action bar when running on a device with a narrow display, and show three tabs.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/colors.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/colors.xml
new file mode 100644
index 0000000..e111f59
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <color name="pressed_styled">#CC669900</color>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/strings.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..de698d4
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+
+ <string name="menu_refresh">Refresh</string>
+ <string name="menu_location">Location</string>
+ <string name="menu_settings">Settings</string>
+ <string name="main_description">This is a basic Activity showing an Action Bar which has been
+ styled.
+ </string>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/styles.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..75b0533
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/styles.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ This is the styled theme.
+
+ It extends from Theme.AppCompat.Light, but it could extend from any of
+ the Theme.AppCompat themes depending on your color scheme. This theme can be applied to
+ your application or individual activities in the AndroidManifest.xml. In this sample it is
+ set on the application.
+
+ This differs from the version of this theme in 'res/values-v14', as not all of the
+ necessary attributes are available in the android: namespace on older versions of Android.
+ This means that for certain attributes we must set the attributes provided in
+ ActionBarCompat's namespace instead.
+ -->
+
+ <style name="Theme.Styled" parent="@style/Theme.AppCompat.Light">
+ <item name="actionBarItemBackground">@drawable/selectable_background</item>
+ <item name="actionBarTabStyle">@style/Widget.Styled.ActionBar.TabView</item>
+ <item name="actionBarStyle">@style/Widget.Styled.ActionBar</item>
+ <item name="actionDropDownStyle">@style/Widget.Styled.Spinner.DropDown.ActionBar</item>
+ <item name="dropDownListViewStyle">@style/Widget.Styled.ListView.DropDown</item>
+ <item name="popupMenuStyle">@style/Widget.Styled.PopupMenu</item>
+ </style>
+
+ <style name="Widget.Styled.ActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid">
+ <item name="background">@drawable/ab_solid_styled</item>
+ <item name="backgroundStacked">@drawable/ab_stacked_solid_styled</item>
+ <item name="backgroundSplit">@drawable/ab_bottom_solid_styled</item>
+ <item name="progressBarStyle">@style/Widget.Styled.ProgressBar.Horizontal</item>
+ </style>
+
+
+ <!--
+ For the following styles, the attributes are available in the android namespace which
+ means that we can set them here for all platforms (v7 through to the latest).
+ -->
+
+ <style name="Widget.Styled.ActionBar.TabView"
+ parent="@style/Widget.AppCompat.Light.ActionBar.TabView">
+ <item name="android:background">@drawable/tab_indicator_ab</item>
+ </style>
+
+ <style name="Widget.Styled.Spinner.DropDown.ActionBar"
+ parent="@style/Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
+ <item name="android:background">@drawable/spinner_background_ab</item>
+ <item name="android:popupBackground">@drawable/menu_dropdown_panel_styled</item>
+ <item name="android:dropDownSelector">@drawable/selectable_background</item>
+ </style>
+
+ <style name="Widget.Styled.ProgressBar.Horizontal"
+ parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
+ <item name="android:progressDrawable">@drawable/progress_horizontal</item>
+ </style>
+
+ <style name="Widget.Styled.PopupMenu" parent="@style/Widget.AppCompat.Light.PopupMenu">
+ <item name="android:popupBackground">@drawable/menu_dropdown_panel_styled</item>
+ </style>
+
+ <style name="Widget.Styled.ListView.DropDown"
+ parent="@style/Widget.AppCompat.Light.ListView.DropDown">
+ <item name="android:listSelector">@drawable/selectable_background</item>
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/AndroidManifest.xml b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..a990607
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.actionbarcompat.styled.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.actionbarcompat.styled"
+ android:label="Tests for com.example.android.actionbarcompat.styled" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/src/com/example/android/actionbarcompat/styled/tests/SampleTests.java b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/src/com/example/android/actionbarcompat/styled/tests/SampleTests.java
new file mode 100644
index 0000000..204afdc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/ActionBarCompat-StyledSample/tests/src/com/example/android/actionbarcompat/styled/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.actionbarcompat.styled.tests;
+
+import com.example.android.actionbarcompat.styled.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for Styled sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private StyledFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (StyledFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/README.txt b/prebuilts/gradle/ActionBarCompat-Styled/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/build.gradle b/prebuilts/gradle/ActionBarCompat-Styled/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/gradlew b/prebuilts/gradle/ActionBarCompat-Styled/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/gradlew.bat b/prebuilts/gradle/ActionBarCompat-Styled/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ActionBarCompat-Styled/settings.gradle b/prebuilts/gradle/ActionBarCompat-Styled/settings.gradle
new file mode 100644
index 0000000..eb7d66b
--- /dev/null
+++ b/prebuilts/gradle/ActionBarCompat-Styled/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ActionBarCompat-StyledSample'
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/build.gradle b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..547d95e
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.activityinstrumentation"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/activityinstrumentation/MainActivity.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/activityinstrumentation/MainActivity.java
new file mode 100644
index 0000000..39056ea
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/activityinstrumentation/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2013 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.activityinstrumentation;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Basic activity with a spinner. The spinner should persist its position to disk every time a
+ * new selection is made.
+ */
+public class MainActivity extends Activity {
+
+ /** Shared preferences key: Holds spinner position. Must not be negative. */
+ private static final String PREF_SPINNER_POS = "spinner_pos";
+ /** Magic constant to indicate that no value is stored for PREF_SPINNER_POS. */
+ private static final int PREF_SPINNER_VALUE_ISNULL = -1;
+ /** Values for display in spinner. */
+ private static final String[] SPINNER_VALUES = new String[] {
+ "Select Weather...", "Sunny", "Partly Cloudy", "Cloudy", "Rain", "Snow", "Hurricane"};
+
+ // Constants representing each of the options in SPINNER_VALUES. Declared package-private
+ // so that they can be accessed from our test suite.
+ static final int WEATHER_NOSELECTION = 0;
+ static final int WEATHER_SUNNY = 1;
+ static final int WEATHER_PARTLY_CLOUDY = 2;
+ static final int WEATHER_CLOUDY = 3;
+ static final int WEATHER_RAIN = 4;
+ static final int WEATHER_SNOW = 5;
+ static final int WEATHER_HURRICANE = 6;
+
+ /** Handle to default shared preferences for this activity. */
+ private SharedPreferences mPrefs;
+ /** Handle to the spinner in this Activity's layout. */
+ private Spinner mSpinner;
+
+ /**
+ * Setup activity state.
+ *
+ * @param savedInstanceState
+ */
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Inflate UI from res/layout/activity_main.xml
+ setContentView(R.layout.sample_main);
+
+ // Get handle to default shared preferences for this activity
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
+
+ // Populate spinner with sample values from an array
+ mSpinner = (Spinner) findViewById(R.id.spinner);
+ mSpinner.setAdapter(
+ new ArrayAdapter<String>(
+ this, // Context
+ android.R.layout.simple_list_item_1, // Layout
+ new ArrayList<String>(Arrays.asList(SPINNER_VALUES)) // Data source
+ ));
+
+ // Read in a sample value, if it's not set.
+ int selection = mPrefs.getInt(PREF_SPINNER_POS, PREF_SPINNER_VALUE_ISNULL);
+ if (selection != PREF_SPINNER_VALUE_ISNULL) {
+ mSpinner.setSelection(selection);
+ }
+
+ // Callback to persist spinner data whenever a new value is selected. This will be the
+ // focus of our sample unit test.
+ mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+
+ // The methods below commit the ID of the currently selected item in the spinner
+ // to disk, using a SharedPreferences file.
+ //
+ // Note: A common mistake here is to forget to call .commit(). Try removing this
+ // statement and running the tests to watch them fail.
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ mPrefs.edit().putInt(PREF_SPINNER_POS, position).commit();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ mPrefs.edit().remove(PREF_SPINNER_POS).commit();
+ }
+ });
+ }
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..2b7a4d1
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2013 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.
+ -->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/instructions"
+ android:id="@+id/instructions"/>
+
+ <Spinner
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/spinner"
+ android:layout_below="@+id/instructions"
+ android:layout_centerHorizontal="true"/>
+
+</RelativeLayout>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..0dfce6a
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ Copyright 2013 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.
+ -->
+
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..dfe40f4
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ActivityInstrumentation</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample provides a basic example of using an InstrumentationTest to probe the
+ internal state of an Activity.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/dimens.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..4afc9dd
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2013 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.
+ -->
+
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/strings.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..4ed2243
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2013 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.
+ -->
+
+<resources>
+ <string name="instructions">The value of the spinner below should be persisted when this activity is destroyed.</string>
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/AndroidManifest.xml b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..ad20a2a
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.activityinstrumentation.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.activityinstrumentation"
+ android:label="Tests for com.example.android.activityinstrumentation" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/src/com/example/android/activityinstrumentation/SampleTests.java b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/src/com/example/android/activityinstrumentation/SampleTests.java
new file mode 100644
index 0000000..3be1867
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/ActivityInstrumentationSample/tests/src/com/example/android/activityinstrumentation/SampleTests.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2013 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.activityinstrumentation;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase2;
+import android.widget.Spinner;
+
+import com.example.android.activityinstrumentation.MainActivity;
+import com.example.android.activityinstrumentation.R;
+
+/**
+ * This is a simple framework for a test of an Application. See
+ * {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
+ * how to write and extend Application tests.
+ *
+ * <p>To run this test, you can type:
+ * adb shell am instrument -w \
+ * -e class com.example.android.activityinstrumentation.MainActivityTest \
+ * quux.tests/android.test.InstrumentationTestRunner
+ *
+ * <p>Individual tests are defined as any method beginning with 'test'.
+ *
+ * <p>ActivityInstrumentationTestCase2 allows these tests to run alongside a running
+ * copy of the application under inspection. Calling getActivity() will return a
+ * handle to this activity (launching it if needed).
+ */
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ public SampleTests() {
+ super("com.example.android.activityinstrumentation", MainActivity.class);
+ }
+
+ /**
+ * Test to make sure that spinner values are persisted across activity restarts.
+ *
+ * <p>Launches the main activity, sets a spinner value, closes the activity, then relaunches
+ * that activity. Checks to make sure that the spinner values match what we set them to.
+ */
+ // BEGIN_INCLUDE (test_name)
+ public void testSpinnerValuePersistedBetweenLaunches() {
+ // END_INCLUDE (test_name)
+ final int TEST_SPINNER_POSITION_1 = MainActivity.WEATHER_PARTLY_CLOUDY;
+
+ // BEGIN_INCLUDE (launch_activity)
+ // Launch the activity
+ Activity activity = getActivity();
+ // END_INCLUDE (launch_activity)
+
+ // BEGIN_INCLUDE (write_to_ui)
+ // Set spinner to test position 1
+ final Spinner spinner1 = (Spinner) activity.findViewById(R.id.spinner);
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // Attempts to manipulate the UI must be performed on a UI thread.
+ // Calling this outside runOnUiThread() will cause an exception.
+ //
+ // You could also use @UiThreadTest, but activity lifecycle methods
+ // cannot be called if this annotation is used.
+ spinner1.requestFocus();
+ spinner1.setSelection(TEST_SPINNER_POSITION_1);
+ }
+ });
+ // END_INCLUDE (write_to_ui)
+
+ // BEGIN_INCLUDE (relaunch_activity)
+ // Close the activity
+ activity.finish();
+ setActivity(null); // Required to force creation of a new activity
+
+ // Relaunch the activity
+ activity = this.getActivity();
+ // END_INCLUDE (relaunch_activity)
+
+ // BEGIN_INCLUDE (check_results)
+ // Verify that the spinner was saved at position 1
+ final Spinner spinner2 = (Spinner) activity.findViewById(R.id.spinner);
+ int currentPosition = spinner2.getSelectedItemPosition();
+ assertEquals(TEST_SPINNER_POSITION_1, currentPosition);
+ // END_INCLUDE (check_results)
+
+ // Since this is a stateful test, we need to make sure that the activity isn't simply
+ // echoing a previously-stored value that (coincidently) matches position 1
+ final int TEST_SPINNER_POSITION_2 = MainActivity.WEATHER_SNOW;
+
+ // Set spinner to test position 2
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ spinner2.requestFocus();
+ spinner2.setSelection(TEST_SPINNER_POSITION_2);
+ }
+ });
+
+ // Close the activity
+ activity.finish();
+ setActivity(null);
+
+ // Relaunch the activity
+ activity = this.getActivity();
+
+ // Verify that the spinner was saved at position 2
+ final Spinner spinner3 = (Spinner) activity.findViewById(R.id.spinner);
+ currentPosition = spinner3.getSelectedItemPosition();
+ assertEquals(TEST_SPINNER_POSITION_2, currentPosition);
+ }
+}
diff --git a/prebuilts/gradle/ActivityInstrumentation/README.txt b/prebuilts/gradle/ActivityInstrumentation/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ActivityInstrumentation/build.gradle b/prebuilts/gradle/ActivityInstrumentation/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ActivityInstrumentation/gradlew b/prebuilts/gradle/ActivityInstrumentation/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ActivityInstrumentation/gradlew.bat b/prebuilts/gradle/ActivityInstrumentation/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ActivityInstrumentation/settings.gradle b/prebuilts/gradle/ActivityInstrumentation/settings.gradle
new file mode 100644
index 0000000..0f010ba
--- /dev/null
+++ b/prebuilts/gradle/ActivityInstrumentation/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ActivityInstrumentationSample'
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/build.gradle b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/AndroidManifest.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1d01856
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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 versionCode is an integer representation of this version of your application. New
+ versions get higher numbers, so the upgrade system can avoid dealing with the ambiguity
+ of "1.9" vs "1.10". versionName, on the other hand, can be whatever you want, as the code
+ that handles upgrading Android apps between versions on your device just ignores it.-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.advancedimmersivemode"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- This sample is to demonstrate features released in API 19.
+ So while it would technically run on an earlier version of Android,
+ there wouldn't be much point) -->
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+ <!-- allowBackup declares if the app can be part of device-wide backups such as "adb backup" -->
+ <!-- theme is a way of applying UI decisions across your entire application. You can also
+ define it on a per-application basis. -->
+ <application
+ android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <!-- Every activity needs its own Manifest element. The intent-filter contained in the
+ element declares the intents that can be used to activate this Activity. For instance,
+ the one below flags this Activity as a "main" entry point of this app, and suitable
+ for creating a shortcut to in the Launcher. If you wanted your app to have 5
+ different Activities available in the launcher, you could just make 5 activities
+ with that intent filter. Please don't do that. Just because it's a good example
+ doesn't mean it's a good idea. -->
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/AdvancedImmersiveModeFragment.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/AdvancedImmersiveModeFragment.java
new file mode 100644
index 0000000..fe11ecb
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/AdvancedImmersiveModeFragment.java
@@ -0,0 +1,174 @@
+/*
+* Copyright (C) 2012 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.advancedimmersivemode;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CheckBox;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * Demonstrates how to update the app's UI by toggling immersive mode.
+ * Checkboxes are also made available for toggling other UI flags which can
+ * alter the behavior of immersive mode.
+ */
+public class AdvancedImmersiveModeFragment extends Fragment {
+
+ public static final String TAG = "AdvancedImmersiveModeFragment";
+ public CheckBox mHideNavCheckbox;
+ public CheckBox mHideStatusBarCheckBox;
+ public CheckBox mImmersiveModeCheckBox;
+ public CheckBox mImmersiveModeStickyCheckBox;
+ public CheckBox mLowProfileCheckBox;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ final View decorView = getActivity().getWindow().getDecorView();
+ ViewGroup parentView = (ViewGroup) getActivity().getWindow().getDecorView()
+ .findViewById(R.id.sample_main_layout);
+
+ mLowProfileCheckBox = new CheckBox(getActivity());
+ mLowProfileCheckBox.setText("Enable Low Profile mode.");
+ parentView.addView(mLowProfileCheckBox);
+
+ mHideNavCheckbox = new CheckBox(getActivity());
+ mHideNavCheckbox.setChecked(true);
+ mHideNavCheckbox.setText("Hide Navigation bar");
+ parentView.addView(mHideNavCheckbox);
+
+ mHideStatusBarCheckBox = new CheckBox(getActivity());
+ mHideStatusBarCheckBox.setChecked(true);
+ mHideStatusBarCheckBox.setText("Hide Status Bar");
+ parentView.addView(mHideStatusBarCheckBox);
+
+ mImmersiveModeCheckBox = new CheckBox(getActivity());
+ mImmersiveModeCheckBox.setText("Enable Immersive Mode.");
+ parentView.addView(mImmersiveModeCheckBox);
+
+ mImmersiveModeStickyCheckBox = new CheckBox(getActivity());
+ mImmersiveModeStickyCheckBox.setText("Enable Immersive Mode (Sticky)");
+ parentView.addView(mImmersiveModeStickyCheckBox);
+
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ toggleImmersiveMode();
+ }
+ return true;
+ }
+
+ /**
+ * Detects and toggles immersive mode (also known as "hidey bar" mode).
+ */
+ public void toggleImmersiveMode() {
+
+ // BEGIN_INCLUDE (get_current_ui_flags)
+ // The "Decor View" is the parent view of the Activity. It's also conveniently the easiest
+ // one to find from within a fragment, since there's a handy helper method to pull it, and
+ // we don't have to bother with picking a view somewhere deeper in the hierarchy and calling
+ // "findViewById" on it.
+ View decorView = getActivity().getWindow().getDecorView();
+ int uiOptions = decorView.getSystemUiVisibility();
+ int newUiOptions = uiOptions;
+ // END_INCLUDE (get_current_ui_flags)
+
+ // BEGIN_INCLUDE (toggle_lowprofile_mode)
+ // Low profile mode doesn't resize the screen at all, but it covers the nav & status bar
+ // icons with black so they're less distracting. Unlike "full screen" and "hide nav bar,"
+ // this mode doesn't interact with immersive mode at all, but it's instructive when running
+ // this sample to observe the differences in behavior.
+ if (mLowProfileCheckBox.isChecked()) {
+ newUiOptions |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ } else {
+ newUiOptions &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ }
+ // END_INCLUDE (toggle_lowprofile_mode)
+
+ // BEGIN_INCLUDE (toggle_fullscreen_mode)
+ // When enabled, this flag hides non-critical UI, such as the status bar,
+ // which usually shows notification icons, battery life, etc
+ // on phone-sized devices. The bar reappears when the user swipes it down. When immersive
+ // mode is also enabled, the app-drawable area expands, and when the status bar is swiped
+ // down, it appears semi-transparently and slides in over the app, instead of pushing it
+ // down.
+ if (mHideStatusBarCheckBox.isChecked()) {
+ newUiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
+ } else {
+ newUiOptions &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
+ }
+ // END_INCLUDE (toggle_fullscreen_mode)
+
+ // BEGIN_INCLUDE (toggle_hidenav_mode)
+ // When enabled, this flag hides the black nav bar along the bottom,
+ // where the home/back buttons are. The nav bar normally instantly reappears
+ // when the user touches the screen. When immersive mode is also enabled, the nav bar
+ // stays hidden until the user swipes it back.
+ if (mHideNavCheckbox.isChecked()) {
+ newUiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ } else {
+ newUiOptions &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ }
+ // END_INCLUDE (toggle_hidenav_mode)
+
+ // BEGIN_INCLUDE (toggle_immersive_mode)
+ // Immersive mode doesn't do anything without at least one of the previous flags
+ // enabled. When enabled, it allows the user to swipe the status and/or nav bars
+ // off-screen. When the user swipes the bars back onto the screen, the flags are cleared
+ // and immersive mode is automatically disabled.
+ if (mImmersiveModeCheckBox.isChecked()) {
+ newUiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE;
+ } else {
+ newUiOptions &= ~View.SYSTEM_UI_FLAG_IMMERSIVE;
+ }
+ // END_INCLUDE (toggle_immersive_mode)
+
+ // BEGIN_INCLUDE (toggle_immersive_mode_sticky)
+ // There's actually two forms of immersive mode, normal and "sticky". Sticky immersive mode
+ // is different in 2 key ways:
+ //
+ // * Uses semi-transparent bars for the nav and status bars
+ // * This UI flag will *not* be cleared when the user interacts with the UI.
+ // When the user swipes, the bars will temporarily appear for a few seconds and then
+ // disappear again.
+ if (mImmersiveModeStickyCheckBox.isChecked()) {
+ newUiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ } else {
+ newUiOptions &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ }
+ // END_INCLUDE (toggle_immersive_mode_sticky)
+
+ // BEGIN_INCLUDE (set_ui_flags)
+ //Set the new UI flags.
+ decorView.setSystemUiVisibility(newUiOptions);
+ Log.i(TAG, "Current height: " + decorView.getHeight() + ", width: " + decorView.getWidth());
+ // END_INCLUDE (set_ui_flags)
+ }
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/MainActivity.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/MainActivity.java
new file mode 100644
index 0000000..0ebe878
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/advancedimmersivemode/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.advancedimmersivemode;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "AdvancedImmersiveModeFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ AdvancedImmersiveModeFragment fragment = new AdvancedImmersiveModeFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/fragment_flags.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/fragment_flags.xml
new file mode 100644
index 0000000..2c74e83
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/layout/fragment_flags.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical" android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/flag_enable_lowprof"
+ android:text="Enable Low Profile Mode" />
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/flag_hide_navbar"
+ android:text="Hide Navigation bar" />
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/flag_hide_statbar"
+ android:text="Hide Status Bar" />
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/flag_enable_immersive"
+ android:text="Enable Immersive Mode" />
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/flag_enable_immersive_sticky"
+ android:text="Enable Immersive Mode (Sticky)" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Do things!"
+ android:id="@+id/btn_changeFlags" />
+
+
+ <TextView
+ android:layout_marginTop="@dimen/margin_large"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Common flag presets"/>
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal" android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Immersive Mode"
+ android:id="@+id/btn_immersive" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Leanback Mode"
+ android:id="@+id/btn_leanback" />
+
+ </LinearLayout>
+
+
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/menu/main.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..305e12a
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">AdvancedImmersiveMode</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ \"Immersive Mode\" is a new UI mode which improves \"hide full screen\" and
+ \"hide nav bar\" modes, by letting users swipe the bars in and out. This sample
+ lets the user experiment with immersive mode by enabling it and seeing how it interacts
+ with some of the other UI flags related to full-screen apps.
+ \n\nThis sample also lets the user choose between normal immersive mode and "sticky"
+ immersive mode, which removes the status bar and nav bar
+ a few seconds after the user has swiped them back in.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/strings.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..a65b891
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Try these settings!</string>
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/AndroidManifest.xml b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..7117969
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.advancedimmersivemode.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.advancedimmersivemode"
+ android:label="Tests for com.example.android.advancedimmersivemode" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/src/com/example/android/advancedimmersivemode/tests/SampleTests.java b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/src/com/example/android/advancedimmersivemode/tests/SampleTests.java
new file mode 100644
index 0000000..c51a488
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/AdvancedImmersiveModeSample/tests/src/com/example/android/advancedimmersivemode/tests/SampleTests.java
@@ -0,0 +1,126 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+* Copyright (C) 2013 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.advancedimmersivemode.tests;
+
+import com.example.android.advancedimmersivemode.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+/**
+* Tests for AdvancedImmersiveMode sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private AdvancedImmersiveModeFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mTestActivity = getActivity();
+ mTestFragment = (AdvancedImmersiveModeFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+
+ /**
+ * Verify that the UI flags actually changed when the toggle method is called.
+ */
+ @UiThreadTest
+ public void testFlagsChanged() {
+ int uiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ mTestFragment.mImmersiveModeCheckBox.setChecked(true);
+ mTestFragment.mHideNavCheckbox.setChecked(true);
+ mTestFragment.mHideStatusBarCheckBox.setChecked(true);
+ mTestFragment.toggleImmersiveMode();
+ int newUiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ assertTrue("UI Flags didn't toggle.", uiFlags != newUiFlags);
+ }
+
+ /**
+ * Verify that the view's height actually changed when the toggle method is called.
+ * This should result in a change in height for the DecorView.
+ */
+ public void testDecorHeightExpanded() {
+ // Grab the initial height of the DecorWindow.
+ int startingHeight = getActivity().getWindow().getDecorView().getHeight();
+
+ // In order to test that this worked: Need to toggle the immersive mode on the UI thread,
+ // wait a suitable amount of time (this test goes with 200 ms), then check to see if the
+ // height changed.
+ try {
+ Runnable testRunnable = (new Runnable() {
+ public void run() {
+ // Toggle immersive mode
+ mTestFragment.mImmersiveModeCheckBox.setChecked(true);
+ mTestFragment.mHideNavCheckbox.setChecked(true);
+ mTestFragment.mHideStatusBarCheckBox.setChecked(true);
+ mTestFragment.toggleImmersiveMode();
+ synchronized(this) {
+ // Notify any thread waiting on this runnable that it can continue
+ this.notify();
+ }
+ }
+ });
+ synchronized(testRunnable) {
+ // Since toggling immersive mode makes changes to the view hierarchy, it needs to run
+ // on the UI thread, or crashing will occur.
+ mTestActivity.runOnUiThread(testRunnable);
+ testRunnable.wait();
+
+ }
+ synchronized(this) {
+ //Wait about 200ms for the change to take place
+ wait(200L);
+ }
+ } catch (Throwable throwable) {
+ fail(throwable.getMessage());
+ }
+
+ int expandedHeight = getActivity().getWindow().getDecorView().getHeight();
+ assertTrue("Bars aren't hidden.", expandedHeight != startingHeight);
+ }
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/README.txt b/prebuilts/gradle/AdvancedImmersiveMode/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/build.gradle b/prebuilts/gradle/AdvancedImmersiveMode/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/gradlew b/prebuilts/gradle/AdvancedImmersiveMode/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/gradlew.bat b/prebuilts/gradle/AdvancedImmersiveMode/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/AdvancedImmersiveMode/settings.gradle b/prebuilts/gradle/AdvancedImmersiveMode/settings.gradle
new file mode 100644
index 0000000..0f7ed4b
--- /dev/null
+++ b/prebuilts/gradle/AdvancedImmersiveMode/settings.gradle
@@ -0,0 +1 @@
+include 'AdvancedImmersiveModeSample'
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/build.gradle b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/build.gradle
new file mode 100644
index 0000000..7bfc9ad
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 18
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/AndroidManifest.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b492bbf
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.apprestrictions"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="18" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher">
+
+ <activity android:name="MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="CustomRestrictionsActivity"
+ android:label="@string/restrictions_activity_label" />
+
+ <receiver android:name="GetRestrictionsReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsActivity.java b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsActivity.java
new file mode 100644
index 0000000..213b313
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 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.apprestrictions;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * This activity demonstrates how an app can integrate its own custom app restriction settings
+ * with the restricted profile feature.
+ *
+ * This sample app maintains custom app restriction settings in shared preferences. When
+ * the activity is invoked (from Settings > Users), the stored settings are used to initialize
+ * the custom configuration on the user interface. Three sample input types are
+ * shown: checkbox, single-choice, and multi-choice. When the settings are modified by the user,
+ * the corresponding restriction entries are saved, which are retrievable under a restricted
+ * profile.
+ */
+public class CustomRestrictionsActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ getFragmentManager().beginTransaction().replace(android.R.id.content,
+ new CustomRestrictionsFragment()).commit();
+ }
+ }
+}
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsFragment.java b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsFragment.java
new file mode 100644
index 0000000..b04dfd1
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/CustomRestrictionsFragment.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 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.apprestrictions;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.RestrictionEntry;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.MultiSelectListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This fragment is included in {@code CustomRestrictionsActivity}. It demonstrates how an app
+ * can integrate its own custom app restriction settings with the restricted profile feature.
+ *
+ * This sample app maintains custom app restriction settings in shared preferences. Your app
+ * can use other methods to maintain the settings. When this activity is invoked
+ * (from Settings > Users > Restricted Profile), the shared preferences are used to initialize
+ * the custom configuration on the user interface.
+ *
+ * Three sample input types are shown: checkbox, single-choice, and multi-choice. When the
+ * settings are modified by the user, the corresponding restriction entries are saved in the
+ * platform. The saved restriction entries are retrievable when the app is launched under a
+ * restricted profile.
+ */
+public class CustomRestrictionsFragment extends PreferenceFragment
+ implements Preference.OnPreferenceChangeListener {
+
+ // Shared preference key for the boolean restriction.
+ private static final String KEY_BOOLEAN_PREF = "pref_boolean";
+ // Shared preference key for the single-select restriction.
+ private static final String KEY_CHOICE_PREF = "pref_choice";
+ // Shared preference key for the multi-select restriction.
+ private static final String KEY_MULTI_PREF = "pref_multi";
+
+
+ private List<RestrictionEntry> mRestrictions;
+ private Bundle mRestrictionsBundle;
+
+ // Shared preferences for each of the sample input types.
+ private CheckBoxPreference mBooleanPref;
+ private ListPreference mChoicePref;
+ private MultiSelectListPreference mMultiPref;
+
+ // Restriction entries for each of the sample input types.
+ private RestrictionEntry mBooleanEntry;
+ private RestrictionEntry mChoiceEntry;
+ private RestrictionEntry mMultiEntry;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.custom_prefs);
+
+ // This sample app uses shared preferences to maintain app restriction settings. Your app
+ // can use other methods to maintain the settings.
+ mBooleanPref = (CheckBoxPreference) findPreference(KEY_BOOLEAN_PREF);
+ mChoicePref = (ListPreference) findPreference(KEY_CHOICE_PREF);
+ mMultiPref = (MultiSelectListPreference) findPreference(KEY_MULTI_PREF);
+
+ mBooleanPref.setOnPreferenceChangeListener(this);
+ mChoicePref.setOnPreferenceChangeListener(this);
+ mMultiPref.setOnPreferenceChangeListener(this);
+
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final Activity activity = getActivity();
+
+ // BEGIN_INCLUDE (GET_CURRENT_RESTRICTIONS)
+ // Existing app restriction settings, if exist, can be retrieved from the Bundle.
+ mRestrictionsBundle =
+ activity.getIntent().getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE);
+
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle =
+ ((UserManager) activity.getSystemService(Context.USER_SERVICE))
+ .getApplicationRestrictions(activity.getPackageName());
+ }
+
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle = new Bundle();
+ }
+
+ mRestrictions = activity.getIntent().getParcelableArrayListExtra(
+ Intent.EXTRA_RESTRICTIONS_LIST);
+ // END_INCLUDE (GET_CURRENT_RESTRICTIONS)
+
+ // Transfers the saved values into the preference hierarchy.
+ if (mRestrictions != null) {
+ for (RestrictionEntry entry : mRestrictions) {
+ if (entry.getKey().equals(GetRestrictionsReceiver.KEY_BOOLEAN)) {
+ mBooleanPref.setChecked(entry.getSelectedState());
+ mBooleanEntry = entry;
+ } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_CHOICE)) {
+ mChoicePref.setValue(entry.getSelectedString());
+ mChoiceEntry = entry;
+ } else if (entry.getKey().equals(GetRestrictionsReceiver.KEY_MULTI_SELECT)) {
+ HashSet<String> set = new HashSet<String>();
+ for (String value : entry.getAllSelectedStrings()) {
+ set.add(value);
+ }
+ mMultiPref.setValues(set);
+ mMultiEntry = entry;
+ }
+ }
+ } else {
+ mRestrictions = new ArrayList<RestrictionEntry>();
+
+ // Initializes the boolean restriction entry and updates its corresponding shared
+ // preference value.
+ mBooleanEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_BOOLEAN,
+ mRestrictionsBundle.getBoolean(GetRestrictionsReceiver.KEY_BOOLEAN, false));
+ mBooleanEntry.setType(RestrictionEntry.TYPE_BOOLEAN);
+ mBooleanPref.setChecked(mBooleanEntry.getSelectedState());
+
+ // Initializes the single choice restriction entry and updates its corresponding
+ // shared preference value.
+ mChoiceEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_CHOICE,
+ mRestrictionsBundle.getString(GetRestrictionsReceiver.KEY_CHOICE));
+ mChoiceEntry.setType(RestrictionEntry.TYPE_CHOICE);
+ mChoicePref.setValue(mChoiceEntry.getSelectedString());
+
+ // Initializes the multi-select restriction entry and updates its corresponding
+ // shared preference value.
+ mMultiEntry = new RestrictionEntry(GetRestrictionsReceiver.KEY_MULTI_SELECT,
+ mRestrictionsBundle.getStringArray(
+ GetRestrictionsReceiver.KEY_MULTI_SELECT));
+ mMultiEntry.setType(RestrictionEntry.TYPE_MULTI_SELECT);
+ if (mMultiEntry.getAllSelectedStrings() != null) {
+ HashSet<String> set = new HashSet<String>();
+ final String[] values = mRestrictionsBundle.getStringArray(
+ GetRestrictionsReceiver.KEY_MULTI_SELECT);
+ if (values != null) {
+ for (String value : values) {
+ set.add(value);
+ }
+ }
+ mMultiPref.setValues(set);
+ }
+ mRestrictions.add(mBooleanEntry);
+ mRestrictions.add(mChoiceEntry);
+ mRestrictions.add(mMultiEntry);
+ }
+ // Prepares result to be passed back to the Settings app when the custom restrictions
+ // activity finishes.
+ Intent intent = new Intent(getActivity().getIntent());
+ intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS_LIST,
+ new ArrayList<RestrictionEntry>(mRestrictions));
+ getActivity().setResult(Activity.RESULT_OK, intent);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mBooleanPref) {
+ mBooleanEntry.setSelectedState((Boolean) newValue);
+ } else if (preference == mChoicePref) {
+ mChoiceEntry.setSelectedString((String) newValue);
+ } else if (preference == mMultiPref) {
+ String[] selectedStrings = new String[((Set<String>)newValue).size()];
+ int i = 0;
+ for (String value : (Set<String>) newValue) {
+ selectedStrings[i++] = value;
+ }
+ mMultiEntry.setAllSelectedStrings(selectedStrings);
+ }
+
+ // Saves all the app restriction configuration changes from the custom activity.
+ Intent intent = new Intent(getActivity().getIntent());
+ intent.putParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS_LIST,
+ new ArrayList<RestrictionEntry>(mRestrictions));
+ getActivity().setResult(Activity.RESULT_OK, intent);
+ return true;
+ }
+}
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/GetRestrictionsReceiver.java b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/GetRestrictionsReceiver.java
new file mode 100644
index 0000000..bb5a283
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/GetRestrictionsReceiver.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2013 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.apprestrictions;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.RestrictionEntry;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+public class GetRestrictionsReceiver extends BroadcastReceiver {
+ private static final String TAG = GetRestrictionsReceiver.class.getSimpleName();
+
+ // Keys for referencing app restriction settings from the platform.
+ public static final String KEY_BOOLEAN = "boolean_key";
+ public static final String KEY_CHOICE = "choice_key";
+ public static final String KEY_MULTI_SELECT = "multi_key";
+
+ @Override
+ public void onReceive(final Context context, Intent intent) {
+ final PendingResult result = goAsync();
+
+ // If app restriction settings are already created, they will be included in the Bundle
+ // as key/value pairs.
+ final Bundle existingRestrictions =
+ intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE);
+ Log.i(TAG, "existingRestrictions = " + existingRestrictions);
+
+ new Thread() {
+ public void run() {
+ createRestrictions(context, result, existingRestrictions);
+ }
+ }.start();
+ }
+
+ // Initializes a boolean type restriction entry.
+ public static void populateBooleanEntry(Resources res, RestrictionEntry entry) {
+ entry.setType(RestrictionEntry.TYPE_BOOLEAN);
+ entry.setTitle(res.getString(R.string.boolean_entry_title));
+ }
+
+ // Initializes a single choice type restriction entry.
+ public static void populateChoiceEntry(Resources res, RestrictionEntry reSingleChoice) {
+ String[] choiceEntries = res.getStringArray(R.array.choice_entry_entries);
+ String[] choiceValues = res.getStringArray(R.array.choice_entry_values);
+ if (reSingleChoice.getSelectedString() == null) {
+ reSingleChoice.setSelectedString(choiceValues[0]);
+ }
+ reSingleChoice.setTitle(res.getString(R.string.choice_entry_title));
+ reSingleChoice.setChoiceEntries(choiceEntries);
+ reSingleChoice.setChoiceValues(choiceValues);
+ reSingleChoice.setType(RestrictionEntry.TYPE_CHOICE);
+ }
+
+ // Initializes a multi-select type restriction entry.
+ public static void populateMultiEntry(Resources res, RestrictionEntry reMultiSelect) {
+ String[] multiEntries = res.getStringArray(R.array.multi_entry_entries);
+ String[] multiValues = res.getStringArray(R.array.multi_entry_values);
+ if (reMultiSelect.getAllSelectedStrings() == null) {
+ reMultiSelect.setAllSelectedStrings(new String[0]);
+ }
+ reMultiSelect.setTitle(res.getString(R.string.multi_entry_title));
+ reMultiSelect.setChoiceEntries(multiEntries);
+ reMultiSelect.setChoiceValues(multiValues);
+ reMultiSelect.setType(RestrictionEntry.TYPE_MULTI_SELECT);
+ }
+
+ // Demonstrates the creation of standard app restriction types: boolean, single choice, and
+ // multi-select.
+ private ArrayList<RestrictionEntry> initRestrictions(Context context) {
+ ArrayList<RestrictionEntry> newRestrictions = new ArrayList<RestrictionEntry>();
+ Resources res = context.getResources();
+
+ RestrictionEntry reBoolean = new RestrictionEntry(KEY_BOOLEAN, false);
+ populateBooleanEntry(res, reBoolean);
+ newRestrictions.add(reBoolean);
+
+ RestrictionEntry reSingleChoice = new RestrictionEntry(KEY_CHOICE, (String) null);
+ populateChoiceEntry(res, reSingleChoice);
+ newRestrictions.add(reSingleChoice);
+
+ RestrictionEntry reMultiSelect = new RestrictionEntry(KEY_MULTI_SELECT, (String[]) null);
+ populateMultiEntry(res, reMultiSelect);
+ newRestrictions.add(reMultiSelect);
+
+ return newRestrictions;
+ }
+
+ private void createRestrictions(Context context, PendingResult result,
+ Bundle existingRestrictions) {
+ // The incoming restrictions bundle contains key/value pairs representing existing app
+ // restrictions for this package. In order to retain existing app restrictions, you need to
+ // construct new restriction entries and then copy in any existing values for the new keys.
+ ArrayList<RestrictionEntry> newEntries = initRestrictions(context);
+
+ // If app restrictions were not previously configured for the package, create the default
+ // restrictions entries and return them.
+ if (existingRestrictions == null) {
+ Bundle extras = new Bundle();
+ extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, newEntries);
+ result.setResult(Activity.RESULT_OK, null, extras);
+ result.finish();
+ return;
+ }
+
+ // Retains current restriction settings by transferring existing restriction entries to
+ // new ones.
+ for (RestrictionEntry entry : newEntries) {
+ final String key = entry.getKey();
+ if (KEY_BOOLEAN.equals(key)) {
+ entry.setSelectedState(existingRestrictions.getBoolean(KEY_BOOLEAN));
+ } else if (KEY_CHOICE.equals(key)) {
+ if (existingRestrictions.containsKey(KEY_CHOICE)) {
+ entry.setSelectedString(existingRestrictions.getString(KEY_CHOICE));
+ }
+ } else if (KEY_MULTI_SELECT.equals(key)) {
+ if (existingRestrictions.containsKey(KEY_MULTI_SELECT)) {
+ entry.setAllSelectedStrings(existingRestrictions.getStringArray(key));
+ }
+ }
+ }
+
+ final Bundle extras = new Bundle();
+
+ // This path demonstrates the use of a custom app restriction activity instead of standard
+ // types. When a custom activity is set, the standard types will not be available under
+ // app restriction settings.
+ //
+ // If your app has an existing activity for app restriction configuration, you can set it
+ // up with the intent here.
+ if (PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(MainActivity.CUSTOM_CONFIG_KEY, false)) {
+ final Intent customIntent = new Intent();
+ customIntent.setClass(context, CustomRestrictionsActivity.class);
+ extras.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, customIntent);
+ }
+
+ extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, newEntries);
+ result.setResult(Activity.RESULT_OK, null, extras);
+ result.finish();
+ }
+}
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/MainActivity.java b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/MainActivity.java
new file mode 100644
index 0000000..57c4439
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/java/com/example/android/apprestrictions/MainActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2013 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.apprestrictions;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.TextView;
+
+/**
+ * This is the main user interface of the App Restrictions sample app. It demonstrates the use
+ * of the App Restriction feature, which is available on Android 4.3 and above tablet devices
+ * with the multiuser feature.
+ *
+ * When launched under the primary User account, you can toggle between standard app restriction
+ * types and custom. When launched under a restricted profile, this activity displays app
+ * restriction settings, if available.
+ *
+ * Follow these steps to exercise the feature:
+ * 1. If this is the primary user, go to Settings > Users.
+ * 2. Create a restricted profile, if one doesn't exist already.
+ * 3. Open the profile settings, locate the sample app, and tap the app restriction settings
+ * icon. Configure app restrictions for the app.
+ * 4. In the lock screen, switch to the user's restricted profile, launch this sample app,
+ * and see the configured app restrictions displayed.
+ */
+public class MainActivity extends Activity {
+ private Bundle mRestrictionsBundle;
+
+ // Checkbox to indicate whether custom or standard app restriction types are selected.
+ private CheckBox mCustomConfig;
+
+ public static final String CUSTOM_CONFIG_KEY = "custom_config";
+
+ private TextView mMultiEntryValue;
+ private TextView mChoiceEntryValue;
+ private TextView mBooleanEntryValue;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Sets up user interface elements.
+ setContentView(R.layout.main);
+
+ mCustomConfig = (CheckBox) findViewById(R.id.custom_app_limits);
+ final boolean customChecked =
+ PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
+ CUSTOM_CONFIG_KEY, false);
+ if (customChecked) mCustomConfig.setChecked(true);
+
+ mMultiEntryValue = (TextView) findViewById(R.id.multi_entry_id);
+ mChoiceEntryValue = (TextView) findViewById(R.id.choice_entry_id);
+ mBooleanEntryValue = (TextView) findViewById(R.id.boolean_entry_id);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // If app restrictions are set for this package, when launched from a restricted profile,
+ // the settings are available in the returned Bundle as key/value pairs.
+ mRestrictionsBundle =
+ ((UserManager) getSystemService(Context.USER_SERVICE))
+ .getApplicationRestrictions(getPackageName());
+ if (mRestrictionsBundle == null) {
+ mRestrictionsBundle = new Bundle();
+ }
+
+ // Reads and displays values from a boolean type restriction entry, if available.
+ // An app can utilize these settings to restrict its content under a restricted profile.
+ final String booleanRestrictionValue =
+ mRestrictionsBundle.containsKey(GetRestrictionsReceiver.KEY_BOOLEAN) ?
+ mRestrictionsBundle.getBoolean(GetRestrictionsReceiver.KEY_BOOLEAN) + "":
+ getString(R.string.na);
+ mBooleanEntryValue.setText(booleanRestrictionValue);
+
+ // Reads and displays values from a single choice restriction entry, if available.
+ final String singleChoiceRestrictionValue =
+ mRestrictionsBundle.containsKey(GetRestrictionsReceiver.KEY_CHOICE) ?
+ mRestrictionsBundle.getString(GetRestrictionsReceiver.KEY_CHOICE) :
+ getString(R.string.na);
+ mChoiceEntryValue.setText(singleChoiceRestrictionValue);
+
+ // Reads and displays values from a multi-select restriction entry, if available.
+ final String[] multiSelectValues =
+ mRestrictionsBundle.getStringArray(GetRestrictionsReceiver.KEY_MULTI_SELECT);
+ if (multiSelectValues == null || multiSelectValues.length == 0) {
+ mMultiEntryValue.setText(getString(R.string.na));
+ } else {
+ String tempValue = "";
+ for (String value : multiSelectValues) {
+ tempValue = tempValue + value + " ";
+ }
+ mMultiEntryValue.setText(tempValue);
+ }
+ }
+
+ /**
+ * Saves custom app restriction to the shared preference.
+ *
+ * This flag is used by {@code GetRestrictionsReceiver} to determine if a custom app
+ * restriction activity should be used.
+ *
+ * @param view
+ */
+ public void onCustomClicked(View view) {
+ final SharedPreferences.Editor editor =
+ PreferenceManager.getDefaultSharedPreferences(this).edit();
+ editor.putBoolean(CUSTOM_CONFIG_KEY, mCustomConfig.isChecked()).commit();
+ }
+}
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..f36c473
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..5ab2e0d
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..7622838
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..7f55fef
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/main.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/main.xml
new file mode 100644
index 0000000..55e2c8e
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/layout/main.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="20dp">
+
+ <TextView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:textSize="18sp"
+ android:text="@string/sample_app_description"/>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="15dp">
+ <CheckBox android:id="@+id/custom_app_limits"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:onClick="onCustomClicked"/>
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/custom_description"
+ android:onClick="onCustomClicked"
+ android:layout_weight="1"/>
+ </LinearLayout>
+
+ <!-- Separator -->
+ <View android:layout_height="1dp"
+ android:background="@android:color/white"
+ android:layout_width="match_parent"
+ android:layout_margin="25dp"/>
+
+ <!-- Section to show app restriction settings under a restricted profile. -->
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="20sp"
+ android:text="@string/current_app_limits_label"/>
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:layout_marginBottom="10dp"
+ android:text="@string/current_app_limits_description"/>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp">
+ <TextView android:layout_width="210dp"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/boolean_entry_title"/>
+ <Space android:layout_height="1dp"
+ android:layout_width="15dp"/>
+ <TextView android:id="@+id/boolean_entry_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/boolean_entry_title"/>
+ </LinearLayout>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp">
+ <TextView android:layout_width="210dp"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/choice_entry_title"/>
+ <Space android:layout_height="1dp"
+ android:layout_width="15dp"/>
+ <TextView android:id="@+id/choice_entry_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/boolean_entry_title"/>
+ </LinearLayout>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dp">
+ <TextView android:layout_width="210dp"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/multi_entry_title"/>
+ <Space android:layout_height="1dp"
+ android:layout_width="15dp"/>
+ <TextView android:id="@+id/multi_entry_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:text="@string/multi_entry_title"/>
+ </LinearLayout>
+ </LinearLayout>
+</ScrollView>
\ No newline at end of file
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..08a4663
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">AppRestrictions</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates the use of the App Restriction feature, which is available on
+ Android 4.3 and above tablet device with the multiuser feature.
+
+ When launched under the primary User account, you can toggle between standard app restriction
+ types and custom. When launched under a restricted profile, this activity displays app
+ restriction settings, if available.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/strings.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..534edf0
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/strings.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="restrictions_activity_label">Custom app restrictions</string>
+ <string name="boolean_entry_title">Test boolean type</string>
+ <string name="choice_entry_title">Test choice type</string>
+ <string name="multi_entry_title">Test multi-select type</string>
+ <string name="custom_description">If checked, use a custom app restriction Activity. Otherwise,
+ use standard restriction types.
+ </string>
+ <string name="sample_app_description">Note: This sample app requires the restricted profile
+ feature.\n\n
+ 1. If this is the primary user, go to Settings > Users.\n\n
+ 2. Create a restricted profile, if one doesn\'t exist already.\n\n
+ 3. Open the profile settings, locate the sample app, and tap the app restriction settings
+ icon. Configure app restrictions for the app.\n\n
+ 4. In the lock screen, switch to the user\'s restricted profile, launch this sample app,
+ and see the configured app restrictions displayed.\n
+ </string>
+ <string name="settings_button_label">Go to Settings</string>
+ <string name="current_app_limits_label">Current app restriction settings:</string>
+ <string name="na">N/A</string>
+ <string name="current_app_limits_description">Your app can restrict its content based on these
+ settings, which can be configured through the primary user\'s Users Settings.
+ </string>
+
+ <string-array name="multi_entry_entries">
+ <item>Ice Cream</item>
+ <item>Jelly Bean</item>
+ <item>More Jelly Bean</item>
+ </string-array>
+
+ <string-array name="multi_entry_values" translateable="false">
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+ <string-array name="choice_entry_entries">
+ <item>Ice Cream</item>
+ <item>Jelly Bean</item>
+ <item>More Jelly Bean</item>
+ </string-array>
+
+ <string-array name="choice_entry_values" translateable="false">
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </string-array>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/xml/custom_prefs.xml b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/xml/custom_prefs.xml
new file mode 100644
index 0000000..5a3cf0d
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/AppRestrictionsSample/src/main/res/xml/custom_prefs.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ android:title="@string/restrictions_activity_label">
+
+ <CheckBoxPreference android:key="pref_boolean"
+ android:title="@string/boolean_entry_title" />
+
+ <ListPreference android:key="pref_choice"
+ android:title="@string/choice_entry_title"
+ android:entries="@array/choice_entry_entries"
+ android:entryValues="@array/choice_entry_values" />
+
+ <MultiSelectListPreference android:key="pref_multi"
+ android:title="@string/multi_entry_title"
+ android:entries="@array/multi_entry_entries"
+ android:entryValues="@array/multi_entry_values" />
+
+</PreferenceScreen>
diff --git a/prebuilts/gradle/AppRestrictions/README.txt b/prebuilts/gradle/AppRestrictions/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/AppRestrictions/build.gradle b/prebuilts/gradle/AppRestrictions/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/AppRestrictions/gradlew b/prebuilts/gradle/AppRestrictions/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/AppRestrictions/gradlew.bat b/prebuilts/gradle/AppRestrictions/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/AppRestrictions/settings.gradle b/prebuilts/gradle/AppRestrictions/settings.gradle
new file mode 100644
index 0000000..02aef49
--- /dev/null
+++ b/prebuilts/gradle/AppRestrictions/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'AppRestrictionsSample'
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/build.gradle b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/build.gradle
new file mode 100644
index 0000000..6bbb9ea
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 11
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..d61d789
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicaccessibility"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="11"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/DialView.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/DialView.java
new file mode 100644
index 0000000..efdb449
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/DialView.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2013 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.basicaccessibility;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Custom view to demonstrate accessibility.
+ *
+ * <p>This view does not use any framework widgets, so does not get any accessibility features
+ * automatically. Instead, we use {@link android.view.accessibility.AccessibilityEvent} to provide accessibility hints to
+ * the OS.
+ *
+ * <p>For example, if TalkBack is enabled, users will be able to receive spoken feedback as they
+ * interact with this view.
+ *
+ * <p>More generally, this view renders a multi-position "dial" that can be used to select a value
+ * between 1 and 4. Each time the dial is clicked, the next position will be selected (modulo
+ * the maximum number of positions).
+ */
+public class DialView extends View {
+ private static int SELECTION_COUNT = 4;
+
+ private static float FONT_SIZE = 40f;
+ private float mWidth;
+ private float mHeight;
+ private float mWidthPadded;
+ private float mHeightPadded;
+ private Paint mTextPaint;
+ private Paint mDialPaint;
+ private float mRadius;
+ private int mActiveSelection;
+
+ /**
+ * Constructor that is called when inflating a view from XML. This is called
+ * when a view is being constructed from an XML file, supplying attributes
+ * that were specified in the XML file.
+ *
+ * <p>In our case, this constructor just calls init().
+ *
+ * @param context The Context the view is running in, through which it can
+ * access the current theme, resources, etc.
+ * @param attrs The attributes of the XML tag that is inflating the view.
+ * @see #View(android.content.Context, android.util.AttributeSet, int)
+ */
+ public DialView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ /**
+ * Helper method to initialize instance variables. Called by constructor.
+ */
+ private void init() {
+ // Paint styles used for rendering are created here, rather than at render-time. This
+ // is a performance optimization, since onDraw() will get called frequently.
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setColor(Color.BLACK);
+ mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+ mTextPaint.setTextAlign(Paint.Align.CENTER);
+ mTextPaint.setTextSize(FONT_SIZE);
+
+ mDialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mDialPaint.setColor(Color.GRAY);
+
+ // Initialize current selection. This will store where the dial's "indicator" is pointing.
+ mActiveSelection = 0;
+
+ // Setup onClick listener for this view. Rotates between each of the different selection
+ // states on each click.
+ //
+ // Notice that we call sendAccessibilityEvent here. Some AccessibilityEvents are generated
+ // by the system. However, custom views will typically need to send events manually as the
+ // user interacts with the view. The type of event sent will vary, depending on the nature
+ // of the view and how the user interacts with it.
+ //
+ // In this case, we are sending TYPE_VIEW_SELECTED rather than TYPE_VIEW_CLICKED, because
+ // clicking on this view selects a new value.
+ //
+ // We will give our AccessibilityEvent further information about the state of the view in
+ // onPopulateAccessibilityEvent(), which will be called automatically by the system
+ // for each AccessibilityEvent.
+ setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // Rotate selection to the next valid choice.
+ mActiveSelection = (mActiveSelection + 1) % SELECTION_COUNT;
+ // Send an AccessibilityEvent, since the user has interacted with the view.
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ // Redraw the entire view. (Inefficient, but this is sufficient for demonstration
+ // purposes.)
+ invalidate();
+ }
+ });
+ }
+
+ /**
+ * This is where a View should populate outgoing accessibility events with its text content.
+ * While this method is free to modify event attributes other than text content, doing so
+ * should normally be performed in
+ * {@link #onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)}.
+ * <p/>
+ * <p>Note that the behavior of this method will typically vary, depending on the type of
+ * accessibility event is passed into it. The allowed values also very, and are documented
+ * in {@link android.view.accessibility.AccessibilityEvent}.
+ * <p/>
+ * <p>Typically, this is where you'll describe the state of your custom view. You may also
+ * want to provide custom directions when the user has focused your view.
+ *
+ * @param event The accessibility event which to populate.
+ */
+ // BEGIN_INCLUDE (on_populate_accessibility_event)
+ @Override
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+ super.onPopulateAccessibilityEvent(event);
+
+ // Detect what type of accessibility event is being passed in.
+ int eventType = event.getEventType();
+
+ // Common case: The user has interacted with our view in some way. State may or may not
+ // have been changed. Read out the current status of the view.
+ //
+ // We also set some other metadata which is not used by TalkBack, but could be used by
+ // other TTS engines.
+ if (eventType == AccessibilityEvent.TYPE_VIEW_SELECTED ||
+ eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
+ event.getText().add("Mode selected: " + Integer.toString(mActiveSelection + 1) + ".");
+ event.setItemCount(SELECTION_COUNT);
+ event.setCurrentItemIndex(mActiveSelection);
+ }
+
+ // When a user first focuses on our view, we'll also read out some simple instructions to
+ // make it clear that this is an interactive element.
+ if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
+ event.getText().add("Tap to change.");
+ }
+ }
+ // END_INCLUDE (on_populate_accessibility_event)
+
+ /**
+ * This is called during layout when the size of this view has changed. If
+ * you were just added to the view hierarchy, you're called with the old
+ * values of 0.
+ *
+ * <p>This is where we determine the drawing bounds for our custom view.
+ *
+ * @param w Current width of this view.
+ * @param h Current height of this view.
+ * @param oldw Old width of this view.
+ * @param oldh Old height of this view.
+ */
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ // Account for padding
+ float xPadding = (float) (getPaddingLeft() + getPaddingRight());
+ float yPadding = (float) (getPaddingTop() + getPaddingBottom());
+
+ // Compute available width/height
+ mWidth = w;
+ mHeight = h;
+ mWidthPadded = w - xPadding;
+ mHeightPadded = h - yPadding;
+ mRadius = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);
+ }
+
+ /**
+ * Render view content.
+ *
+ * <p>We render an outer grey circle to serve as our "dial", and then render a smaller black
+ * circle to server as our indicator. The position for the indicator is determined based
+ * on mActiveSelection.
+ *
+ * @param canvas the canvas on which the background will be drawn
+ */
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ // Draw dial
+ canvas.drawCircle(mWidth / 2, mHeight / 2, (float) mRadius, mDialPaint);
+
+ // Draw text labels
+ final float labelRadius = mRadius + 10;
+ for (int i = 0; i < SELECTION_COUNT; i++) {
+ float[] xyData = computeXYForPosition(i, labelRadius);
+ float x = xyData[0];
+ float y = xyData[1];
+ canvas.drawText(Integer.toString(i + 1), x, y, mTextPaint);
+ }
+
+ // Draw indicator mark
+ final float markerRadius = mRadius - 35;
+ float[] xyData = computeXYForPosition(mActiveSelection, markerRadius);
+ float x = xyData[0];
+ float y = xyData[1];
+ canvas.drawCircle(x, y, 20, mTextPaint);
+ }
+
+ /**
+ * Compute the X/Y-coordinates for a label or indicator, given the position number and radius
+ * where the label should be drawn.
+ *
+ * @param pos Zero based position index
+ * @param radius Radius where label/indicator is to be drawn.
+ * @return 2-element array. Element 0 is X-coordinate, element 1 is Y-coordinate.
+ */
+ private float[] computeXYForPosition(final int pos, final float radius) {
+ float[] result = new float[2];
+ Double startAngle = Math.PI * (9 / 8d); // Angles are in radiansq
+ Double angle = startAngle + (pos * (Math.PI / 4));
+ result[0] = (float) (radius * Math.cos(angle)) + (mWidth / 2);
+ result[1] = (float) (radius * Math.sin(angle)) + (mHeight / 2);
+ return result;
+ }
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/MainActivity.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/MainActivity.java
new file mode 100644
index 0000000..2777ad7
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/basicaccessibility/MainActivity.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 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.basicaccessibility;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Basic activity class.
+ *
+ * <p>Responsible for rendering layout, and displaying some toasts to give buttons feedback.
+ * There's nothing terribly interesting in this class. All the interesting stuff is in
+ * res/layout/activity_main.xml and {@link DialView}.
+ */
+public class MainActivity extends Activity {
+
+ /**
+ * Standard onCreate() implementation. Sets R.layout.activity_main as the layout.
+ */
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+ }
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_discard.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_discard.png
new file mode 100644
index 0000000..ece5ad8
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_discard.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_info.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_info.png
new file mode 100644
index 0000000..da65dea
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_action_info.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..6c0b5ee
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/partly_cloudy.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/partly_cloudy.png
new file mode 100644
index 0000000..b1b380c
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/partly_cloudy.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_discard.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_discard.png
new file mode 100644
index 0000000..93483b6
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_discard.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_info.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_info.png
new file mode 100644
index 0000000..7f7e0a3
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_action_info.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..4ce0b82
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_discard.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_discard.png
new file mode 100644
index 0000000..94f7c8c
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_discard.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_info.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_info.png
new file mode 100644
index 0000000..4ede9ce
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_action_info.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ded707
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..74ae891
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..64f4f38
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,206 @@
+<!--
+Copyright (C) 2013 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center_horizontal">
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="false">
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity"
+ >
+
+ <!-- Notice the presence of nextFocusDown/nextFocusUp on the elements below. You can
+ also use nextFocusLeft/nextFocusRight. This tells the system in what order elements
+ should be navigated through. If not present, the system will make a guess based on
+ element location in the layout. -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Buttons"
+ android:id="@+id/buttonsLabel"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentLeft="true"
+ android:nextFocusDown="@+id/composeButton"/>
+
+ <!-- This is a regular, text-based button. No contentDescription is needed, since the
+ text field sufficiently describes the action performed. -->
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/composeButtonLabel"
+ android:id="@+id/composeButton"
+ android:layout_below="@+id/buttonsLabel"
+ android:layout_alignLeft="@+id/buttonsLabel"
+ android:nextFocusUp="@+id/buttonsLabel"
+ android:nextFocusDown="@+id/checkboxesLabel"
+ />
+
+ <!-- The next two buttons are different types of image-based buttons. -->
+
+ <!-- BEGIN_INCLUDE (image_content_description) -->
+ <!-- Adding a contentDescription is needed for accessibility, since no text is present.
+ Since the contentDescription is read verbatim, you may want to be a bit more
+ descriptive than usual, such as adding "button" to the end of your description, if
+ appropriate. -->
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/discardButton"
+ android:layout_alignTop="@+id/composeButton"
+ android:layout_toRightOf="@+id/composeButton"
+ android:src="@drawable/ic_action_discard"
+ android:layout_alignBottom="@+id/composeButton"
+ android:contentDescription="@string/discardButtonDescription"
+ android:scaleType="fitCenter"
+ android:nextFocusUp="@+id/buttonsLabel"
+ android:nextFocusDown="@+id/checkboxesLabel"
+ />
+ <!-- END_INCLUDE (image_content_description) -->
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/infoButton"
+ android:layout_alignTop="@+id/discardButton"
+ android:layout_toRightOf="@+id/discardButton"
+ android:src="@drawable/ic_action_info"
+ android:layout_alignBottom="@+id/discardButton"
+ android:layout_alignRight="@+id/hyperspaceCheckbox"
+ android:scaleType="fitCenter"
+ android:background="?android:selectableItemBackground"
+ android:padding="5dp"
+ android:contentDescription="@string/infoButtonDescription"
+ android:nextFocusUp="@+id/buttonsLabel"
+ android:nextFocusDown="@+id/checkboxesLabel"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/checkboxesLabel"
+ android:id="@+id/checkboxesLabel"
+ android:layout_below="@+id/composeButton"
+ android:layout_alignLeft="@+id/composeButton"
+ android:nextFocusUp="@+id/composeButton"
+ android:nextFocusDown="@+id/jetpackCheckbox"
+ />
+
+ <!-- Like a text-based button, checkboxes with text will often work correctly as-is.
+ If your checkboxes do not have a text attribute, you will need to add a
+ contentDescriptoin. -->
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/jetpackCheckboxLabel"
+ android:id="@+id/jetpackCheckbox"
+ android:layout_below="@+id/checkboxesLabel"
+ android:layout_alignLeft="@+id/checkboxesLabel"
+ android:checked="false"
+ android:nextFocusUp="@+id/checkboxesLabel"
+ android:nextFocusDown="@+id/hyperspaceCheckbox"
+ />
+
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hyperspaceCheckboxLabel"
+ android:id="@+id/hyperspaceCheckbox"
+ android:layout_below="@+id/jetpackCheckbox"
+ android:layout_alignLeft="@+id/jetpackCheckbox"
+ android:checked="false"
+ android:nextFocusUp="@+id/jetpackCheckbox"
+ android:nextFocusDown="@+id/imagesAndTextLabel"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/imagesAndTextLabel"
+ android:id="@+id/imagesAndTextLabel"
+ android:layout_below="@+id/hyperspaceCheckbox"
+ android:layout_alignLeft="@+id/hyperspaceCheckbox"
+ android:nextFocusUp="@+id/hyperspaceCheckbox"
+ android:nextFocusDown="@+id/partlyCloudImage"
+ />
+
+ <!-- Images should have a contentDescription if they convey any meaningful
+ information. Images that are purely decorative may not need a contentDescription,
+ however. -->
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/partlyCloudyImage"
+ android:layout_below="@+id/imagesAndTextLabel"
+ android:layout_alignLeft="@+id/imagesAndTextLabel"
+ android:src="@drawable/partly_cloudy"
+ android:contentDescription="@string/partlyCloudyDescription"
+ android:layout_alignRight="@+id/discardButton"
+ android:nextFocusUp="@+id/imagesAndTextLabel"
+ android:nextFocusDown="@+id/customViewLabel"
+ />
+
+ <!-- TextViews are typically self describing, so do not need extra modifications. -->
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="@string/temperature"
+ android:textSize="60sp"
+ android:id="@+id/temperatureText"
+ android:layout_alignTop="@+id/partlyCloudyImage"
+ android:layout_toRightOf="@+id/partlyCloudyImage"
+ android:layout_alignBottom="@+id/partlyCloudyImage"
+ android:gravity="center_vertical"
+ android:nextFocusUp="@+id/imagesAndTextLabel"
+ android:nextFocusDown="@+id/customViewLabel"
+ />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/customViewLabel"
+ android:id="@+id/customViewLabel"
+ android:layout_below="@+id/partlyCloudyImage"
+ android:layout_alignLeft="@+id/partlyCloudyImage"
+ android:nextFocusUp="@+id/partlyCloudImage"
+ android:nextFocusDown="@+id/dialView"
+ />
+
+ <!-- Custom views require additonal code changes. See DialView.java for more
+ details. -->
+ <com.example.android.basicaccessibility.DialView
+ android:layout_width="200dp"
+ android:layout_height="200dp"
+ android:id="@+id/dialView"
+ android:layout_below="@+id/customViewLabel"
+ android:layout_alignLeft="@+id/partlyCloudyImage"
+ android:nextFocusUp="@+id/customViewLabel"
+ />
+
+ </RelativeLayout>
+ </ScrollView>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..2c2d431
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+Copyright (C) 2013 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.
+-->
+
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..20790c7
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicAccessibility</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to create an accessible application, using a mix of different widgets demonstrating different ways of adding accessibility markup to a UI.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/dimens.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..a5e4ebe
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<!--
+Copyright (C) 2013 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.
+-->
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8340682
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2013 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.
+-->
+
+<resources>
+ <string name="composeButtonPressed">(Compose button pressed.)</string>
+ <string name="discardButtonPressed">(Discard button pressed.)</string>
+ <string name="infoButtonPressed">(Info button pressed.)</string>
+ <string name="composeButtonLabel">Compose</string>
+ <string name="discardButtonDescription">Discard Button</string>
+ <string name="infoButtonDescription">Info Button</string>
+ <string name="partlyCloudyDescription">Partly Cloudy</string>
+ <string name="checkboxesLabel">Checkboxes</string>
+ <string name="jetpackCheckboxLabel">Enable Jetpack</string>
+ <string name="hyperspaceCheckboxLabel">Enable Hyperspace Engines</string>
+ <string name="imagesAndTextLabel">Images & Text</string>
+ <string name="temperature">53 °F</string>
+ <string name="customViewLabel">Custom View</string>
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8dc47be
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicaccessibility.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicaccessibility"
+ android:label="Tests for com.example.android.basicaccessibility" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/src/com/example/android/basicaccessibility/tests/SampleTests.java b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/src/com/example/android/basicaccessibility/tests/SampleTests.java
new file mode 100644
index 0000000..0c9a152
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/BasicAccessibilitySample/tests/src/com/example/android/basicaccessibility/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicaccessibility.tests;
+
+import com.example.android.basicaccessibility.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicAccessibility sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicAccessibilityFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicAccessibilityFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAccessibility/README.txt b/prebuilts/gradle/BasicAccessibility/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicAccessibility/build.gradle b/prebuilts/gradle/BasicAccessibility/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicAccessibility/gradlew b/prebuilts/gradle/BasicAccessibility/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicAccessibility/gradlew.bat b/prebuilts/gradle/BasicAccessibility/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicAccessibility/settings.gradle b/prebuilts/gradle/BasicAccessibility/settings.gradle
new file mode 100644
index 0000000..7900b3d
--- /dev/null
+++ b/prebuilts/gradle/BasicAccessibility/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicAccessibilitySample'
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/build.gradle b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/build.gradle
new file mode 100644
index 0000000..7bfc9ad
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 18
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..28d256c
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicandroidkeystore"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="18" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java
new file mode 100644
index 0000000..12873e8
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/BasicAndroidKeyStoreFragment.java
@@ -0,0 +1,327 @@
+/*
+* Copyright (C) 2013 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.basicandroidkeystore;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.security.KeyPairGeneratorSpec;
+import android.support.v4.app.Fragment;
+import android.util.Base64;
+import android.view.MenuItem;
+
+import com.example.android.common.logger.Log;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.CertificateException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import javax.security.auth.x500.X500Principal;
+
+public class BasicAndroidKeyStoreFragment extends Fragment {
+
+ public static final String TAG = "BasicAndroidKeyStoreFragment";
+
+ // BEGIN_INCLUDE(values)
+
+ public static final String SAMPLE_ALIAS = "myKey";
+
+ // Some sample data to sign, and later verify using the generated signature.
+ public static final String SAMPLE_INPUT="Hello, Android!";
+
+ // Just a handy place to store the signature in between signing and verifying.
+ public String mSignatureStr = null;
+
+ // You can store multiple key pairs in the Key Store. The string used to refer to the Key you
+ // want to store, or later pull, is referred to as an "alias" in this case, because calling it
+ // a key, when you use it to retrieve a key, would just be irritating.
+ private String mAlias = null;
+
+ // END_INCLUDE(values)
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ setAlias(SAMPLE_ALIAS);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.btn_create_keys:
+ try {
+ createKeys(getActivity());
+ Log.d(TAG, "Keys created");
+ return true;
+ } catch (NoSuchAlgorithmException e) {
+ Log.w(TAG, "RSA not supported", e);
+ } catch (InvalidAlgorithmParameterException e) {
+ Log.w(TAG, "No such provider: AndroidKeyStore");
+ } catch (NoSuchProviderException e) {
+ Log.w(TAG, "Invalid Algorithm Parameter Exception", e);
+ }
+ return true;
+ case R.id.btn_sign_data:
+ try {
+ mSignatureStr = signData(SAMPLE_INPUT);
+ } catch (KeyStoreException e) {
+ Log.w(TAG, "KeyStore not Initialized", e);
+ } catch (UnrecoverableEntryException e) {
+ Log.w(TAG, "KeyPair not recovered", e);
+ } catch (NoSuchAlgorithmException e) {
+ Log.w(TAG, "RSA not supported", e);
+ } catch (InvalidKeyException e) {
+ Log.w(TAG, "Invalid Key", e);
+ } catch (SignatureException e) {
+ Log.w(TAG, "Invalid Signature", e);
+ } catch (IOException e) {
+ Log.w(TAG, "IO Exception", e);
+ } catch (CertificateException e) {
+ Log.w(TAG, "Error occurred while loading certificates", e);
+ }
+ Log.d(TAG, "Signature: " + mSignatureStr);
+ return true;
+
+ case R.id.btn_verify_data:
+ boolean verified = false;
+ try {
+ if (mSignatureStr != null) {
+ verified = verifyData(SAMPLE_INPUT, mSignatureStr);
+ }
+ } catch (KeyStoreException e) {
+ Log.w(TAG, "KeyStore not Initialized", e);
+ } catch (CertificateException e) {
+ Log.w(TAG, "Error occurred while loading certificates", e);
+ } catch (NoSuchAlgorithmException e) {
+ Log.w(TAG, "RSA not supported", e);
+ } catch (IOException e) {
+ Log.w(TAG, "IO Exception", e);
+ } catch (UnrecoverableEntryException e) {
+ Log.w(TAG, "KeyPair not recovered", e);
+ } catch (InvalidKeyException e) {
+ Log.w(TAG, "Invalid Key", e);
+ } catch (SignatureException e) {
+ Log.w(TAG, "Invalid Signature", e);
+ }
+ if (verified) {
+ Log.d(TAG, "Data Signature Verified");
+ } else {
+ Log.d(TAG, "Data not verified.");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Creates a public and private key and stores it using the Android Key Store, so that only
+ * this application will be able to access the keys.
+ */
+ public void createKeys(Context context) throws NoSuchProviderException,
+ NoSuchAlgorithmException, InvalidAlgorithmParameterException {
+ // BEGIN_INCLUDE(create_valid_dates)
+ // Create a start and end time, for the validity range of the key pair that's about to be
+ // generated.
+ Calendar start = new GregorianCalendar();
+ Calendar end = new GregorianCalendar();
+ end.add(1, Calendar.YEAR);
+ //END_INCLUDE(create_valid_dates)
+
+
+ // BEGIN_INCLUDE(create_spec)
+ // The KeyPairGeneratorSpec object is how parameters for your key pair are passed
+ // to the KeyPairGenerator. For a fun home game, count how many classes in this sample
+ // start with the phrase "KeyPair".
+ KeyPairGeneratorSpec spec =
+ new KeyPairGeneratorSpec.Builder(context)
+ // You'll use the alias later to retrieve the key. It's a key for the key!
+ .setAlias(mAlias)
+ // The subject used for the self-signed certificate of the generated pair
+ .setSubject(new X500Principal("CN=" + mAlias))
+ // The serial number used for the self-signed certificate of the
+ // generated pair.
+ .setSerialNumber(BigInteger.valueOf(1337))
+ // Date range of validity for the generated pair.
+ .setStartDate(start.getTime())
+ .setEndDate(end.getTime())
+ .build();
+ // END_INCLUDE(create_spec)
+
+ // BEGIN_INCLUDE(create_keypair)
+ // Initialize a KeyPair generator using the the intended algorithm (in this example, RSA
+ // and the KeyStore. This example uses the AndroidKeyStore.
+ KeyPairGenerator kpGenerator = KeyPairGenerator
+ .getInstance(SecurityConstants.TYPE_RSA,
+ SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
+ kpGenerator.initialize(spec);
+ KeyPair kp = kpGenerator.generateKeyPair();
+ Log.d(TAG, "Public Key is: " + kp.getPublic().toString());
+ // END_INCLUDE(create_keypair)
+ }
+
+ /**
+ * Signs the data using the key pair stored in the Android Key Store. This signature can be
+ * used with the data later to verify it was signed by this application.
+ * @return A string encoding of the data signature generated
+ */
+ public String signData(String inputStr) throws KeyStoreException,
+ UnrecoverableEntryException, NoSuchAlgorithmException, InvalidKeyException,
+ SignatureException, IOException, CertificateException {
+ byte[] data = inputStr.getBytes();
+
+ // BEGIN_INCLUDE(sign_load_keystore)
+ KeyStore ks = KeyStore.getInstance(SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE);
+
+ // Weird artifact of Java API. If you don't have an InputStream to load, you still need
+ // to call "load", or it'll crash.
+ ks.load(null);
+
+ // Load the key pair from the Android Key Store
+ KeyStore.Entry entry = ks.getEntry(mAlias, null);
+
+ /* If the entry is null, keys were never stored under this alias.
+ * Debug steps in this situation would be:
+ * -Check the list of aliases by iterating over Keystore.aliases(), be sure the alias
+ * exists.
+ * -If that's empty, verify they were both stored and pulled from the same keystore
+ * "AndroidKeyStore"
+ */
+ if (entry == null) {
+ Log.w(TAG, "No key found under alias: " + mAlias);
+ Log.w(TAG, "Exiting signData()...");
+ return null;
+ }
+
+ /* If entry is not a KeyStore.PrivateKeyEntry, it might have gotten stored in a previous
+ * iteration of your application that was using some other mechanism, or been overwritten
+ * by something else using the same keystore with the same alias.
+ * You can determine the type using entry.getClass() and debug from there.
+ */
+ if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
+ Log.w(TAG, "Not an instance of a PrivateKeyEntry");
+ Log.w(TAG, "Exiting signData()...");
+ return null;
+ }
+ // END_INCLUDE(sign_data)
+
+ // BEGIN_INCLUDE(sign_create_signature)
+ // This class doesn't actually represent the signature,
+ // just the engine for creating/verifying signatures, using
+ // the specified algorithm.
+ Signature s = Signature.getInstance(SecurityConstants.SIGNATURE_SHA256withRSA);
+
+ // Initialize Signature using specified private key
+ s.initSign(((KeyStore.PrivateKeyEntry) entry).getPrivateKey());
+
+ // Sign the data, store the result as a Base64 encoded String.
+ s.update(data);
+ byte[] signature = s.sign();
+ String result = Base64.encodeToString(signature, Base64.DEFAULT);
+ // END_INCLUDE(sign_data)
+
+ return result;
+ }
+
+ /**
+ * Given some data and a signature, uses the key pair stored in the Android Key Store to verify
+ * that the data was signed by this application, using that key pair.
+ * @param input The data to be verified.
+ * @param signatureStr The signature provided for the data.
+ * @return A boolean value telling you whether the signature is valid or not.
+ */
+ public boolean verifyData(String input, String signatureStr) throws KeyStoreException,
+ CertificateException, NoSuchAlgorithmException, IOException,
+ UnrecoverableEntryException, InvalidKeyException, SignatureException {
+ byte[] data = input.getBytes();
+ byte[] signature;
+ // BEGIN_INCLUDE(decode_signature)
+
+ // Make sure the signature string exists. If not, bail out, nothing to do.
+
+ if (signatureStr == null) {
+ Log.w(TAG, "Invalid signature.");
+ Log.w(TAG, "Exiting verifyData()...");
+ return false;
+ }
+
+ try {
+ // The signature is going to be examined as a byte array,
+ // not as a base64 encoded string.
+ signature = Base64.decode(signatureStr, Base64.DEFAULT);
+ } catch (IllegalArgumentException e) {
+ // signatureStr wasn't null, but might not have been encoded properly.
+ // It's not a valid Base64 string.
+ return false;
+ }
+ // END_INCLUDE(decode_signature)
+
+ KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
+
+ // Weird artifact of Java API. If you don't have an InputStream to load, you still need
+ // to call "load", or it'll crash.
+ ks.load(null);
+
+ // Load the key pair from the Android Key Store
+ KeyStore.Entry entry = ks.getEntry(mAlias, null);
+
+ if (entry == null) {
+ Log.w(TAG, "No key found under alias: " + mAlias);
+ Log.w(TAG, "Exiting verifyData()...");
+ return false;
+ }
+
+ if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
+ Log.w(TAG, "Not an instance of a PrivateKeyEntry");
+ return false;
+ }
+
+ // This class doesn't actually represent the signature,
+ // just the engine for creating/verifying signatures, using
+ // the specified algorithm.
+ Signature s = Signature.getInstance(SecurityConstants.SIGNATURE_SHA256withRSA);
+
+ // BEGIN_INCLUDE(verify_data)
+ // Verify the data.
+ s.initVerify(((KeyStore.PrivateKeyEntry) entry).getCertificate());
+ s.update(data);
+ boolean valid = s.verify(signature);
+ return valid;
+ // END_INCLUDE(verify_data)
+ }
+
+ public void setAlias(String alias) {
+ mAlias = alias;
+ }
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/MainActivity.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/MainActivity.java
new file mode 100644
index 0000000..7711f35
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/MainActivity.java
@@ -0,0 +1,81 @@
+/*
+* Copyright 2013 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.basicandroidkeystore;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "BasicAndroidKeyStoreFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ BasicAndroidKeyStoreFragment fragment = new BasicAndroidKeyStoreFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+ logFragment.getLogView().setTextAppearance(this, R.style.Log);
+ logFragment.getLogView().setBackgroundColor(Color.WHITE);
+
+ Log.i(TAG, "Ready");
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/SecurityConstants.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/SecurityConstants.java
new file mode 100644
index 0000000..ea5ee30
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/basicandroidkeystore/SecurityConstants.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2013 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.basicandroidkeystore;
+
+/**
+ * Helper class, contains several constants used when encrypting/decrypting data on Android.
+ * This class should not be considered a complete list of the algorithms, keystore types,
+ * or signature types within the Android Platform, only the more common ones.
+ */
+public class SecurityConstants {
+ public static final String KEYSTORE_PROVIDER_ANDROID_KEYSTORE = "AndroidKeyStore";
+
+ public static final String TYPE_RSA = "RSA";
+ public static final String TYPE_DSA = "DSA";
+ public static final String TYPE_BKS = "BKS";
+
+ public static final String SIGNATURE_SHA256withRSA = "SHA256withRSA";
+ public static final String SIGNATURE_SHA512withRSA = "SHA512withRSA";
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp-land/activity_main.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp-land/activity_main.xml
new file mode 100644
index 0000000..653454b
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp-land/activity_main.xml
@@ -0,0 +1,37 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:background="@android:color/white"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message"
+ android:layout_margin="16dp" />
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp/activity_main.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp/activity_main.xml
new file mode 100644
index 0000000..11cd71b
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout-sw600dp/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:background="@android:color/white"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_message"
+ android:padding="16dp"
+ android:layout_margin="16dp"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="16dp" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..6f41369
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,39 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message"
+ android:padding="16dp" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..74435ca
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/menu/main.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/btn_create_keys"
+ android:showAsAction="always"
+ android:title="@string/str_create_keys" />
+
+ <item android:id="@+id/btn_sign_data"
+ android:showAsAction="always"
+ android:title="@string/str_sign_data" />
+
+ <item android:id="@+id/btn_verify_data"
+ android:showAsAction="always"
+ android:title="@string/str_verify_data" />
+
+</menu>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..0699a4a
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicAndroidKeyStore</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ Welcome to the <b>Basic Android Key Store</b> sample!\n\n
+ This sample demonstrates how to use the Android Key Store to safely create and store
+ encryption keys that only your application can access. You can also sign data
+ using those keys.\n\n
+ To create a new KeyPair, click \"Create\".\n\n
+ To sign some data using a KeyPair, click \"Sign\".\n\n
+ To verify the data using the signature provided, click \"Verify\".\n\n
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..25ad389
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="str_create_keys">Create</string>
+ <string name="str_sign_data">Sign</string>
+ <string name="str_verify_data">Verify</string>
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..cfffcbd
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,54 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ <item name="android:layout_margin">16dp</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..eb8b7b8
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicandroidkeystore.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicandroidkeystore"
+ android:label="Tests for com.example.android.basicandroidkeystore" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/src/com/example/android/basicandroidkeystore/tests/SampleTests.java b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/src/com/example/android/basicandroidkeystore/tests/SampleTests.java
new file mode 100644
index 0000000..756b605
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/BasicAndroidKeyStoreSample/tests/src/com/example/android/basicandroidkeystore/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicandroidkeystore.tests;
+
+import com.example.android.basicandroidkeystore.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicAndroidKeyStore sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicAndroidKeyStoreFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicAndroidKeyStoreFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/README.txt b/prebuilts/gradle/BasicAndroidKeyStore/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/build.gradle b/prebuilts/gradle/BasicAndroidKeyStore/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/gradlew b/prebuilts/gradle/BasicAndroidKeyStore/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/gradlew.bat b/prebuilts/gradle/BasicAndroidKeyStore/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicAndroidKeyStore/settings.gradle b/prebuilts/gradle/BasicAndroidKeyStore/settings.gradle
new file mode 100644
index 0000000..e4b36fe
--- /dev/null
+++ b/prebuilts/gradle/BasicAndroidKeyStore/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicAndroidKeyStoreSample'
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/build.gradle b/prebuilts/gradle/BasicContactables/BasicContactablesSample/build.gradle
new file mode 100644
index 0000000..7bfc9ad
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 18
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..62b9812
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/AndroidManifest.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basiccontactables"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <!-- BEGIN_INCLUDE(contacts_permission) -->
+ <uses-permission android:name="android.permission.READ_CONTACTS"/>
+ <!-- END_INCLUDE(contacts_permission) -->
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="18" />
+ <permission android:name="android"></permission>
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/Theme.Sample" >
+ <activity
+ android:name="com.example.android.basiccontactables.MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTop">
+ <meta-data
+ android:name="android.app.searchable"
+ android:resource="@xml/searchable" />
+ <intent-filter>
+ <action android:name="android.intent.action.SEARCH" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/ContactablesLoaderCallbacks.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/ContactablesLoaderCallbacks.java
new file mode 100644
index 0000000..4fc4da7
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/ContactablesLoaderCallbacks.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 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.basiccontactables;
+
+import android.app.Activity;
+import android.app.LoaderManager;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.util.Log;
+import android.widget.TextView;
+
+/**
+ * Helper class to handle all the callbacks that occur when interacting with loaders. Most of the
+ * interesting code in this sample app will be in this file.
+ */
+public class ContactablesLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
+
+ Context mContext;
+
+ public static final String QUERY_KEY = "query";
+
+ public static final String TAG = "ContactablesLoaderCallbacks";
+
+ public ContactablesLoaderCallbacks(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int loaderIndex, Bundle args) {
+ // Where the Contactables table excels is matching text queries,
+ // not just data dumps from Contacts db. One search term is used to query
+ // display name, email address and phone number. In this case, the query was extracted
+ // from an incoming intent in the handleIntent() method, via the
+ // intent.getStringExtra() method.
+
+ // BEGIN_INCLUDE(uri_with_query)
+ String query = args.getString(QUERY_KEY);
+ Uri uri = Uri.withAppendedPath(
+ CommonDataKinds.Contactables.CONTENT_FILTER_URI, query);
+ // END_INCLUDE(uri_with_query)
+
+
+ // BEGIN_INCLUDE(cursor_loader)
+ // Easy way to limit the query to contacts with phone numbers.
+ String selection =
+ CommonDataKinds.Contactables.HAS_PHONE_NUMBER + " = " + 1;
+
+ // Sort results such that rows for the same contact stay together.
+ String sortBy = CommonDataKinds.Contactables.LOOKUP_KEY;
+
+ return new CursorLoader(
+ mContext, // Context
+ uri, // URI representing the table/resource to be queried
+ null, // projection - the list of columns to return. Null means "all"
+ selection, // selection - Which rows to return (condition rows must match)
+ null, // selection args - can be provided separately and subbed into selection.
+ sortBy); // string specifying sort order
+ // END_INCLUDE(cursor_loader)
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
+ TextView tv = (TextView) ((Activity)mContext).findViewById(R.id.sample_output);
+ if(tv == null) {
+ Log.e(TAG, "TextView is null?!");
+ } else if (mContext == null) {
+ Log.e(TAG, "Context is null?");
+ } else {
+ Log.e(TAG, "Nothing is null?!");
+ }
+
+ // Reset text in case of a previous query
+ tv.setText(mContext.getText(R.string.intro_message) + "\n\n");
+
+ if (cursor.getCount() == 0) {
+ return;
+ }
+
+ // Pulling the relevant value from the cursor requires knowing the column index to pull
+ // it from.
+ // BEGIN_INCLUDE(get_columns)
+ int phoneColumnIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
+ int emailColumnIndex = cursor.getColumnIndex(CommonDataKinds.Email.ADDRESS);
+ int nameColumnIndex = cursor.getColumnIndex(CommonDataKinds.Contactables.DISPLAY_NAME);
+ int lookupColumnIndex = cursor.getColumnIndex(CommonDataKinds.Contactables.LOOKUP_KEY);
+ int typeColumnIndex = cursor.getColumnIndex(CommonDataKinds.Contactables.MIMETYPE);
+ // END_INCLUDE(get_columns)
+
+ cursor.moveToFirst();
+ // Lookup key is the easiest way to verify a row of data is for the same
+ // contact as the previous row.
+ String lookupKey = "";
+ do {
+ // BEGIN_INCLUDE(lookup_key)
+ String currentLookupKey = cursor.getString(lookupColumnIndex);
+ if (!lookupKey.equals(currentLookupKey)) {
+ String displayName = cursor.getString(nameColumnIndex);
+ tv.append(displayName + "\n");
+ lookupKey = currentLookupKey;
+ }
+ // END_INCLUDE(lookup_key)
+
+ // BEGIN_INCLUDE(retrieve_data)
+ // The data type can be determined using the mime type column.
+ String mimeType = cursor.getString(typeColumnIndex);
+ if (mimeType.equals(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
+ tv.append("\tPhone Number: " + cursor.getString(phoneColumnIndex) + "\n");
+ } else if (mimeType.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
+ tv.append("\tEmail Address: " + cursor.getString(emailColumnIndex) + "\n");
+ }
+ // END_INCLUDE(retrieve_data)
+
+ // Look at DDMS to see all the columns returned by a query to Contactables.
+ // Behold, the firehose!
+ for(String column : cursor.getColumnNames()) {
+ Log.d(TAG, column + column + ": " +
+ cursor.getString(cursor.getColumnIndex(column)) + "\n");
+ }
+ } while (cursor.moveToNext());
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> cursorLoader) {
+ }
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/MainActivity.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/MainActivity.java
new file mode 100644
index 0000000..b8b074e
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/basiccontactables/MainActivity.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2012 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.basiccontactables;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.Menu;
+import android.widget.SearchView;
+
+/**
+ * Simple one-activity app that takes a search term via the Action Bar
+ * and uses it as a query to search the contacts database via the Contactables
+ * table.
+ */
+public class MainActivity extends Activity {
+
+ public static final int CONTACT_QUERY_LOADER = 0;
+ public static final String QUERY_KEY = "query";
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ if (getIntent() != null) {
+ handleIntent(getIntent());
+ }
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ handleIntent(intent);
+ }
+
+ /**
+ * Assuming this activity was started with a new intent, process the incoming information and
+ * react accordingly.
+ * @param intent
+ */
+ private void handleIntent(Intent intent) {
+ // Special processing of the incoming intent only occurs if the if the action specified
+ // by the intent is ACTION_SEARCH.
+ if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
+ // SearchManager.QUERY is the key that a SearchManager will use to send a query string
+ // to an Activity.
+ String query = intent.getStringExtra(SearchManager.QUERY);
+
+ // We need to create a bundle containing the query string to send along to the
+ // LoaderManager, which will be handling querying the database and returning results.
+ Bundle bundle = new Bundle();
+ bundle.putString(QUERY_KEY, query);
+
+ ContactablesLoaderCallbacks loaderCallbacks = new ContactablesLoaderCallbacks(this);
+
+ // Start the loader with the new query, and an object that will handle all callbacks.
+ getLoaderManager().restartLoader(CONTACT_QUERY_LOADER, bundle, loaderCallbacks);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.main, menu);
+
+ // Associate searchable configuration with the SearchView
+ SearchManager searchManager =
+ (SearchManager) getSystemService(Context.SEARCH_SERVICE);
+ SearchView searchView =
+ (SearchView) menu.findItem(R.id.search).getActionView();
+ searchView.setSearchableInfo(
+ searchManager.getSearchableInfo(getComponentName()));
+
+ return true;
+ }
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_search_api_holo_light.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_search_api_holo_light.png
new file mode 100644
index 0000000..72e207b
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_search_api_holo_light.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_search_api_holo_light.png
new file mode 100644
index 0000000..f2e26f8
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-mdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_search_api_holo_light.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_search_api_holo_light.png
new file mode 100644
index 0000000..a4cdf1c
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xhdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/sample_main.xml
new file mode 100755
index 0000000..52dc311
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+ -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleOutput"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_message" />
+
+</ScrollView>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..4a530f1
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/menu/main.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/search"
+ android:title="@string/search_title"
+ android:icon="@drawable/ic_search_api_holo_light"
+ android:showAsAction="collapseActionView|ifRoom"
+ android:actionViewClass="android.widget.SearchView" />
+</menu>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..0fc07ef
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicContactables</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to use the Contactables table to search for contacts.
+ \n\nQuery strings sent to the Contactables table will match both contact names and phone numbers,
+ reducing the number of queries your application needs to use when searching the contacts database!
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..a499fd2
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <string name="sample_action">Sample action</string>
+ <string name="search_title">Search Contacts</string>
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/styles.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..c3a400d
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <!-- Widget styling -->
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/xml/searchable.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/xml/searchable.xml
new file mode 100644
index 0000000..32fe1cc
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/src/main/res/xml/searchable.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+ -->
+
+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
+ android:label="@string/app_name"
+ android:hint="@string/search_title" />
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8c4af25
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basiccontactables.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basiccontactables"
+ android:label="Tests for com.example.android.basiccontactables" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/src/com/example/android/basiccontactables/tests/SampleTests.java b/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/src/com/example/android/basiccontactables/tests/SampleTests.java
new file mode 100644
index 0000000..dd48bf2
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/BasicContactablesSample/tests/src/com/example/android/basiccontactables/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basiccontactables.tests;
+
+import com.example.android.basiccontactables.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicContactables sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicContactablesFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicContactablesFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicContactables/README.txt b/prebuilts/gradle/BasicContactables/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicContactables/build.gradle b/prebuilts/gradle/BasicContactables/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicContactables/gradlew b/prebuilts/gradle/BasicContactables/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicContactables/gradlew.bat b/prebuilts/gradle/BasicContactables/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicContactables/settings.gradle b/prebuilts/gradle/BasicContactables/settings.gradle
new file mode 100644
index 0000000..5fec49c
--- /dev/null
+++ b/prebuilts/gradle/BasicContactables/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicContactablesSample'
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/build.gradle b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/build.gradle
new file mode 100644
index 0000000..7bfc9ad
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 18
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1d7b3bd
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicgesturedetect"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/BasicGestureDetectFragment.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/BasicGestureDetectFragment.java
new file mode 100644
index 0000000..820e972
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/BasicGestureDetectFragment.java
@@ -0,0 +1,81 @@
+/*
+* Copyright (C) 2013 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.basicgesturedetect;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.GestureDetector;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+
+public class BasicGestureDetectFragment extends Fragment{
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ View gestureView = getActivity().findViewById(R.id.sample_output);
+ gestureView.setClickable(true);
+ gestureView.setFocusable(true);
+
+ // BEGIN_INCLUDE(init_detector)
+
+ // First create the GestureListener that will include all our callbacks.
+ // Then create the GestureDetector, which takes that listener as an argument.
+ GestureDetector.SimpleOnGestureListener gestureListener = new GestureListener();
+ final GestureDetector gd = new GestureDetector(getActivity(), gestureListener);
+
+ /* For the view where gestures will occur, create an onTouchListener that sends
+ * all motion events to the gesture detector. When the gesture detector
+ * actually detects an event, it will use the callbacks you created in the
+ * SimpleOnGestureListener to alert your application.
+ */
+
+ gestureView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ gd.onTouchEvent(motionEvent);
+ return false;
+ }
+ });
+ // END_INCLUDE(init_detector)
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ clearLog();
+ }
+ return true;
+ }
+
+ public void clearLog() {
+ LogFragment logFragment = ((LogFragment) getActivity().getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment));
+ logFragment.getLogView().setText("");
+ }
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/GestureListener.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/GestureListener.java
new file mode 100644
index 0000000..2e2921d
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/GestureListener.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2013 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.basicgesturedetect;
+
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+
+import com.example.android.common.logger.Log;
+
+public class GestureListener extends GestureDetector.SimpleOnGestureListener {
+
+ public static final String TAG = "GestureListener";
+
+ // BEGIN_INCLUDE(init_gestureListener)
+ @Override
+ public boolean onSingleTapUp(MotionEvent e) {
+ // Up motion completing a single tap occurred.
+ Log.i(TAG, "Single Tap Up");
+ return false;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ // Touch has been long enough to indicate a long press.
+ // Does not indicate motion is complete yet (no up event necessarily)
+ Log.i(TAG, "Long Press");
+ }
+
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
+ float distanceY) {
+ // User attempted to scroll
+ Log.i(TAG, "Scroll");
+ return false;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
+ float velocityY) {
+ // Fling event occurred. Notification of this one happens after an "up" event.
+ Log.i(TAG, "Fling");
+ return false;
+ }
+
+ @Override
+ public void onShowPress(MotionEvent e) {
+ // User performed a down event, and hasn't moved yet.
+ Log.i(TAG, "Show Press");
+ }
+
+ @Override
+ public boolean onDown(MotionEvent e) {
+ // "Down" event - User touched the screen.
+ Log.i(TAG, "Down");
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ // User tapped the screen twice.
+ Log.i(TAG, "Double tap");
+ return false;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent e) {
+ // Since double-tap is actually several events which are considered one aggregate
+ // gesture, there's a separate callback for an individual event within the doubletap
+ // occurring. This occurs for down, up, and move.
+ Log.i(TAG, "Event within double tap");
+ return false;
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ // A confirmed single-tap event has occurred. Only called when the detector has
+ // determined that the first tap stands alone, and is not part of a double tap.
+ Log.i(TAG, "Single tap confirmed");
+ return false;
+ }
+ // END_INCLUDE(init_gestureListener)
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/MainActivity.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/MainActivity.java
new file mode 100644
index 0000000..1547807
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/basicgesturedetect/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.basicgesturedetect;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "BasicGestureDetectFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ BasicGestureDetectFragment fragment = new BasicGestureDetectFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..e9ce7cd
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicGestureDetect</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ Welcome to Basic Gesture Detect!
+ In order to try this sample out, try dragging or tapping this text to see what happens!
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c047c4f
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Clear Text</string>
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..3c5487c
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicgesturedetect.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicgesturedetect"
+ android:label="Tests for com.example.android.basicgesturedetect" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/src/com/example/android/basicgesturedetect/tests/SampleTests.java b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/src/com/example/android/basicgesturedetect/tests/SampleTests.java
new file mode 100644
index 0000000..e72c22e
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/BasicGestureDetectSample/tests/src/com/example/android/basicgesturedetect/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicgesturedetect.tests;
+
+import com.example.android.basicgesturedetect.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicGestureDetect sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicGestureDetectFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicGestureDetectFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicGestureDetect/README.txt b/prebuilts/gradle/BasicGestureDetect/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicGestureDetect/build.gradle b/prebuilts/gradle/BasicGestureDetect/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicGestureDetect/gradlew b/prebuilts/gradle/BasicGestureDetect/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicGestureDetect/gradlew.bat b/prebuilts/gradle/BasicGestureDetect/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicGestureDetect/settings.gradle b/prebuilts/gradle/BasicGestureDetect/settings.gradle
new file mode 100644
index 0000000..ba7e8c0
--- /dev/null
+++ b/prebuilts/gradle/BasicGestureDetect/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicGestureDetectSample'
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/build.gradle b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/build.gradle
new file mode 100644
index 0000000..f73b206
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 19
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..00b4e3c
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicimmersivemode"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/BasicImmersiveModeFragment.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/BasicImmersiveModeFragment.java
new file mode 100644
index 0000000..a675e05
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/BasicImmersiveModeFragment.java
@@ -0,0 +1,88 @@
+/*
+* Copyright (C) 2013 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.basicimmersivemode;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.MenuItem;
+import android.view.View;
+
+import com.example.android.common.logger.Log;
+
+public class BasicImmersiveModeFragment extends Fragment {
+
+ public static final String TAG = "BasicImmersiveModeFragment";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final View decorView = getActivity().getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int i) {
+ int height = decorView.getHeight();
+ Log.i(TAG, "Current height: " + height);
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ toggleHideyBar();
+ }
+ return true;
+ }
+
+ /**
+ * Detects and toggles immersive mode.
+ */
+ public void toggleHideyBar() {
+ // BEGIN_INCLUDE (get_current_ui_flags)
+ // The UI options currently enabled are represented by a bitfield.
+ // getSystemUiVisibility() gives us that bitfield.
+ int uiOptions = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ int newUiOptions = uiOptions;
+ // END_INCLUDE (get_current_ui_flags)
+ // BEGIN_INCLUDE (toggle_ui_flags)
+ boolean isImmersiveModeEnabled =
+ ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
+ if (isImmersiveModeEnabled) {
+ Log.i(TAG, "Turning immersive mode mode off. ");
+ } else {
+ Log.i(TAG, "Turning immersive mode mode on.");
+ }
+
+ // Immersive mode: Backward compatible to KitKat (API 19).
+ // Note that this flag doesn't do anything by itself, it only augments the behavior
+ // of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of this sample
+ // all three flags are being toggled together.
+ // This sample uses the "sticky" form of immersive mode, which will let the user swipe
+ // the bars back in again, but will automatically make them disappear a few seconds later.
+ newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
+ newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ getActivity().getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
+ //END_INCLUDE (set_ui_flags)
+ }
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/MainActivity.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/MainActivity.java
new file mode 100644
index 0000000..83e8f0e
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/basicimmersivemode/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.basicimmersivemode;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "BasicImmersiveModeFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ BasicImmersiveModeFragment fragment = new BasicImmersiveModeFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..20a0647
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicImmersiveMode</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ \"Immersive Mode\" is a new UI mode which improves \"hide full screen\" and
+ \"hide nav bar\" modes, by letting users swipe the bars in and out. This sample
+ demonstrates how to enable and disable immersive mode programmatically.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e845261
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Toggle Immersive Mode!</string>
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..070368c
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicimmersivemode.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicimmersivemode"
+ android:label="Tests for com.example.android.basicimmersivemode" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/src/com/example/android/basicimmersivemode/tests/SampleTests.java b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/src/com/example/android/basicimmersivemode/tests/SampleTests.java
new file mode 100644
index 0000000..31c25bb
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/BasicImmersiveModeSample/tests/src/com/example/android/basicimmersivemode/tests/SampleTests.java
@@ -0,0 +1,124 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+* Copyright (C) 2013 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.basicimmersivemode.tests;
+
+import com.example.android.basicimmersivemode.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+/**
+* Tests for immersive mode sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicImmersiveModeFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicImmersiveModeFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Verify that the UI flags actually changed when the toggle method is called.
+ */
+ @UiThreadTest
+ public void testFlagsChanged() {
+ int uiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ mTestFragment.toggleHideyBar();
+ int newUiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ assertTrue("UI Flags didn't toggle.", uiFlags != newUiFlags);
+ }
+
+ /**
+ * Verify that the view's height actually changed when the toggle method is called.
+ * This should result in a change in height for the DecorView.
+ */
+ public void testDecorHeightExpanded() {
+ // Grab the initial height of the DecorWindow.
+ int startingHeight = getActivity().getWindow().getDecorView().getHeight();
+
+ // In order to test that this worked: Need to toggle the immersive mode on the UI thread,
+ // wait a suitable amount of time (this test goes with 200 ms), then check to see if the
+ // height changed.
+ try {
+ Runnable testRunnable = (new Runnable() {
+ public void run() {
+ // Toggle immersive mode
+ mTestFragment.toggleHideyBar();
+ synchronized(this) {
+ // Notify any thread waiting on this runnable that it can continue
+ this.notify();
+ }
+ }
+ });
+ synchronized(testRunnable) {
+ // Since toggling immersive mode makes changes to the view heirarchy, it needs to run
+ // on the UI thread, or crashing will occur.
+ mTestActivity.runOnUiThread(testRunnable);
+ testRunnable.wait();
+
+ }
+ synchronized(this) {
+ //Wait about 200ms for the change to take place
+ wait(200L);
+ }
+ } catch (Throwable throwable) {
+ fail(throwable.getMessage());
+ }
+
+ int expandedHeight = getActivity().getWindow().getDecorView().getHeight();
+ assertTrue("Bars aren't hidden.", expandedHeight != startingHeight);
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicImmersiveMode/README.txt b/prebuilts/gradle/BasicImmersiveMode/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicImmersiveMode/build.gradle b/prebuilts/gradle/BasicImmersiveMode/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicImmersiveMode/gradlew b/prebuilts/gradle/BasicImmersiveMode/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicImmersiveMode/gradlew.bat b/prebuilts/gradle/BasicImmersiveMode/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicImmersiveMode/settings.gradle b/prebuilts/gradle/BasicImmersiveMode/settings.gradle
new file mode 100644
index 0000000..8dda383
--- /dev/null
+++ b/prebuilts/gradle/BasicImmersiveMode/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicImmersiveModeSample'
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/build.gradle b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/build.gradle
new file mode 100644
index 0000000..2a7b163
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 17
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..d191491
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicmediadecoder"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="17"/>
+ <application
+ android:label="@string/app_name" android:icon="@drawable/ic_launcher">
+ <activity
+ android:name=".MainActivity"
+ android:screenOrientation="landscape"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/basicmediadecoder/MainActivity.java b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/basicmediadecoder/MainActivity.java
new file mode 100644
index 0000000..cac5bf2
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/basicmediadecoder/MainActivity.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2013 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.basicmediadecoder;
+
+
+import android.animation.TimeAnimator;
+import android.app.Activity;
+import android.media.MediaCodec;
+import android.media.MediaExtractor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.View;
+import android.widget.TextView;
+
+import com.example.android.common.media.MediaCodecWrapper;
+
+import java.io.IOException;
+
+/**
+ * This activity uses a {@link android.view.TextureView} to render the frames of a video decoded using
+ * {@link android.media.MediaCodec} API.
+ */
+public class MainActivity extends Activity {
+
+ private TextureView mPlaybackView;
+ private TimeAnimator mTimeAnimator = new TimeAnimator();
+
+ // A utility that wraps up the underlying input and output buffer processing operations
+ // into an east to use API.
+ private MediaCodecWrapper mCodecWrapper;
+ private MediaExtractor mExtractor = new MediaExtractor();
+ TextView mAttribView = null;
+
+
+ /**
+ * Called when the activity is first created.
+ */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+ mPlaybackView = (TextureView) findViewById(R.id.PlaybackView);
+ mAttribView = (TextView)findViewById(R.id.AttribView);
+
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.action_menu, menu);
+ return true;
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ if(mTimeAnimator != null && mTimeAnimator.isRunning()) {
+ mTimeAnimator.end();
+ }
+
+ if (mCodecWrapper != null ) {
+ mCodecWrapper.stopAndRelease();
+ mExtractor.release();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.menu_play) {
+ mAttribView.setVisibility(View.VISIBLE);
+ startPlayback();
+ item.setEnabled(false);
+ }
+ return true;
+ }
+
+
+ public void startPlayback() {
+
+ // Construct a URI that points to the video resource that we want to play
+ Uri videoUri = Uri.parse("android.resource://"
+ + getPackageName() + "/"
+ + R.raw.vid_bigbuckbunny);
+
+ try {
+
+ // BEGIN_INCLUDE(initialize_extractor)
+ mExtractor.setDataSource(this, videoUri, null);
+ int nTracks = mExtractor.getTrackCount();
+
+ // Begin by unselecting all of the tracks in the extractor, so we won't see
+ // any tracks that we haven't explicitly selected.
+ for (int i = 0; i < nTracks; ++i) {
+ mExtractor.unselectTrack(i);
+ }
+
+
+ // Find the first video track in the stream. In a real-world application
+ // it's possible that the stream would contain multiple tracks, but this
+ // sample assumes that we just want to play the first one.
+ for (int i = 0; i < nTracks; ++i) {
+ // Try to create a video codec for this track. This call will return null if the
+ // track is not a video track, or not a recognized video format. Once it returns
+ // a valid MediaCodecWrapper, we can break out of the loop.
+ mCodecWrapper = MediaCodecWrapper.fromVideoFormat(mExtractor.getTrackFormat(i),
+ new Surface(mPlaybackView.getSurfaceTexture()));
+ if (mCodecWrapper != null) {
+ mExtractor.selectTrack(i);
+ break;
+ }
+ }
+ // END_INCLUDE(initialize_extractor)
+
+
+
+
+ // By using a {@link TimeAnimator}, we can sync our media rendering commands with
+ // the system display frame rendering. The animator ticks as the {@link Choreographer}
+ // recieves VSYNC events.
+ mTimeAnimator.setTimeListener(new TimeAnimator.TimeListener() {
+ @Override
+ public void onTimeUpdate(final TimeAnimator animation,
+ final long totalTime,
+ final long deltaTime) {
+
+ boolean isEos = ((mExtractor.getSampleFlags() & MediaCodec
+ .BUFFER_FLAG_END_OF_STREAM) == MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+
+ // BEGIN_INCLUDE(write_sample)
+ if (!isEos) {
+ // Try to submit the sample to the codec and if successful advance the
+ // extractor to the next available sample to read.
+ boolean result = mCodecWrapper.writeSample(mExtractor, false,
+ mExtractor.getSampleTime(), mExtractor.getSampleFlags());
+
+ if (result) {
+ // Advancing the extractor is a blocking operation and it MUST be
+ // executed outside the main thread in real applications.
+ mExtractor.advance();
+ }
+ }
+ // END_INCLUDE(write_sample)
+
+ // Examine the sample at the head of the queue to see if its ready to be
+ // rendered and is not zero sized End-of-Stream record.
+ MediaCodec.BufferInfo out_bufferInfo = new MediaCodec.BufferInfo();
+ mCodecWrapper.peekSample(out_bufferInfo);
+
+ // BEGIN_INCLUDE(render_sample)
+ if (out_bufferInfo.size <= 0 && isEos) {
+ mTimeAnimator.end();
+ mCodecWrapper.stopAndRelease();
+ mExtractor.release();
+ } else if (out_bufferInfo.presentationTimeUs / 1000 < totalTime) {
+ // Pop the sample off the queue and send it to {@link Surface}
+ mCodecWrapper.popSample(true);
+ }
+ // END_INCLUDE(render_sample)
+
+ }
+ });
+
+ // We're all set. Kick off the animator to process buffers and render video frames as
+ // they become available
+ mTimeAnimator.start();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/CameraHelper.java b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/CameraHelper.java
new file mode 100644
index 0000000..1fa8416
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/CameraHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.annotation.TargetApi;
+import android.hardware.Camera;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Camera related utilities.
+ */
+public class CameraHelper {
+
+ public static final int MEDIA_TYPE_IMAGE = 1;
+ public static final int MEDIA_TYPE_VIDEO = 2;
+
+ /**
+ * Iterate over supported camera preview sizes to see which one best fits the
+ * dimensions of the given view while maintaining the aspect ratio. If none can,
+ * be lenient with the aspect ratio.
+ *
+ * @param sizes Supported camera preview sizes.
+ * @param w The width of the view.
+ * @param h The height of the view.
+ * @return Best match camera preview size to fit in the view.
+ */
+ public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
+ // Use a very small tolerance because we want an exact match.
+ final double ASPECT_TOLERANCE = 0.1;
+ double targetRatio = (double) w / h;
+ if (sizes == null)
+ return null;
+
+ Camera.Size optimalSize = null;
+
+ // Start with max value and refine as we iterate over available preview sizes. This is the
+ // minimum difference between view and camera height.
+ double minDiff = Double.MAX_VALUE;
+
+ // Target view height
+ int targetHeight = h;
+
+ // Try to find a preview size that matches aspect ratio and the target view size.
+ // Iterate over all available sizes and pick the largest size that can fit in the view and
+ // still maintain the aspect ratio.
+ for (Camera.Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+ continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find preview size that matches the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ minDiff = Double.MAX_VALUE;
+ for (Camera.Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
+
+ /**
+ * @return the default camera on the device. Return null if there is no camera on the device.
+ */
+ public static Camera getDefaultCameraInstance() {
+ return Camera.open();
+ }
+
+
+ /**
+ * @return the default rear/back facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultBackFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
+ }
+
+ /**
+ * @return the default front facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultFrontFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
+ }
+
+
+ /**
+ *
+ * @param position Physical position of the camera i.e Camera.CameraInfo.CAMERA_FACING_FRONT
+ * or Camera.CameraInfo.CAMERA_FACING_BACK.
+ * @return the default camera on the device. Returns null if camera is not available.
+ */
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ private static Camera getDefaultCamera(int position) {
+ // Find the total number of cameras available
+ int mNumberOfCameras = Camera.getNumberOfCameras();
+
+ // Find the ID of the back-facing ("default") camera
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ for (int i = 0; i < mNumberOfCameras; i++) {
+ Camera.getCameraInfo(i, cameraInfo);
+ if (cameraInfo.facing == position) {
+ return Camera.open(i);
+
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
+ * is persistent and available to other applications like gallery.
+ *
+ * @param type Media type. Can be video or image.
+ * @return A file object pointing to the newly created file.
+ */
+ public static File getOutputMediaFile(int type){
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+ if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
+ return null;
+ }
+
+ File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), "CameraSample");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (! mediaStorageDir.exists()){
+ if (! mediaStorageDir.mkdirs()) {
+ Log.d("CameraSample", "failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ File mediaFile;
+ if (type == MEDIA_TYPE_IMAGE){
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "IMG_"+ timeStamp + ".jpg");
+ } else if(type == MEDIA_TYPE_VIDEO) {
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "VID_"+ timeStamp + ".mp4");
+ } else {
+ return null;
+ }
+
+ return mediaFile;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
new file mode 100644
index 0000000..a511221
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.media.*;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * Simplifies the MediaCodec interface by wrapping around the buffer processing operations.
+ */
+public class MediaCodecWrapper {
+
+ // Handler to use for {@code OutputSampleListener} and {code OutputFormatChangedListener}
+ // callbacks
+ private Handler mHandler;
+
+
+ // Callback when media output format changes.
+ public interface OutputFormatChangedListener {
+ void outputFormatChanged(MediaCodecWrapper sender, MediaFormat newFormat);
+ }
+
+ private OutputFormatChangedListener mOutputFormatChangedListener = null;
+
+ /**
+ * Callback for decodes frames. Observers can register a listener for optional stream
+ * of decoded data
+ */
+ public interface OutputSampleListener {
+ void outputSample(MediaCodecWrapper sender, MediaCodec.BufferInfo info, ByteBuffer buffer);
+ }
+
+ /**
+ * The {@link MediaCodec} that is managed by this class.
+ */
+ private MediaCodec mDecoder;
+
+ // References to the internal buffers managed by the codec. The codec
+ // refers to these buffers by index, never by reference so it's up to us
+ // to keep track of which buffer is which.
+ private ByteBuffer[] mInputBuffers;
+ private ByteBuffer[] mOutputBuffers;
+
+ // Indices of the input buffers that are currently available for writing. We'll
+ // consume these in the order they were dequeued from the codec.
+ private Queue<Integer> mAvailableInputBuffers;
+
+ // Indices of the output buffers that currently hold valid data, in the order
+ // they were produced by the codec.
+ private Queue<Integer> mAvailableOutputBuffers;
+
+ // Information about each output buffer, by index. Each entry in this array
+ // is valid if and only if its index is currently contained in mAvailableOutputBuffers.
+ private MediaCodec.BufferInfo[] mOutputBufferInfo;
+
+ // An (optional) stream that will receive decoded data.
+ private OutputSampleListener mOutputSampleListener;
+
+ private MediaCodecWrapper(MediaCodec codec) {
+ mDecoder = codec;
+ codec.start();
+ mInputBuffers = codec.getInputBuffers();
+ mOutputBuffers = codec.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableInputBuffers = new ArrayDeque<Integer>(mOutputBuffers.length);
+ mAvailableOutputBuffers = new ArrayDeque<Integer>(mInputBuffers.length);
+ }
+
+ /**
+ * Releases resources and ends the encoding/decoding session.
+ */
+ public void stopAndRelease() {
+ mDecoder.stop();
+ mDecoder.release();
+ mDecoder = null;
+ mHandler = null;
+ }
+
+ /**
+ * Getter for the registered {@link OutputFormatChangedListener}
+ */
+ public OutputFormatChangedListener getOutputFormatChangedListener() {
+ return mOutputFormatChangedListener;
+ }
+
+ /**
+ *
+ * @param outputFormatChangedListener the listener for callback.
+ * @param handler message handler for posting the callback.
+ */
+ public void setOutputFormatChangedListener(final OutputFormatChangedListener
+ outputFormatChangedListener, Handler handler) {
+ mOutputFormatChangedListener = outputFormatChangedListener;
+
+ // Making sure we don't block ourselves due to a bad implementation of the callback by
+ // using a handler provided by client.
+ Looper looper;
+ mHandler = handler;
+ if (outputFormatChangedListener != null && mHandler == null) {
+ if ((looper = Looper.myLooper()) != null) {
+ mHandler = new Handler();
+ } else {
+ throw new IllegalArgumentException(
+ "Looper doesn't exist in the calling thread");
+ }
+ }
+ }
+
+ /**
+ * Constructs the {@link MediaCodecWrapper} wrapper object around the video codec.
+ * The codec is created using the encapsulated information in the
+ * {@link MediaFormat} object.
+ *
+ * @param trackFormat The format of the media object to be decoded.
+ * @param surface Surface to render the decoded frames.
+ * @return
+ */
+ public static MediaCodecWrapper fromVideoFormat(final MediaFormat trackFormat,
+ Surface surface) {
+ MediaCodecWrapper result = null;
+ MediaCodec videoCodec = null;
+
+ // BEGIN_INCLUDE(create_codec)
+ final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+
+ // Check to see if this is actually a video mime type. If it is, then create
+ // a codec that can decode this mime type.
+ if (mimeType.contains("video/")) {
+ videoCodec = MediaCodec.createDecoderByType(mimeType);
+ videoCodec.configure(trackFormat, surface, null, 0);
+
+ }
+
+ // If codec creation was successful, then create a wrapper object around the
+ // newly created codec.
+ if (videoCodec != null) {
+ result = new MediaCodecWrapper(videoCodec);
+ }
+ // END_INCLUDE(create_codec)
+
+ return result;
+ }
+
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param input A ByteBuffer containing the input data for one sample. The buffer must be set
+ * up for reading, with its position set to the beginning of the sample data and its limit
+ * set to the end of the sample data.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final ByteBuffer input,
+ final MediaCodec.CryptoInfo crypto,
+ final long presentationTimeUs,
+ final int flags) throws MediaCodec.CryptoException, WriteException {
+ boolean result = false;
+ int size = input.remaining();
+
+ // check if we have dequed input buffers available from the codec
+ if (size > 0 && !mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // we can't write our sample to a lesser capacity input buffer.
+ if (size > buffer.capacity()) {
+ throw new MediaCodecWrapper.WriteException(String.format(
+ "Insufficient capacity in MediaCodec buffer: "
+ + "tried to write %d, buffer capacity is %d.",
+ input.remaining(),
+ buffer.capacity()));
+ }
+
+ buffer.clear();
+ buffer.put(input);
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (crypto == null) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ mDecoder.queueSecureInputBuffer(index, 0, crypto, presentationTimeUs, flags);
+ }
+ result = true;
+ }
+ return result;
+ }
+
+ static MediaCodec.CryptoInfo cryptoInfo= new MediaCodec.CryptoInfo();
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param extractor Instance of {@link android.media.MediaExtractor} wrapping the media.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final MediaExtractor extractor,
+ final boolean isSecure,
+ final long presentationTimeUs,
+ int flags) {
+ boolean result = false;
+ boolean isEos = false;
+
+ if (!mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // reads the sample from the file using extractor into the buffer
+ int size = extractor.readSampleData(buffer, 0);
+ if (size <= 0) {
+ flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (!isSecure) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ extractor.getSampleCryptoInfo(cryptoInfo);
+ mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
+ }
+
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Performs a peek() operation in the queue to extract media info for the buffer ready to be
+ * released i.e. the head element of the queue.
+ *
+ * @param out_bufferInfo An output var to hold the buffer info.
+ *
+ * @return True, if the peek was successful.
+ */
+ public boolean peekSample(MediaCodec.BufferInfo out_bufferInfo) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ boolean result = false;
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.peek();
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ // metadata of the sample
+ out_bufferInfo.set(
+ info.offset,
+ info.size,
+ info.presentationTimeUs,
+ info.flags);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Processes, releases and optionally renders the output buffer available at the head of the
+ * queue. All observers are notified with a callback. See {@link
+ * OutputSampleListener#outputSample(MediaCodecWrapper, android.media.MediaCodec.BufferInfo,
+ * java.nio.ByteBuffer)}
+ *
+ * @param render True, if the buffer is to be rendered on the {@link Surface} configured
+ *
+ */
+ public void popSample(boolean render) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.remove();
+
+ if (render && mOutputSampleListener != null) {
+ ByteBuffer buffer = mOutputBuffers[index];
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ mOutputSampleListener.outputSample(this, info, buffer);
+ }
+
+ // releases the buffer back to the codec
+ mDecoder.releaseOutputBuffer(index, render);
+ }
+ }
+
+ /**
+ * Synchronize this object's state with the internal state of the wrapped
+ * MediaCodec.
+ */
+ private void update() {
+ // BEGIN_INCLUDE(update_codec_state)
+ int index;
+
+ // Get valid input buffers from the codec to fill later in the same order they were
+ // made available by the codec.
+ while ((index = mDecoder.dequeueInputBuffer(0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ mAvailableInputBuffers.add(index);
+ }
+
+
+ // Likewise with output buffers. If the output buffers have changed, start using the
+ // new set of output buffers. If the output format has changed, notify listeners.
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ while ((index = mDecoder.dequeueOutputBuffer(info, 0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ switch (index) {
+ case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
+ mOutputBuffers = mDecoder.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableOutputBuffers.clear();
+ break;
+ case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
+ if (mOutputFormatChangedListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mOutputFormatChangedListener
+ .outputFormatChanged(MediaCodecWrapper.this,
+ mDecoder.getOutputFormat());
+
+ }
+ });
+ }
+ break;
+ default:
+ // Making sure the index is valid before adding to output buffers. We've already
+ // handled INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED &
+ // INFO_OUTPUT_BUFFERS_CHANGED i.e all the other possible return codes but
+ // asserting index value anyways for future-proofing the code.
+ if(index >= 0) {
+ mOutputBufferInfo[index] = info;
+ mAvailableOutputBuffers.add(index);
+ } else {
+ throw new IllegalStateException("Unknown status from dequeueOutputBuffer");
+ }
+ break;
+ }
+
+ }
+ // END_INCLUDE(update_codec_state)
+
+ }
+
+ private class WriteException extends Throwable {
+ private WriteException(final String detailMessage) {
+ super(detailMessage);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play.png
new file mode 100755
index 0000000..dbfd337
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play_disabled.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play_disabled.png
new file mode 100755
index 0000000..e4310ef
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_action_play_disabled.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..9bc536b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play.png
new file mode 100755
index 0000000..a2f198a
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play_disabled.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play_disabled.png
new file mode 100755
index 0000000..d69107b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_action_play_disabled.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..d656b21
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play.png
new file mode 100755
index 0000000..9e63c90
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play_disabled.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play_disabled.png
new file mode 100755
index 0000000..2ff8c39
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_action_play_disabled.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bbb9b16
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4a5c33f
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable/selector_play.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable/selector_play.xml
new file mode 100644
index 0000000..2307135
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/drawable/selector_play.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="true"
+ android:drawable="@drawable/ic_action_play"/>
+
+ <item android:state_enabled="false"
+ android:drawable="@drawable/ic_action_play_disabled"/>
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..7543120
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <TextureView
+ android:id="@+id/PlaybackView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+ <TextView
+ android:id="@+id/AttribView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="right|bottom"
+ android:visibility="gone"
+ android:textColor="@android:color/holo_blue_bright"
+ android:text="@string/app_video_attrib"/>
+</FrameLayout>
+
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/menu/action_menu.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/menu/action_menu.xml
new file mode 100644
index 0000000..2b31a86
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/menu/action_menu.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_play"
+ android:icon="@drawable/selector_play"
+ android:title="Play"
+ android:showAsAction="ifRoom|withText" />
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/raw/vid_bigbuckbunny.mp4 b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/raw/vid_bigbuckbunny.mp4
new file mode 100644
index 0000000..81d11df
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/raw/vid_bigbuckbunny.mp4
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..94d02a8
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicMediaDecoder</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This activity uses a TextureView to render the frames of a video decoded using the
+ MediaCodec API.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..2cf79ab
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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.
+-->
+<resources>
+ <string name="app_video_attrib">(c) copyright 2008, Blender Foundation / www.bigbuckbunny.org
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/BasicMediaDecoderSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaDecoder/README.txt b/prebuilts/gradle/BasicMediaDecoder/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicMediaDecoder/build.gradle b/prebuilts/gradle/BasicMediaDecoder/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicMediaDecoder/gradlew b/prebuilts/gradle/BasicMediaDecoder/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicMediaDecoder/gradlew.bat b/prebuilts/gradle/BasicMediaDecoder/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicMediaDecoder/settings.gradle b/prebuilts/gradle/BasicMediaDecoder/settings.gradle
new file mode 100644
index 0000000..1e76e09
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaDecoder/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicMediaDecoderSample'
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/build.gradle b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/build.gradle
new file mode 100644
index 0000000..2a7b163
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 17
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..33c20d5
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicmediarouter"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="17"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/MainActivity.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/MainActivity.java
new file mode 100644
index 0000000..23b2709
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/MainActivity.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2013 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.basicmediarouter;
+
+import android.app.Activity;
+import android.app.MediaRouteActionProvider;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteInfo;
+import android.os.Bundle;
+import android.view.Display;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * <p>
+ * This sample demonstrates the use of the MediaRouter API to show content on a
+ * secondary display using a {@link android.app.Presentation}.
+ * </p>
+ * <p>
+ * The activity uses the {@link android.media.MediaRouter} API to automatically detect when a
+ * presentation display is available and to allow the user to control the media
+ * routes using a menu item provided by the {@link android.app.MediaRouteActionProvider}.
+ * When a presentation display is available a {@link android.app.Presentation} (implemented
+ * as a {@link SamplePresentation}) is shown on the preferred display. A button
+ * toggles the background color of the secondary screen to show the interaction
+ * between the primary and secondary screens.
+ * </p>
+ * <p>
+ * This sample requires an HDMI or Wifi display. Alternatively, the
+ * "Simulate secondary displays" feature in Development Settings can be enabled
+ * to simulate secondary displays.
+ * </p>
+ *
+ * @see android.app.Presentation
+ * @see android.media.MediaRouter
+ */
+public class MainActivity extends Activity {
+
+ private MediaRouter mMediaRouter;
+
+ // Active Presentation, set to null if no secondary screen is enabled
+ private SamplePresentation mPresentation;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.sample_main);
+ mTextStatus = (TextView) findViewById(R.id.textStatus);
+
+ // get the list of background colors
+ mColors = getResources().getIntArray(R.array.androidcolors);
+
+ // Enable clicks on the 'change color' button
+ mButton = (Button) findViewById(R.id.button1);
+ mButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ showNextColor();
+ }
+ });
+
+ // BEGIN_INCLUDE(getMediaRouter)
+ // Get the MediaRouter service
+ mMediaRouter = (MediaRouter) getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ // END_INCLUDE(getMediaRouter)
+ }
+
+ /**
+ * Implementing a {@link android.media.MediaRouter.Callback} to update the displayed
+ * {@link android.app.Presentation} when a route is selected, unselected or the
+ * presentation display has changed. The provided stub implementation
+ * {@link android.media.MediaRouter.SimpleCallback} is extended and only
+ * {@link android.media.MediaRouter.SimpleCallback#onRouteSelected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
+ * ,
+ * {@link android.media.MediaRouter.SimpleCallback#onRouteUnselected(android.media.MediaRouter, int, android.media.MediaRouter.RouteInfo)}
+ * and
+ * {@link android.media.MediaRouter.SimpleCallback#onRoutePresentationDisplayChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo)}
+ * are overridden to update the displayed {@link android.app.Presentation} in
+ * {@link #updatePresentation()}. These callbacks enable or disable the
+ * second screen presentation based on the routing provided by the
+ * {@link android.media.MediaRouter} for {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}
+ * streams. @
+ */
+ private final MediaRouter.SimpleCallback mMediaRouterCallback =
+ new MediaRouter.SimpleCallback() {
+
+ // BEGIN_INCLUDE(SimpleCallback)
+ /**
+ * A new route has been selected as active. Disable the current
+ * route and enable the new one.
+ */
+ @Override
+ public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+ updatePresentation();
+ }
+
+ /**
+ * The route has been unselected.
+ */
+ @Override
+ public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+ updatePresentation();
+
+ }
+
+ /**
+ * The route's presentation display has changed. This callback
+ * is called when the presentation has been activated, removed
+ * or its properties have changed.
+ */
+ @Override
+ public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
+ updatePresentation();
+ }
+ // END_INCLUDE(SimpleCallback)
+ };
+
+ /**
+ * Updates the displayed presentation to enable a secondary screen if it has
+ * been selected in the {@link android.media.MediaRouter} for the
+ * {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO} type. If no screen has been
+ * selected by the {@link android.media.MediaRouter}, the current screen is disabled.
+ * Otherwise a new {@link SamplePresentation} is initialized and shown on
+ * the secondary screen.
+ */
+ private void updatePresentation() {
+
+ // BEGIN_INCLUDE(updatePresentationInit)
+ // Get the selected route for live video
+ RouteInfo selectedRoute = mMediaRouter.getSelectedRoute(
+ MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
+
+ // Get its Display if a valid route has been selected
+ Display selectedDisplay = null;
+ if (selectedRoute != null) {
+ selectedDisplay = selectedRoute.getPresentationDisplay();
+ }
+ // END_INCLUDE(updatePresentationInit)
+
+ // BEGIN_INCLUDE(updatePresentationDismiss)
+ /*
+ * Dismiss the current presentation if the display has changed or no new
+ * route has been selected
+ */
+ if (mPresentation != null && mPresentation.getDisplay() != selectedDisplay) {
+ mPresentation.dismiss();
+ mPresentation = null;
+ mButton.setEnabled(false);
+ mTextStatus.setText(R.string.secondary_notconnected);
+ }
+ // END_INCLUDE(updatePresentationDismiss)
+
+ // BEGIN_INCLUDE(updatePresentationNew)
+ /*
+ * Show a new presentation if the previous one has been dismissed and a
+ * route has been selected.
+ */
+ if (mPresentation == null && selectedDisplay != null) {
+
+ // Initialise a new Presentation for the Display
+ mPresentation = new SamplePresentation(this, selectedDisplay);
+ mPresentation.setOnDismissListener(mOnDismissListener);
+
+ // Try to show the presentation, this might fail if the display has
+ // gone away in the mean time
+ try {
+ mPresentation.show();
+ mTextStatus.setText(getResources().getString(R.string.secondary_connected,
+ selectedRoute.getName(MainActivity.this)));
+ mButton.setEnabled(true);
+ showNextColor();
+ } catch (WindowManager.InvalidDisplayException ex) {
+ // Couldn't show presentation - display was already removed
+ mPresentation = null;
+ }
+ }
+ // END_INCLUDE(updatePresentationNew)
+
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // BEGIN_INCLUDE(addCallback)
+ // Register a callback for all events related to live video devices
+ mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_LIVE_VIDEO, mMediaRouterCallback);
+ // END_INCLUDE(addCallback)
+
+ // Show the 'Not connected' status message
+ mButton.setEnabled(false);
+ mTextStatus.setText(R.string.secondary_notconnected);
+
+ // Update the displays based on the currently active routes
+ updatePresentation();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ // BEGIN_INCLUDE(onPause)
+ // Stop listening for changes to media routes.
+ mMediaRouter.removeCallback(mMediaRouterCallback);
+ // END_INCLUDE(onPause)
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ // BEGIN_INCLUDE(onStop)
+ // Dismiss the presentation when the activity is not visible.
+ if (mPresentation != null) {
+ mPresentation.dismiss();
+ mPresentation = null;
+ }
+ // BEGIN_INCLUDE(onStop)
+ }
+
+ /**
+ * Inflates the ActionBar or options menu. The menu file defines an item for
+ * the {@link android.app.MediaRouteActionProvider}, which is registered here for all
+ * live video devices using {@link android.media.MediaRouter#ROUTE_TYPE_LIVE_VIDEO}.
+ */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ getMenuInflater().inflate(R.menu.main, menu);
+
+ // BEGIN_INCLUDE(MediaRouteActionProvider)
+ // Configure the media router action provider
+ MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
+ MediaRouteActionProvider mediaRouteActionProvider =
+ (MediaRouteActionProvider) mediaRouteMenuItem.getActionProvider();
+ mediaRouteActionProvider.setRouteTypes(MediaRouter.ROUTE_TYPE_LIVE_VIDEO);
+ // BEGIN_INCLUDE(MediaRouteActionProvider)
+
+ return true;
+ }
+
+ /**
+ * Listens for dismissal of the {@link SamplePresentation} and removes its
+ * reference.
+ */
+ private final DialogInterface.OnDismissListener mOnDismissListener =
+ new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ if (dialog == mPresentation) {
+ mPresentation = null;
+ }
+ }
+ };
+
+ // Views used to display status information on the primary screen
+ private TextView mTextStatus;
+ private Button mButton;
+
+ // selected color index
+ private int mColor = 0;
+
+ // background colors
+ public int[] mColors;
+
+ /**
+ * Displays the next color on the secondary screen if it is activate.
+ */
+ private void showNextColor() {
+ if (mPresentation != null) {
+ // a second screen is active and initialized, show the next color
+ mPresentation.setColor(mColors[mColor]);
+ mColor = (mColor + 1) % mColors.length;
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/SamplePresentation.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/SamplePresentation.java
new file mode 100644
index 0000000..ac1f40f
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/basicmediarouter/SamplePresentation.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013 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.basicmediarouter;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Display;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * <p>
+ * A {@link android.app.Presentation} used to demonstrate interaction between primary and
+ * secondary screens.
+ * </p>
+ * <p>
+ * It displays the name of the display in which it has been embedded (see
+ * {@link android.app.Presentation#getDisplay()}) and exposes a facility to change its
+ * background color and display its text.
+ * </p>
+ */
+public class SamplePresentation extends Presentation {
+
+ private LinearLayout mLayout;
+ private TextView mText;
+
+ public SamplePresentation(Context outerContext, Display display) {
+ super(outerContext, display);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Set the content view to the custom layout
+ setContentView(R.layout.display);
+
+ // Get the Views
+ mLayout = (LinearLayout) findViewById(R.id.display_layout);
+ mText = (TextView) findViewById(R.id.display_text);
+
+ /*
+ * Show the name of the display this presentation was embedded in.
+ */
+ TextView smallText = (TextView) findViewById(R.id.display_smalltext);
+ final String name = getDisplay().getName();
+ smallText.setText(getResources().getString(R.string.display_name, name));
+ }
+
+ /**
+ * Set the background color of the layout and display the color as a String.
+ *
+ * @param color The background color
+ */
+ public void setColor(int color) {
+ mLayout.setBackgroundColor(color);
+
+ // Display the color as a string on screen
+ String s = getResources().getString(R.string.display_color, color);
+ mText.setText(s);
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/display.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/display.xml
new file mode 100644
index 0000000..47d5aa9
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/display.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/display_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/display_text"
+ style="@style/DisplayLargeText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="" />
+
+ <TextView
+ android:id="@+id/display_smalltext"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..2768514
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,32 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/LinearLayout1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:orientation="vertical"
+ tools:context=".MainActivity" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="5dp"
+ android:text="@string/intro_message" />
+
+ <TextView
+ android:id="@+id/textStatus"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/secondary_notconnected"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:layout_margin="5dp" />
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:enabled="false"
+ android:text="@string/change_color" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..ebb6286
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/menu/main.xml
@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <!-- This ActionProvider is configured to -->
+ <item
+ android:id="@+id/menu_media_route"
+ android:actionProviderClass="android.app.MediaRouteActionProvider"
+ android:orderInCategory="1"
+ android:showAsAction="always"
+ android:title="@string/menu_present_to"
+ android:visible="true"/>
+
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..2115771
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicMediaRouter</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates the use of the MediaRouter API to display
+ content on a secondary display.\n\nUse the "Media Route Action Item" in the ActionBar
+ to select an output device. If your device supports Miracast wireless displays,
+ you may need to enable "Wireless Display" functionality in the system settings.
+ Secondary screen simulation can also be enabled from the "Developer Options".\n\n
+Once connected, use the "Change Color" button to change the background color of the secondary screen.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/colors.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/colors.xml
new file mode 100644
index 0000000..521d9cd
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <item name="blue" type="color">#FF33B5E5</item>
+ <item name="purple" type="color">#FFAA66CC</item>
+ <item name="green" type="color">#FF99CC00</item>
+ <item name="orange" type="color">#FFFFBB33</item>
+ <item name="red" type="color">#FFFF4444</item>
+ <item name="darkblue" type="color">#FF0099CC</item>
+ <item name="darkpurple" type="color">#FF9933CC</item>
+ <item name="darkgreen" type="color">#FF669900</item>
+ <item name="darkorange" type="color">#FFFF8800</item>
+ <item name="darkred" type="color">#FFCC0000</item>
+
+ <integer-array name="androidcolors">
+ <item>@color/blue</item>
+ <item>@color/purple</item>
+ <item>@color/green</item>
+ <item>@color/orange</item>
+ <item>@color/red</item>
+ <item>@color/darkblue</item>
+ <item>@color/darkpurple</item>
+ <item>@color/darkgreen</item>
+ <item>@color/darkorange</item>
+ <item>@color/darkred</item>
+ </integer-array>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..40c023a
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/strings.xml
@@ -0,0 +1,9 @@
+<resources>
+ <string name="menu_present_to">Present to</string>
+ <string name="title_activity_main">MainActivity</string>
+ <string name="secondary_connected">Connected to:\n%s</string>
+ <string name="secondary_notconnected">No secondary display connected.</string>
+ <string name="change_color">Change Color</string>
+ <string name="display_name">This display is: %s</string>
+ <string name="display_color">Background color: #%X</string>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/styles.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..4f64054
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/styles.xml
@@ -0,0 +1,22 @@
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+
+ <style name="DisplayLargeText">
+ <item name="android:textSize">30sp</item>
+ <item name="android:textStyle">bold</item>
+ <item name="android:textColor">#FFFFFF</item>
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8800232
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicmediarouter.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicmediarouter"
+ android:label="Tests for com.example.android.basicmediarouter" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/src/com/example/android/basicmediarouter/tests/SampleTests.java b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/src/com/example/android/basicmediarouter/tests/SampleTests.java
new file mode 100644
index 0000000..5c475a3
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/BasicMediaRouterSample/tests/src/com/example/android/basicmediarouter/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicmediarouter.tests;
+
+import com.example.android.basicmediarouter.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicMediaRouter sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicMediaRouterFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicMediaRouterFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMediaRouter/README.txt b/prebuilts/gradle/BasicMediaRouter/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicMediaRouter/build.gradle b/prebuilts/gradle/BasicMediaRouter/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicMediaRouter/gradlew b/prebuilts/gradle/BasicMediaRouter/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicMediaRouter/gradlew.bat b/prebuilts/gradle/BasicMediaRouter/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicMediaRouter/settings.gradle b/prebuilts/gradle/BasicMediaRouter/settings.gradle
new file mode 100644
index 0000000..9d5cbc2
--- /dev/null
+++ b/prebuilts/gradle/BasicMediaRouter/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicMediaRouterSample'
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/build.gradle b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/build.gradle
new file mode 100644
index 0000000..e88b9ff
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 8
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..043345c
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicmultitouch"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/MainActivity.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/MainActivity.java
new file mode 100644
index 0000000..fc95a60
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/MainActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 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.basicmultitouch;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * This is an example of keeping track of individual touches across multiple
+ * {@link android.view.MotionEvent}s.
+ * <p>
+ * This is illustrated by a View ({@link TouchDisplayView}) that responds to
+ * touch events and draws coloured circles for each pointer, stores the last
+ * positions of this pointer and draws them. This example shows the relationship
+ * between MotionEvent indices, pointer identifiers and actions.
+ *
+ * @see android.view.MotionEvent
+ */
+public class MainActivity extends Activity {
+ TouchDisplayView mView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.layout_mainactivity);
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/Pools.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/Pools.java
new file mode 100644
index 0000000..0eda0ee
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/Pools.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 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.basicmultitouch;
+
+/**
+ * Helper class for crating pools of objects. An example use looks like this:
+ * <pre>
+ * public class MyPooledClass {
+ *
+ * private static final SynchronizedPool<MyPooledClass> sPool =
+ * new SynchronizedPool<MyPooledClass>(10);
+ *
+ * public static MyPooledClass obtain() {
+ * MyPooledClass instance = sPool.acquire();
+ * return (instance != null) ? instance : new MyPooledClass();
+ * }
+ *
+ * public void recycle() {
+ * // Clear state if needed.
+ * sPool.release(this);
+ * }
+ *
+ * . . .
+ * }
+ * </pre>
+ *
+ * @hide
+ */
+public final class Pools {
+
+ /**
+ * Interface for managing a pool of objects.
+ *
+ * @param <T> The pooled type.
+ */
+ public static interface Pool<T> {
+
+ /**
+ * @return An instance from the pool if such, null otherwise.
+ */
+ public T acquire();
+
+ /**
+ * Release an instance to the pool.
+ *
+ * @param instance The instance to release.
+ * @return Whether the instance was put in the pool.
+ *
+ * @throws IllegalStateException If the instance is already in the pool.
+ */
+ public boolean release(T instance);
+ }
+
+ private Pools() {
+ /* do nothing - hiding constructor */
+ }
+
+ /**
+ * Simple (non-synchronized) pool of objects.
+ *
+ * @param <T> The pooled type.
+ */
+ public static class SimplePool<T> implements Pool<T> {
+ private final Object[] mPool;
+
+ private int mPoolSize;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param maxPoolSize The max pool size.
+ *
+ * @throws IllegalArgumentException If the max pool size is less than zero.
+ */
+ public SimplePool(int maxPoolSize) {
+ if (maxPoolSize <= 0) {
+ throw new IllegalArgumentException("The max pool size must be > 0");
+ }
+ mPool = new Object[maxPoolSize];
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public T acquire() {
+ if (mPoolSize > 0) {
+ final int lastPooledIndex = mPoolSize - 1;
+ T instance = (T) mPool[lastPooledIndex];
+ mPool[lastPooledIndex] = null;
+ mPoolSize--;
+ return instance;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean release(T instance) {
+ if (isInPool(instance)) {
+ throw new IllegalStateException("Already in the pool!");
+ }
+ if (mPoolSize < mPool.length) {
+ mPool[mPoolSize] = instance;
+ mPoolSize++;
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isInPool(T instance) {
+ for (int i = 0; i < mPoolSize; i++) {
+ if (mPool[i] == instance) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Synchronized) pool of objects.
+ *
+ * @param <T> The pooled type.
+ */
+ public static class SynchronizedPool<T> extends SimplePool<T> {
+ private final Object mLock = new Object();
+
+ /**
+ * Creates a new instance.
+ *
+ * @param maxPoolSize The max pool size.
+ *
+ * @throws IllegalArgumentException If the max pool size is less than zero.
+ */
+ public SynchronizedPool(int maxPoolSize) {
+ super(maxPoolSize);
+ }
+
+ @Override
+ public T acquire() {
+ synchronized (mLock) {
+ return super.acquire();
+ }
+ }
+
+ @Override
+ public boolean release(T element) {
+ synchronized (mLock) {
+ return super.release(element);
+ }
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/TouchDisplayView.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/TouchDisplayView.java
new file mode 100644
index 0000000..78e6abe
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/basicmultitouch/TouchDisplayView.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2013 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.basicmultitouch;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.example.android.basicmultitouch.Pools.SimplePool;
+
+/**
+ * View that shows touch events and their history. This view demonstrates the
+ * use of {@link #onTouchEvent(android.view.MotionEvent)} and {@link android.view.MotionEvent}s to keep
+ * track of touch pointers across events.
+ */
+public class TouchDisplayView extends View {
+
+ // Hold data for active touch pointer IDs
+ private SparseArray<TouchHistory> mTouches;
+
+ // Is there an active touch?
+ private boolean mHasTouch = false;
+
+ /**
+ * Holds data related to a touch pointer, including its current position,
+ * pressure and historical positions. Objects are allocated through an
+ * object pool using {@link #obtain()} and {@link #recycle()} to reuse
+ * existing objects.
+ */
+ static final class TouchHistory {
+
+ // number of historical points to store
+ public static final int HISTORY_COUNT = 20;
+
+ public float x;
+ public float y;
+ public float pressure = 0f;
+ public String label = null;
+
+ // current position in history array
+ public int historyIndex = 0;
+ public int historyCount = 0;
+
+ // arrray of pointer position history
+ public PointF[] history = new PointF[HISTORY_COUNT];
+
+ private static final int MAX_POOL_SIZE = 10;
+ private static final SimplePool<TouchHistory> sPool =
+ new SimplePool<TouchHistory>(MAX_POOL_SIZE);
+
+ public static TouchHistory obtain(float x, float y, float pressure) {
+ TouchHistory data = sPool.acquire();
+ if (data == null) {
+ data = new TouchHistory();
+ }
+
+ data.setTouch(x, y, pressure);
+
+ return data;
+ }
+
+ public TouchHistory() {
+
+ // initialise history array
+ for (int i = 0; i < HISTORY_COUNT; i++) {
+ history[i] = new PointF();
+ }
+ }
+
+ public void setTouch(float x, float y, float pressure) {
+ this.x = x;
+ this.y = y;
+ this.pressure = pressure;
+ }
+
+ public void recycle() {
+ this.historyIndex = 0;
+ this.historyCount = 0;
+ sPool.release(this);
+ }
+
+ /**
+ * Add a point to its history. Overwrites oldest point if the maximum
+ * number of historical points is already stored.
+ *
+ * @param point
+ */
+ public void addHistory(float x, float y) {
+ PointF p = history[historyIndex];
+ p.x = x;
+ p.y = y;
+
+ historyIndex = (historyIndex + 1) % history.length;
+
+ if (historyCount < HISTORY_COUNT) {
+ historyCount++;
+ }
+ }
+
+ }
+
+ public TouchDisplayView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ // SparseArray for touch events, indexed by touch id
+ mTouches = new SparseArray<TouchHistory>(10);
+
+ initialisePaint();
+ }
+
+ // BEGIN_INCLUDE(onTouchEvent)
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+
+ final int action = event.getAction();
+
+ /*
+ * Switch on the action. The action is extracted from the event by
+ * applying the MotionEvent.ACTION_MASK. Alternatively a call to
+ * event.getActionMasked() would yield in the action as well.
+ */
+ switch (action & MotionEvent.ACTION_MASK) {
+
+ case MotionEvent.ACTION_DOWN: {
+ // first pressed gesture has started
+
+ /*
+ * Only one touch event is stored in the MotionEvent. Extract
+ * the pointer identifier of this touch from the first index
+ * within the MotionEvent object.
+ */
+ int id = event.getPointerId(0);
+
+ TouchHistory data = TouchHistory.obtain(event.getX(0), event.getY(0),
+ event.getPressure(0));
+ data.label = "id: " + 0;
+
+ /*
+ * Store the data under its pointer identifier. The pointer
+ * number stays consistent for the duration of a gesture,
+ * accounting for other pointers going up or down.
+ */
+ mTouches.put(id, data);
+
+ mHasTouch = true;
+
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ /*
+ * A non-primary pointer has gone down, after an event for the
+ * primary pointer (ACTION_DOWN) has already been received.
+ */
+
+ /*
+ * The MotionEvent object contains multiple pointers. Need to
+ * extract the index at which the data for this particular event
+ * is stored.
+ */
+ int index = event.getActionIndex();
+ int id = event.getPointerId(index);
+
+ TouchHistory data = TouchHistory.obtain(event.getX(index), event.getY(index),
+ event.getPressure(index));
+ data.label = "id: " + id;
+
+ /*
+ * Store the data under its pointer identifier. The index of
+ * this pointer can change over multiple events, but this
+ * pointer is always identified by the same identifier for this
+ * active gesture.
+ */
+ mTouches.put(id, data);
+
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ /*
+ * Final pointer has gone up and has ended the last pressed
+ * gesture.
+ */
+
+ /*
+ * Extract the pointer identifier for the only event stored in
+ * the MotionEvent object and remove it from the list of active
+ * touches.
+ */
+ int id = event.getPointerId(0);
+ TouchHistory data = mTouches.get(id);
+ mTouches.remove(id);
+ data.recycle();
+
+ mHasTouch = false;
+
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ /*
+ * A non-primary pointer has gone up and other pointers are
+ * still active.
+ */
+
+ /*
+ * The MotionEvent object contains multiple pointers. Need to
+ * extract the index at which the data for this particular event
+ * is stored.
+ */
+ int index = event.getActionIndex();
+ int id = event.getPointerId(index);
+
+ TouchHistory data = mTouches.get(id);
+ mTouches.remove(id);
+ data.recycle();
+
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ /*
+ * A change event happened during a pressed gesture. (Between
+ * ACTION_DOWN and ACTION_UP or ACTION_POINTER_DOWN and
+ * ACTION_POINTER_UP)
+ */
+
+ /*
+ * Loop through all active pointers contained within this event.
+ * Data for each pointer is stored in a MotionEvent at an index
+ * (starting from 0 up to the number of active pointers). This
+ * loop goes through each of these active pointers, extracts its
+ * data (position and pressure) and updates its stored data. A
+ * pointer is identified by its pointer number which stays
+ * constant across touch events as long as it remains active.
+ * This identifier is used to keep track of a pointer across
+ * events.
+ */
+ for (int index = 0; index < event.getPointerCount(); index++) {
+ // get pointer id for data stored at this index
+ int id = event.getPointerId(index);
+
+ // get the data stored externally about this pointer.
+ TouchHistory data = mTouches.get(id);
+
+ // add previous position to history and add new values
+ data.addHistory(data.x, data.y);
+ data.setTouch(event.getX(index), event.getY(index),
+ event.getPressure(index));
+
+ }
+
+ break;
+ }
+ }
+
+ // trigger redraw on UI thread
+ this.postInvalidate();
+
+ return true;
+ }
+
+ // END_INCLUDE(onTouchEvent)
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Canvas background color depends on whether there is an active touch
+ if (mHasTouch) {
+ canvas.drawColor(BACKGROUND_ACTIVE);
+ } else {
+ // draw inactive border
+ canvas.drawRect(mBorderWidth, mBorderWidth, getWidth() - mBorderWidth, getHeight()
+ - mBorderWidth, mBorderPaint);
+ }
+
+ // loop through all active touches and draw them
+ for (int i = 0; i < mTouches.size(); i++) {
+
+ // get the pointer id and associated data for this index
+ int id = mTouches.keyAt(i);
+ TouchHistory data = mTouches.valueAt(i);
+
+ // draw the data and its history to the canvas
+ drawCircle(canvas, id, data);
+ }
+ }
+
+ /*
+ * Below are only helper methods and variables required for drawing.
+ */
+
+ // radius of active touch circle in dp
+ private static final float CIRCLE_RADIUS_DP = 75f;
+ // radius of historical circle in dp
+ private static final float CIRCLE_HISTORICAL_RADIUS_DP = 7f;
+
+ // calculated radiuses in px
+ private float mCircleRadius;
+ private float mCircleHistoricalRadius;
+
+ private Paint mCirclePaint = new Paint();
+ private Paint mTextPaint = new Paint();
+
+ private static final int BACKGROUND_ACTIVE = Color.WHITE;
+
+ // inactive border
+ private static final float INACTIVE_BORDER_DP = 15f;
+ private static final int INACTIVE_BORDER_COLOR = 0xFFffd060;
+ private Paint mBorderPaint = new Paint();
+ private float mBorderWidth;
+
+ public final int[] COLORS = {
+ 0xFF33B5E5, 0xFFAA66CC, 0xFF99CC00, 0xFFFFBB33, 0xFFFF4444,
+ 0xFF0099CC, 0xFF9933CC, 0xFF669900, 0xFFFF8800, 0xFFCC0000
+ };
+
+ /**
+ * Sets up the required {@link android.graphics.Paint} objects for the screen density of this
+ * device.
+ */
+ private void initialisePaint() {
+
+ // Calculate radiuses in px from dp based on screen density
+ float density = getResources().getDisplayMetrics().density;
+ mCircleRadius = CIRCLE_RADIUS_DP * density;
+ mCircleHistoricalRadius = CIRCLE_HISTORICAL_RADIUS_DP * density;
+
+ // Setup text paint for circle label
+ mTextPaint.setTextSize(27f);
+ mTextPaint.setColor(Color.BLACK);
+
+ // Setup paint for inactive border
+ mBorderWidth = INACTIVE_BORDER_DP * density;
+ mBorderPaint.setStrokeWidth(mBorderWidth);
+ mBorderPaint.setColor(INACTIVE_BORDER_COLOR);
+ mBorderPaint.setStyle(Paint.Style.STROKE);
+
+ }
+
+ /**
+ * Draws the data encapsulated by a {@link TouchDisplayView.TouchHistory} object to a canvas.
+ * A large circle indicates the current position held by the
+ * {@link TouchDisplayView.TouchHistory} object, while a smaller circle is drawn for each
+ * entry in its history. The size of the large circle is scaled depending on
+ * its pressure, clamped to a maximum of <code>1.0</code>.
+ *
+ * @param canvas
+ * @param id
+ * @param data
+ */
+ protected void drawCircle(Canvas canvas, int id, TouchHistory data) {
+ // select the color based on the id
+ int color = COLORS[id % COLORS.length];
+ mCirclePaint.setColor(color);
+
+ /*
+ * Draw the circle, size scaled to its pressure. Pressure is clamped to
+ * 1.0 max to ensure proper drawing. (Reported pressure values can
+ * exceed 1.0, depending on the calibration of the touch screen).
+ */
+ float pressure = Math.min(data.pressure, 1f);
+ float radius = pressure * mCircleRadius;
+
+ canvas.drawCircle(data.x, (data.y) - (radius / 2f), radius,
+ mCirclePaint);
+
+ // draw all historical points with a lower alpha value
+ mCirclePaint.setAlpha(125);
+ for (int j = 0; j < data.history.length && j < data.historyCount; j++) {
+ PointF p = data.history[j];
+ canvas.drawCircle(p.x, p.y, mCircleHistoricalRadius, mCirclePaint);
+ }
+
+ // draw its label next to the main circle
+ canvas.drawText(data.label, data.x + radius, data.y
+ - radius, mTextPaint);
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/layout_mainactivity.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/layout_mainactivity.xml
new file mode 100644
index 0000000..539a43a
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/layout/layout_mainactivity.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:padding="75dp"
+ android:text="@string/intro_message" />
+
+ <com.example.android.basicmultitouch.TouchDisplayView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</FrameLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v11/styles.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..9daaa26
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v11/styles.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+ <resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..42ce193
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+ <resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..a5388a7
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicMultitouch</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+This samples demonstrates the use of MotionEvent properties to keep track of individual touches
+across multiple touch events.
+\n\nTouch the screen with multiple fingers to show that the pointer id
+(also represented by a colour) does not change as new touch events are received.</string>
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..5765548
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/styles.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..e56d4f8
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/styles.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright 2013 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.
+ -->
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light.NoTitleBar">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/BasicMultitouchSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicMultitouch/README.txt b/prebuilts/gradle/BasicMultitouch/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicMultitouch/build.gradle b/prebuilts/gradle/BasicMultitouch/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicMultitouch/gradlew b/prebuilts/gradle/BasicMultitouch/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicMultitouch/gradlew.bat b/prebuilts/gradle/BasicMultitouch/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicMultitouch/settings.gradle b/prebuilts/gradle/BasicMultitouch/settings.gradle
new file mode 100644
index 0000000..6e6c5ba
--- /dev/null
+++ b/prebuilts/gradle/BasicMultitouch/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicMultitouchSample'
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/build.gradle b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..48bfeac
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicnetworking"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.Sample"
+ android:allowBackup="true">
+
+ <activity
+ android:name="com.example.android.basicnetworking.MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/MainActivity.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/MainActivity.java
new file mode 100755
index 0000000..39ed4b1
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/MainActivity.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2013 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.basicnetworking;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.util.TypedValue;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * Sample application demonstrating how to test whether a device is connected,
+ * and if so, whether the connection happens to be wifi or mobile (it could be
+ * something else).
+ *
+ * This sample uses the logging framework to display log output in the log
+ * fragment (LogFragment).
+ */
+public class MainActivity extends FragmentActivity {
+
+ public static final String TAG = "Basic Network Demo";
+ // Whether there is a Wi-Fi connection.
+ private static boolean wifiConnected = false;
+ // Whether there is a mobile connection.
+ private static boolean mobileConnected = false;
+
+ // Reference to the fragment showing events, so we can clear it with a button
+ // as necessary.
+ private LogFragment mLogFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ // Initialize text fragment that displays intro text.
+ SimpleTextFragment introFragment = (SimpleTextFragment)
+ getSupportFragmentManager().findFragmentById(R.id.intro_fragment);
+ introFragment.setText(R.string.intro_message);
+ introFragment.getTextView().setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16.0f);
+
+ // Initialize the logging framework.
+ initializeLogging();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ // When the user clicks TEST, display the connection status.
+ case R.id.test_action:
+ checkNetworkConnection();
+ return true;
+ // Clear the log view fragment.
+ case R.id.clear_action:
+ mLogFragment.getLogView().setText("");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Check whether the device is connected, and if so, whether the connection
+ * is wifi or mobile (it could be something else).
+ */
+ private void checkNetworkConnection() {
+ // BEGIN_INCLUDE(connect)
+ ConnectivityManager connMgr =
+ (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();
+ if (activeInfo != null && activeInfo.isConnected()) {
+ wifiConnected = activeInfo.getType() == ConnectivityManager.TYPE_WIFI;
+ mobileConnected = activeInfo.getType() == ConnectivityManager.TYPE_MOBILE;
+ if(wifiConnected) {
+ Log.i(TAG, getString(R.string.wifi_connection));
+ } else if (mobileConnected){
+ Log.i(TAG, getString(R.string.mobile_connection));
+ }
+ } else {
+ Log.i(TAG, getString(R.string.no_wifi_or_mobile));
+ }
+ // END_INCLUDE(connect)
+ }
+
+ /** Create a chain of targets that will receive log data */
+ public void initializeLogging() {
+
+ // Using Log, front-end to the logging chain, emulates
+ // android.util.log method signatures.
+
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ // A filter that strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ mLogFragment =
+ (LogFragment) getSupportFragmentManager().findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(mLogFragment.getLogView());
+ }
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/SimpleTextFragment.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/SimpleTextFragment.java
new file mode 100644
index 0000000..c6d409c
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/basicnetworking/SimpleTextFragment.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2013 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.basicnetworking;
+
+import android.os.Bundle;
+
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Simple fragment containing only a TextView. Used by TextPagerAdapter to create
+ * tutorial-style pages for apps.
+ */
+public class SimpleTextFragment extends Fragment {
+
+ // Contains the text that will be displayed by this Fragment
+ String mText;
+
+ // Contains a resource ID for the text that will be displayed by this fragment.
+ int mTextId = -1;
+
+ // Keys which will be used to store/retrieve text passed in via setArguments.
+ public static final String TEXT_KEY = "text";
+ public static final String TEXT_ID_KEY = "text_id";
+
+ // For situations where the app wants to modify text at Runtime, exposing the TextView.
+ private TextView mTextView;
+
+ public SimpleTextFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Before initializing the textView, check if any arguments were provided via setArguments.
+ processArguments();
+
+ // Create a new TextView and set its text to whatever was provided.
+ mTextView = new TextView(getActivity());
+ mTextView.setGravity(Gravity.CENTER);
+
+ if (mText != null) {
+ mTextView.setText(mText);
+ Log.i("SimpleTextFragment", mText);
+ }
+ return mTextView;
+ }
+
+ public TextView getTextView() {
+ return mTextView;
+ }
+
+ /**
+ * Changes the text for this TextView, according to the resource ID provided.
+ * @param stringId A resource ID representing the text content for this Fragment's TextView.
+ */
+ public void setText(int stringId) {
+ getTextView().setText(getActivity().getString(stringId));
+ }
+
+ /**
+ * Processes the arguments passed into this Fragment via setArguments method.
+ * Currently the method only looks for text or a textID, nothing else.
+ */
+ public void processArguments() {
+ // For most objects we'd handle the multiple possibilities for initialization variables
+ // as multiple constructors. For Fragments, however, it's customary to use
+ // setArguments / getArguments.
+ if (getArguments() != null) {
+ Bundle args = getArguments();
+ if (args.containsKey(TEXT_KEY)) {
+ mText = args.getString(TEXT_KEY);
+ Log.d("Constructor", "Added Text.");
+ } else if (args.containsKey(TEXT_ID_KEY)) {
+ mTextId = args.getInt(TEXT_ID_KEY);
+ mText = getString(mTextId);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..22ce606
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..f21e17b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..64b8059
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..6b4434a
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/sample_main.xml
new file mode 100755
index 0000000..ccbe6ae
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <fragment
+ android:name="com.example.android.basicnetworking.SimpleTextFragment"
+ android:id="@+id/intro_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..f05f16a
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/menu/main.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/test_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/test_text" />
+ <item android:id="@+id/clear_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/clear_text" />
+</menu>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..668bcdf
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicNetworking</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to use the ConnectivityManager to determine if you have
+ a network connection, and if so, what type of connection it is.
+ \n\nA "NetworkInfo" object is retrieved from the ConnectivityManager, which contains information
+ on the active connection, and then the connection type is printed to an on-screen console.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..d39460a
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/strings.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <string name="test_text">Test</string>
+ <string name="clear_text">Clear</string>
+ <string name="wifi_connection">The active connection is wifi.</string>
+ <string name="mobile_connection">The active connection is mobile.</string>
+ <string name="no_wifi_or_mobile">No wireless or mobile connection.</string>
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/styles.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..3450a54
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/styles.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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 thegi 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.
+ -->
+
+<resources>
+
+ <!-- Widget styling -->
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..293c16b
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicnetworking.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicnetworking"
+ android:label="Tests for com.example.android.basicnetworking" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/src/com/example/android/basicnetworking/tests/SampleTests.java b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/src/com/example/android/basicnetworking/tests/SampleTests.java
new file mode 100644
index 0000000..0cf077e
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/BasicNetworkingSample/tests/src/com/example/android/basicnetworking/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicnetworking.tests;
+
+import com.example.android.basicnetworking.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicNetworking sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicNetworkingFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicNetworkingFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNetworking/README.txt b/prebuilts/gradle/BasicNetworking/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicNetworking/build.gradle b/prebuilts/gradle/BasicNetworking/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicNetworking/gradlew b/prebuilts/gradle/BasicNetworking/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicNetworking/gradlew.bat b/prebuilts/gradle/BasicNetworking/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicNetworking/settings.gradle b/prebuilts/gradle/BasicNetworking/settings.gradle
new file mode 100644
index 0000000..453e7cd
--- /dev/null
+++ b/prebuilts/gradle/BasicNetworking/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicNetworkingSample'
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/build.gradle b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/build.gradle
new file mode 100644
index 0000000..e88b9ff
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 8
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1e37d0b
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicnotifications"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="17"/>
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme">
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/java/com/example/android/basicnotifications/MainActivity.java b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/java/com/example/android/basicnotifications/MainActivity.java
new file mode 100644
index 0000000..3e78c34
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/java/com/example/android/basicnotifications/MainActivity.java
@@ -0,0 +1,101 @@
+package com.example.android.basicnotifications;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.view.View;
+
+/**
+ * The entry point to the BasicNotification sample.
+ */
+public class MainActivity extends Activity {
+ /**
+ * A numeric value that identifies the notification that we'll be sending.
+ * This value needs to be unique within this app, but it doesn't need to be
+ * unique system-wide.
+ */
+ public static final int NOTIFICATION_ID = 1;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_layout);
+
+ }
+
+ /**
+ * Send a sample notification using the NotificationCompat API.
+ */
+ public void sendNotification(View view) {
+
+ // BEGIN_INCLUDE(build_action)
+ /** Create an intent that will be fired when the user clicks the notification.
+ * The intent needs to be packaged into a {@link android.app.PendingIntent} so that the
+ * notification service can fire it on our behalf.
+ */
+ Intent intent = new Intent(Intent.ACTION_VIEW,
+ Uri.parse("http://developer.android.com/reference/android/app/Notification.html"));
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
+ // END_INCLUDE(build_action)
+
+ // BEGIN_INCLUDE (build_notification)
+ /**
+ * Use NotificationCompat.Builder to set up our notification.
+ */
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+
+ /** Set the icon that will appear in the notification bar. This icon also appears
+ * in the lower right hand corner of the notification itself.
+ *
+ * Important note: although you can use any drawable as the small icon, Android
+ * design guidelines state that the icon should be simple and monochrome. Full-color
+ * bitmaps or busy images don't render well on smaller screens and can end up
+ * confusing the user.
+ */
+ builder.setSmallIcon(R.drawable.ic_stat_notification);
+
+ // Set the intent that will fire when the user taps the notification.
+ builder.setContentIntent(pendingIntent);
+
+ // Set the notification to auto-cancel. This means that the notification will disappear
+ // after the user taps it, rather than remaining until it's explicitly dismissed.
+ builder.setAutoCancel(true);
+
+ /**
+ *Build the notification's appearance.
+ * Set the large icon, which appears on the left of the notification. In this
+ * sample we'll set the large icon to be the same as our app icon. The app icon is a
+ * reasonable default if you don't have anything more compelling to use as an icon.
+ */
+ builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
+
+ /**
+ * Set the text of the notification. This sample sets the three most commononly used
+ * text areas:
+ * 1. The content title, which appears in large type at the top of the notification
+ * 2. The content text, which appears in smaller text below the title
+ * 3. The subtext, which appears under the text on newer devices. Devices running
+ * versions of Android prior to 4.2 will ignore this field, so don't use it for
+ * anything vital!
+ */
+ builder.setContentTitle("BasicNotifications Sample");
+ builder.setContentText("Time to learn about notifications!");
+ builder.setSubText("Tap to view documentation about notifications.");
+
+ // END_INCLUDE (build_notification)
+
+ // BEGIN_INCLUDE(send_notification)
+ /**
+ * Send the notification. This will immediately display the notification icon in the
+ * notification bar.
+ */
+ NotificationManager notificationManager = (NotificationManager) getSystemService(
+ NOTIFICATION_SERVICE);
+ notificationManager.notify(NOTIFICATION_ID, builder.build());
+ // END_INCLUDE(send_notification)
+ }
+}
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_notification.png
new file mode 100644
index 0000000..604d3a3
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_notification.png
new file mode 100644
index 0000000..5c86ffd
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..743382b
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_stat_notification.png
new file mode 100644
index 0000000..f39c3b3
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_notification.png
new file mode 100644
index 0000000..b919a32
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_notification.png
new file mode 100644
index 0000000..1ce3e7e
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_notification.png
new file mode 100644
index 0000000..3f4d4a6
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_notification.png
new file mode 100644
index 0000000..1dbd17c
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..46a51a4
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_stat_notification.png
new file mode 100644
index 0000000..eafbbd1
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-mdpi/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_notification.png
new file mode 100644
index 0000000..d2317d7
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_notification.png
new file mode 100644
index 0000000..7011de8
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..f97cef3
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_notification.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_notification.png
new file mode 100644
index 0000000..1f0d652
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_notification.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..17fa130
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/sample_layout.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/sample_layout.xml
new file mode 100644
index 0000000..4b0adf6
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/layout/sample_layout.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/coreLayout"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/description"
+ android:id="@+id/description"
+ android:scrollbars="vertical"
+ android:layout_gravity="fill_vertical"
+ android:layout_weight="1"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Do it!"
+ android:id="@+id/button"
+ android:layout_gravity="center"
+ android:onClick="sendNotification"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..15dafec
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicNotifications</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to display events in the system\'s notification bar. The
+ NotificationCompat API is used for compatibility with older devices, running Android
+ 2.2 (Froyo) or newer.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..075f681
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+<resources>
+
+ <string name="description">
+ Tap the button below to send a notification.\n\nThe notification\'s icon will immediately
+ appear in the notification bar. Drag the notification bar open to see the full
+ notification. Depending on which version of Android you\'re running, the full
+ notification will display an icon and two or three lines of text.
+ \n\nTap the notification to execute the notification\'s \"action,\" which is an intent
+ that we associate with the notification when it\'s created. This sample notification\'s
+ action is to send a browse intent with the url of the Notification docs on
+ developer.android.com.
+ \n\nThis sample uses the NotificationCompat API for maximum compatibility with versions
+ of Android from Froyo (Android 2.2) to the present. Try it on devices or AVDs that are
+ running different versions of Android. You\'ll see that while the presentation varies
+ slightly, the basic functionality is the same. NotificationCompat automatically takes
+ advantage of the expanded notification format in newer versions of Android, and
+ falls back gracefully to a reduced set of functionality on earlier versions.
+ </string>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..62c01e8
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicnotifications.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicnotifications"
+ android:label="Tests for com.example.android.basicnotifications" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/src/com/example/android/basicnotifications/tests/SampleTests.java b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/src/com/example/android/basicnotifications/tests/SampleTests.java
new file mode 100644
index 0000000..ffe5840
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/BasicNotificationsSample/tests/src/com/example/android/basicnotifications/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicnotifications.tests;
+
+import com.example.android.basicnotifications.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicNotifications sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicNotificationsFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicNotificationsFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicNotifications/README.txt b/prebuilts/gradle/BasicNotifications/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicNotifications/build.gradle b/prebuilts/gradle/BasicNotifications/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicNotifications/gradlew b/prebuilts/gradle/BasicNotifications/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicNotifications/gradlew.bat b/prebuilts/gradle/BasicNotifications/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicNotifications/settings.gradle b/prebuilts/gradle/BasicNotifications/settings.gradle
new file mode 100644
index 0000000..b33d67f
--- /dev/null
+++ b/prebuilts/gradle/BasicNotifications/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicNotificationsSample'
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/AndroidManifest.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/AndroidManifest.xml
new file mode 100644
index 0000000..1e35dc3
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicrenderscript"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.basicrenderscript.MainActivity"
+ android:configChanges="orientation|keyboardHidden|screenSize"
+ android:label="@string/app_name"
+ android:theme="@style/FullscreenTheme" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/build.gradle b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/build.gradle
new file mode 100644
index 0000000..0f68091
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/build.gradle
@@ -0,0 +1,67 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 8
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile files('renderscript-v8.jar')
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+
+ defaultConfig {
+
+ renderscriptTargetApi 18
+ renderscriptSupportMode true
+
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/project.properties b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/project.properties
new file mode 100644
index 0000000..aa550f1
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/project.properties
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
+renderscript.support.mode=true
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e1e2dfc
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicrenderscript"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:theme="@style/FullscreenTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/basicrenderscript/MainActivity.java b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/basicrenderscript/MainActivity.java
new file mode 100644
index 0000000..ed6d5ad
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/basicrenderscript/MainActivity.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.basicrenderscript;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.support.v8.renderscript.*;
+
+public class MainActivity extends Activity {
+ /* Number of bitmaps that is used for renderScript thread and UI thread synchronization.
+ Ideally, this can be reduced to 2, however in some devices, 2 buffers still showing tierings on UI.
+ Investigating a root cause.
+ */
+ private final int NUM_BITMAPS = 3;
+ private int mCurrentBitmap = 0;
+ private Bitmap mBitmapIn;
+ private Bitmap[] mBitmapsOut;
+ private ImageView mImageView;
+
+ private RenderScript mRS;
+ private Allocation mInAllocation;
+ private Allocation[] mOutAllocations;
+ private ScriptC_saturation mScript;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main_layout);
+
+ /*
+ * Initialize UI
+ */
+ mBitmapIn = loadBitmap(R.drawable.data);
+ mBitmapsOut = new Bitmap[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mBitmapsOut[i] = Bitmap.createBitmap(mBitmapIn.getWidth(),
+ mBitmapIn.getHeight(), mBitmapIn.getConfig());
+ }
+
+ mImageView = (ImageView) findViewById(R.id.imageView);
+ mImageView.setImageBitmap(mBitmapsOut[mCurrentBitmap]);
+ mCurrentBitmap += (mCurrentBitmap + 1) % NUM_BITMAPS;
+
+ SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1);
+ seekbar.setProgress(50);
+ seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+ public void onProgressChanged(SeekBar seekBar, int progress,
+ boolean fromUser) {
+ float max = 2.0f;
+ float min = 0.0f;
+ float f = (float) ((max - min) * (progress / 100.0) + min);
+ updateImage(f);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ });
+
+ /*
+ * Create renderScript
+ */
+ createScript();
+
+ /*
+ * Invoke renderScript kernel and update imageView
+ */
+ updateImage(1.0f);
+ }
+
+ /*
+ * Initialize RenderScript
+ * In the sample, it creates RenderScript kernel that performs saturation manipulation.
+ */
+ private void createScript() {
+ //Initialize RS
+ mRS = RenderScript.create(this);
+
+ //Allocate buffers
+ mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
+ mOutAllocations = new Allocation[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mOutAllocations[i] = Allocation.createFromBitmap(mRS, mBitmapsOut[i]);
+ }
+
+ //Load script
+ mScript = new ScriptC_saturation(mRS);
+ }
+
+ /*
+ * In the AsyncTask, it invokes RenderScript intrinsics to do a filtering.
+ * After the filtering is done, an operation blocks at Allication.copyTo() in AsyncTask thread.
+ * Once all operation is finished at onPostExecute() in UI thread, it can invalidate and update ImageView UI.
+ */
+ private class RenderScriptTask extends AsyncTask<Float, Integer, Integer> {
+ Boolean issued = false;
+
+ protected Integer doInBackground(Float... values) {
+ int index = -1;
+ if (isCancelled() == false) {
+ issued = true;
+ index = mCurrentBitmap;
+
+ /*
+ * Set global variable in RS
+ */
+ mScript.set_saturationValue(values[0]);
+
+ /*
+ * Invoke saturation filter kernel
+ */
+ mScript.forEach_saturation(mInAllocation, mOutAllocations[index]);
+
+ /*
+ * Copy to bitmap and invalidate image view
+ */
+ mOutAllocations[index].copyTo(mBitmapsOut[index]);
+ mCurrentBitmap = (mCurrentBitmap + 1) % NUM_BITMAPS;
+ }
+ return index;
+ }
+
+ void updateView(Integer result) {
+ if (result != -1) {
+ // Request UI update
+ mImageView.setImageBitmap(mBitmapsOut[result]);
+ mImageView.invalidate();
+ }
+ }
+
+ protected void onPostExecute(Integer result) {
+ updateView(result);
+ }
+
+ protected void onCancelled(Integer result) {
+ if (issued) {
+ updateView(result);
+ }
+ }
+ }
+
+ RenderScriptTask currentTask = null;
+
+ /*
+ Invoke AsynchTask and cancel previous task.
+ When AsyncTasks are piled up (typically in slow device with heavy kernel),
+ Only the latest (and already started) task invokes RenderScript operation.
+ */
+ private void updateImage(final float f) {
+ if (currentTask != null)
+ currentTask.cancel(false);
+ currentTask = new RenderScriptTask();
+ currentTask.execute(f);
+ }
+
+ /*
+ Helper to load Bitmap from resource
+ */
+ private Bitmap loadBitmap(int resource) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ return BitmapFactory.decodeResource(getResources(), resource, options);
+ }
+
+}
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/CameraHelper.java b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/CameraHelper.java
new file mode 100644
index 0000000..1fa8416
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/CameraHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.annotation.TargetApi;
+import android.hardware.Camera;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Camera related utilities.
+ */
+public class CameraHelper {
+
+ public static final int MEDIA_TYPE_IMAGE = 1;
+ public static final int MEDIA_TYPE_VIDEO = 2;
+
+ /**
+ * Iterate over supported camera preview sizes to see which one best fits the
+ * dimensions of the given view while maintaining the aspect ratio. If none can,
+ * be lenient with the aspect ratio.
+ *
+ * @param sizes Supported camera preview sizes.
+ * @param w The width of the view.
+ * @param h The height of the view.
+ * @return Best match camera preview size to fit in the view.
+ */
+ public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
+ // Use a very small tolerance because we want an exact match.
+ final double ASPECT_TOLERANCE = 0.1;
+ double targetRatio = (double) w / h;
+ if (sizes == null)
+ return null;
+
+ Camera.Size optimalSize = null;
+
+ // Start with max value and refine as we iterate over available preview sizes. This is the
+ // minimum difference between view and camera height.
+ double minDiff = Double.MAX_VALUE;
+
+ // Target view height
+ int targetHeight = h;
+
+ // Try to find a preview size that matches aspect ratio and the target view size.
+ // Iterate over all available sizes and pick the largest size that can fit in the view and
+ // still maintain the aspect ratio.
+ for (Camera.Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+ continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find preview size that matches the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ minDiff = Double.MAX_VALUE;
+ for (Camera.Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
+
+ /**
+ * @return the default camera on the device. Return null if there is no camera on the device.
+ */
+ public static Camera getDefaultCameraInstance() {
+ return Camera.open();
+ }
+
+
+ /**
+ * @return the default rear/back facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultBackFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
+ }
+
+ /**
+ * @return the default front facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultFrontFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
+ }
+
+
+ /**
+ *
+ * @param position Physical position of the camera i.e Camera.CameraInfo.CAMERA_FACING_FRONT
+ * or Camera.CameraInfo.CAMERA_FACING_BACK.
+ * @return the default camera on the device. Returns null if camera is not available.
+ */
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ private static Camera getDefaultCamera(int position) {
+ // Find the total number of cameras available
+ int mNumberOfCameras = Camera.getNumberOfCameras();
+
+ // Find the ID of the back-facing ("default") camera
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ for (int i = 0; i < mNumberOfCameras; i++) {
+ Camera.getCameraInfo(i, cameraInfo);
+ if (cameraInfo.facing == position) {
+ return Camera.open(i);
+
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
+ * is persistent and available to other applications like gallery.
+ *
+ * @param type Media type. Can be video or image.
+ * @return A file object pointing to the newly created file.
+ */
+ public static File getOutputMediaFile(int type){
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+ if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
+ return null;
+ }
+
+ File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), "CameraSample");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (! mediaStorageDir.exists()){
+ if (! mediaStorageDir.mkdirs()) {
+ Log.d("CameraSample", "failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ File mediaFile;
+ if (type == MEDIA_TYPE_IMAGE){
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "IMG_"+ timeStamp + ".jpg");
+ } else if(type == MEDIA_TYPE_VIDEO) {
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "VID_"+ timeStamp + ".mp4");
+ } else {
+ return null;
+ }
+
+ return mediaFile;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
new file mode 100644
index 0000000..a511221
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.media.*;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * Simplifies the MediaCodec interface by wrapping around the buffer processing operations.
+ */
+public class MediaCodecWrapper {
+
+ // Handler to use for {@code OutputSampleListener} and {code OutputFormatChangedListener}
+ // callbacks
+ private Handler mHandler;
+
+
+ // Callback when media output format changes.
+ public interface OutputFormatChangedListener {
+ void outputFormatChanged(MediaCodecWrapper sender, MediaFormat newFormat);
+ }
+
+ private OutputFormatChangedListener mOutputFormatChangedListener = null;
+
+ /**
+ * Callback for decodes frames. Observers can register a listener for optional stream
+ * of decoded data
+ */
+ public interface OutputSampleListener {
+ void outputSample(MediaCodecWrapper sender, MediaCodec.BufferInfo info, ByteBuffer buffer);
+ }
+
+ /**
+ * The {@link MediaCodec} that is managed by this class.
+ */
+ private MediaCodec mDecoder;
+
+ // References to the internal buffers managed by the codec. The codec
+ // refers to these buffers by index, never by reference so it's up to us
+ // to keep track of which buffer is which.
+ private ByteBuffer[] mInputBuffers;
+ private ByteBuffer[] mOutputBuffers;
+
+ // Indices of the input buffers that are currently available for writing. We'll
+ // consume these in the order they were dequeued from the codec.
+ private Queue<Integer> mAvailableInputBuffers;
+
+ // Indices of the output buffers that currently hold valid data, in the order
+ // they were produced by the codec.
+ private Queue<Integer> mAvailableOutputBuffers;
+
+ // Information about each output buffer, by index. Each entry in this array
+ // is valid if and only if its index is currently contained in mAvailableOutputBuffers.
+ private MediaCodec.BufferInfo[] mOutputBufferInfo;
+
+ // An (optional) stream that will receive decoded data.
+ private OutputSampleListener mOutputSampleListener;
+
+ private MediaCodecWrapper(MediaCodec codec) {
+ mDecoder = codec;
+ codec.start();
+ mInputBuffers = codec.getInputBuffers();
+ mOutputBuffers = codec.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableInputBuffers = new ArrayDeque<Integer>(mOutputBuffers.length);
+ mAvailableOutputBuffers = new ArrayDeque<Integer>(mInputBuffers.length);
+ }
+
+ /**
+ * Releases resources and ends the encoding/decoding session.
+ */
+ public void stopAndRelease() {
+ mDecoder.stop();
+ mDecoder.release();
+ mDecoder = null;
+ mHandler = null;
+ }
+
+ /**
+ * Getter for the registered {@link OutputFormatChangedListener}
+ */
+ public OutputFormatChangedListener getOutputFormatChangedListener() {
+ return mOutputFormatChangedListener;
+ }
+
+ /**
+ *
+ * @param outputFormatChangedListener the listener for callback.
+ * @param handler message handler for posting the callback.
+ */
+ public void setOutputFormatChangedListener(final OutputFormatChangedListener
+ outputFormatChangedListener, Handler handler) {
+ mOutputFormatChangedListener = outputFormatChangedListener;
+
+ // Making sure we don't block ourselves due to a bad implementation of the callback by
+ // using a handler provided by client.
+ Looper looper;
+ mHandler = handler;
+ if (outputFormatChangedListener != null && mHandler == null) {
+ if ((looper = Looper.myLooper()) != null) {
+ mHandler = new Handler();
+ } else {
+ throw new IllegalArgumentException(
+ "Looper doesn't exist in the calling thread");
+ }
+ }
+ }
+
+ /**
+ * Constructs the {@link MediaCodecWrapper} wrapper object around the video codec.
+ * The codec is created using the encapsulated information in the
+ * {@link MediaFormat} object.
+ *
+ * @param trackFormat The format of the media object to be decoded.
+ * @param surface Surface to render the decoded frames.
+ * @return
+ */
+ public static MediaCodecWrapper fromVideoFormat(final MediaFormat trackFormat,
+ Surface surface) {
+ MediaCodecWrapper result = null;
+ MediaCodec videoCodec = null;
+
+ // BEGIN_INCLUDE(create_codec)
+ final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+
+ // Check to see if this is actually a video mime type. If it is, then create
+ // a codec that can decode this mime type.
+ if (mimeType.contains("video/")) {
+ videoCodec = MediaCodec.createDecoderByType(mimeType);
+ videoCodec.configure(trackFormat, surface, null, 0);
+
+ }
+
+ // If codec creation was successful, then create a wrapper object around the
+ // newly created codec.
+ if (videoCodec != null) {
+ result = new MediaCodecWrapper(videoCodec);
+ }
+ // END_INCLUDE(create_codec)
+
+ return result;
+ }
+
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param input A ByteBuffer containing the input data for one sample. The buffer must be set
+ * up for reading, with its position set to the beginning of the sample data and its limit
+ * set to the end of the sample data.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final ByteBuffer input,
+ final MediaCodec.CryptoInfo crypto,
+ final long presentationTimeUs,
+ final int flags) throws MediaCodec.CryptoException, WriteException {
+ boolean result = false;
+ int size = input.remaining();
+
+ // check if we have dequed input buffers available from the codec
+ if (size > 0 && !mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // we can't write our sample to a lesser capacity input buffer.
+ if (size > buffer.capacity()) {
+ throw new MediaCodecWrapper.WriteException(String.format(
+ "Insufficient capacity in MediaCodec buffer: "
+ + "tried to write %d, buffer capacity is %d.",
+ input.remaining(),
+ buffer.capacity()));
+ }
+
+ buffer.clear();
+ buffer.put(input);
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (crypto == null) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ mDecoder.queueSecureInputBuffer(index, 0, crypto, presentationTimeUs, flags);
+ }
+ result = true;
+ }
+ return result;
+ }
+
+ static MediaCodec.CryptoInfo cryptoInfo= new MediaCodec.CryptoInfo();
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param extractor Instance of {@link android.media.MediaExtractor} wrapping the media.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final MediaExtractor extractor,
+ final boolean isSecure,
+ final long presentationTimeUs,
+ int flags) {
+ boolean result = false;
+ boolean isEos = false;
+
+ if (!mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // reads the sample from the file using extractor into the buffer
+ int size = extractor.readSampleData(buffer, 0);
+ if (size <= 0) {
+ flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (!isSecure) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ extractor.getSampleCryptoInfo(cryptoInfo);
+ mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
+ }
+
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Performs a peek() operation in the queue to extract media info for the buffer ready to be
+ * released i.e. the head element of the queue.
+ *
+ * @param out_bufferInfo An output var to hold the buffer info.
+ *
+ * @return True, if the peek was successful.
+ */
+ public boolean peekSample(MediaCodec.BufferInfo out_bufferInfo) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ boolean result = false;
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.peek();
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ // metadata of the sample
+ out_bufferInfo.set(
+ info.offset,
+ info.size,
+ info.presentationTimeUs,
+ info.flags);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Processes, releases and optionally renders the output buffer available at the head of the
+ * queue. All observers are notified with a callback. See {@link
+ * OutputSampleListener#outputSample(MediaCodecWrapper, android.media.MediaCodec.BufferInfo,
+ * java.nio.ByteBuffer)}
+ *
+ * @param render True, if the buffer is to be rendered on the {@link Surface} configured
+ *
+ */
+ public void popSample(boolean render) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.remove();
+
+ if (render && mOutputSampleListener != null) {
+ ByteBuffer buffer = mOutputBuffers[index];
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ mOutputSampleListener.outputSample(this, info, buffer);
+ }
+
+ // releases the buffer back to the codec
+ mDecoder.releaseOutputBuffer(index, render);
+ }
+ }
+
+ /**
+ * Synchronize this object's state with the internal state of the wrapped
+ * MediaCodec.
+ */
+ private void update() {
+ // BEGIN_INCLUDE(update_codec_state)
+ int index;
+
+ // Get valid input buffers from the codec to fill later in the same order they were
+ // made available by the codec.
+ while ((index = mDecoder.dequeueInputBuffer(0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ mAvailableInputBuffers.add(index);
+ }
+
+
+ // Likewise with output buffers. If the output buffers have changed, start using the
+ // new set of output buffers. If the output format has changed, notify listeners.
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ while ((index = mDecoder.dequeueOutputBuffer(info, 0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ switch (index) {
+ case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
+ mOutputBuffers = mDecoder.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableOutputBuffers.clear();
+ break;
+ case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
+ if (mOutputFormatChangedListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mOutputFormatChangedListener
+ .outputFormatChanged(MediaCodecWrapper.this,
+ mDecoder.getOutputFormat());
+
+ }
+ });
+ }
+ break;
+ default:
+ // Making sure the index is valid before adding to output buffers. We've already
+ // handled INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED &
+ // INFO_OUTPUT_BUFFERS_CHANGED i.e all the other possible return codes but
+ // asserting index value anyways for future-proofing the code.
+ if(index >= 0) {
+ mOutputBufferInfo[index] = info;
+ mAvailableOutputBuffers.add(index);
+ } else {
+ throw new IllegalStateException("Unknown status from dequeueOutputBuffer");
+ }
+ break;
+ }
+
+ }
+ // END_INCLUDE(update_codec_state)
+
+ }
+
+ private class WriteException extends Throwable {
+ private WriteException(final String detailMessage) {
+ super(detailMessage);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..75b3c97
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..4ccd98e
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-nodpi/data.jpg b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-nodpi/data.jpg
new file mode 100644
index 0000000..81a87b1
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-nodpi/data.jpg
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..7c5aeed
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..3c45f51
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/main_layout.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/main_layout.xml
new file mode 100644
index 0000000..69695f0
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/layout/main_layout.xml
@@ -0,0 +1,22 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#0099cc"
+ tools:context=".MainActivity">
+
+ <ImageView
+ android:id="@+id/imageView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="fitCenter"
+ android:src="@drawable/data" />
+
+ <SeekBar
+ android:id="@+id/seekBar1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="16dp" />
+
+</FrameLayout>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v11/styles.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..f3a90c6
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v11/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+ <style name="FullscreenTheme" parent="android:Theme.Holo">
+ <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
+ <item name="android:windowActionBarOverlay">true</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
+ <item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
+ </style>
+
+ <style name="FullscreenActionBarStyle" parent="android:Widget.Holo.ActionBar">
+ <item name="android:background">@color/black_overlay</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..a91fd03
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/attrs.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..e67df0a
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/attrs.xml
@@ -0,0 +1,14 @@
+<resources>
+
+ <!--
+ Declare custom theme attributes that allow changing which styles are
+ used for button bars depending on the API level.
+ ?android:attr/buttonBarStyle is new as of API 11 so this is
+ necessary to support previous API levels.
+ -->
+ <declare-styleable name="ButtonBarContainerTheme">
+ <attr name="buttonBarStyle" format="reference" />
+ <attr name="buttonBarButtonStyle" format="reference" />
+ </declare-styleable>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..a35b320
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicRenderScript</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ BasicRenderScript sample demonstrates basic steps how to use renderScript.
+ In the sample, it performs graphical filter operation on a image with renderScript.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/colors.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/colors.xml
new file mode 100644
index 0000000..327c060
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <color name="black_overlay">#66000000</color>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/styles.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..49299b9
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/styles.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+
+ <style name="FullscreenTheme" parent="android:Theme.NoTitleBar">
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">@style/ButtonBar</item>
+ <item name="buttonBarButtonStyle">@style/ButtonBarButton</item>
+ </style>
+
+ <style name="ButtonBar">
+ <item name="android:paddingLeft">2dp</item>
+ <item name="android:paddingTop">5dp</item>
+ <item name="android:paddingRight">2dp</item>
+ <item name="android:paddingBottom">0dp</item>
+ <item name="android:background">@android:drawable/bottom_bar</item>
+ </style>
+
+ <style name="ButtonBarButton" />
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..02a8db3
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicrenderscript.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicrenderscript"
+ android:label="Tests for com.example.android.basicrenderscript" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/src/com/example/android/basicrenderscript/tests/SampleTests.java b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/src/com/example/android/basicrenderscript/tests/SampleTests.java
new file mode 100644
index 0000000..b361507
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/BasicRenderScriptSample/tests/src/com/example/android/basicrenderscript/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicrenderscript.tests;
+
+import com.example.android.basicrenderscript.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicRenderScript sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicRenderScriptFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicRenderScriptFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicRenderScript/README.txt b/prebuilts/gradle/BasicRenderScript/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicRenderScript/build.gradle b/prebuilts/gradle/BasicRenderScript/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..5838598
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..8e914ab
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 30 14:48:26 PST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/BasicRenderScript/gradlew b/prebuilts/gradle/BasicRenderScript/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicRenderScript/gradlew.bat b/prebuilts/gradle/BasicRenderScript/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicRenderScript/settings.gradle b/prebuilts/gradle/BasicRenderScript/settings.gradle
new file mode 100644
index 0000000..cb17006
--- /dev/null
+++ b/prebuilts/gradle/BasicRenderScript/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicRenderScriptSample'
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/build.gradle b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/build.gradle
new file mode 100644
index 0000000..007d99d
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 7
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..dd59b06
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/AndroidManifest.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicsyncadapter"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- SyncAdapters are available in API 5 and above. We use API 7 as a baseline for samples. -->
+ <uses-sdk
+ android:minSdkVersion="7"
+ android:targetSdkVersion="17" />
+
+ <!-- Required for fetching feed data. -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <!-- Required to register a SyncStatusObserver to display a "syncing..." progress indicator. -->
+ <uses-permission android:name="android.permission.READ_SYNC_STATS"/>
+ <!-- Required to enable our SyncAdapter after it's created. -->
+ <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
+ <!-- Required because we're manually creating a new account. -->
+ <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
+
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+
+ <!-- Main activity, responsible for showing a list of feed entries. -->
+ <activity
+ android:name=".EntryListActivity"
+ android:label="@string/app_name" >
+ <!-- This intent filter places this activity in the system's app launcher. -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- ContentProvider to store feed data.
+
+ The "authorities" here are defined as part of a ContentProvider interface. It's used here
+ as an attachment point for the SyncAdapter. See res/xml/syncadapter.xml and
+ SyncService.java.
+
+ Since this ContentProvider is not exported, it will not be accessible outside of this app's
+ package. -->
+ <provider
+ android:name=".provider.FeedProvider"
+ android:authorities="com.example.android.basicsyncadapter"
+ android:exported="false" />
+
+ <!-- This service implements our SyncAdapter. It needs to be exported, so that the system
+ sync framework can access it. -->
+ <service android:name=".SyncService"
+ android:exported="true">
+ <!-- This intent filter is required. It allows the system to launch our sync service
+ as needed. -->
+ <intent-filter>
+ <action android:name="android.content.SyncAdapter" />
+ </intent-filter>
+ <!-- This points to a required XML file which describes our SyncAdapter. -->
+ <meta-data android:name="android.content.SyncAdapter"
+ android:resource="@xml/syncadapter" />
+ </service>
+
+ <!-- This implements the account we'll use as an attachment point for our SyncAdapter. Since
+ our SyncAdapter doesn't need to authenticate the current user (it just fetches a public RSS
+ feed), this account's implementation is largely empty.
+
+ It's also possible to attach a SyncAdapter to an existing account provided by another
+ package. In that case, this element could be omitted here. -->
+ <service android:name="com.example.android.common.accounts.GenericAccountService">
+ <!-- Required filter used by the system to launch our account service. -->
+ <intent-filter>
+ <action android:name="android.accounts.AccountAuthenticator" />
+ </intent-filter>
+ <!-- This points to an XMLf ile which describes our account service. -->
+ <meta-data android:name="android.accounts.AccountAuthenticator"
+ android:resource="@xml/authenticator" />
+ </service>
+
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListActivity.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListActivity.java
new file mode 100644
index 0000000..9d8cb77
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListActivity.java
@@ -0,0 +1,16 @@
+package com.example.android.basicsyncadapter;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+/**
+ * Activity for holding EntryListFragment.
+ */
+public class EntryListActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_entry_list);
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListFragment.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListFragment.java
new file mode 100644
index 0000000..83e240a
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/EntryListFragment.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2013 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.basicsyncadapter;
+
+import android.accounts.Account;
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.SyncStatusObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v4.widget.SimpleCursorAdapter;
+import android.text.format.Time;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.example.android.common.accounts.GenericAccountService;
+import com.example.android.basicsyncadapter.provider.FeedContract;
+
+/**
+ * List fragment containing a list of Atom entry objects (articles) stored in the local database.
+ *
+ * <p>Database access is mediated by a content provider, specified in
+ * {@link com.example.android.basicsyncadapter.provider.FeedProvider}. This content
+ * provider is
+ * automatically populated by {@link SyncService}.
+ *
+ * <p>Selecting an item from the displayed list displays the article in the default browser.
+ *
+ * <p>If the content provider doesn't return any data, then the first sync hasn't run yet. This sync
+ * adapter assumes data exists in the provider once a sync has run. If your app doesn't work like
+ * this, you should add a flag that notes if a sync has run, so you can differentiate between "no
+ * available data" and "no initial sync", and display this in the UI.
+ *
+ * <p>The ActionBar displays a "Refresh" button. When the user clicks "Refresh", the sync adapter
+ * runs immediately. An indeterminate ProgressBar element is displayed, showing that the sync is
+ * occurring.
+ */
+public class EntryListFragment extends ListFragment
+ implements LoaderManager.LoaderCallbacks<Cursor> {
+
+ private static final String TAG = "EntryListFragment";
+
+ /**
+ * Cursor adapter for controlling ListView results.
+ */
+ private SimpleCursorAdapter mAdapter;
+
+ /**
+ * Handle to a SyncObserver. The ProgressBar element is visible until the SyncObserver reports
+ * that the sync is complete.
+ *
+ * <p>This allows us to delete our SyncObserver once the application is no longer in the
+ * foreground.
+ */
+ private Object mSyncObserverHandle;
+
+ /**
+ * Options menu used to populate ActionBar.
+ */
+ private Menu mOptionsMenu;
+
+ /**
+ * Projection for querying the content provider.
+ */
+ private static final String[] PROJECTION = new String[]{
+ FeedContract.Entry._ID,
+ FeedContract.Entry.COLUMN_NAME_TITLE,
+ FeedContract.Entry.COLUMN_NAME_LINK,
+ FeedContract.Entry.COLUMN_NAME_PUBLISHED
+ };
+
+ // Column indexes. The index of a column in the Cursor is the same as its relative position in
+ // the projection.
+ /** Column index for _ID */
+ private static final int COLUMN_ID = 0;
+ /** Column index for title */
+ private static final int COLUMN_TITLE = 1;
+ /** Column index for link */
+ private static final int COLUMN_URL_STRING = 2;
+ /** Column index for published */
+ private static final int COLUMN_PUBLISHED = 3;
+
+ /**
+ * List of Cursor columns to read from when preparing an adapter to populate the ListView.
+ */
+ private static final String[] FROM_COLUMNS = new String[]{
+ FeedContract.Entry.COLUMN_NAME_TITLE,
+ FeedContract.Entry.COLUMN_NAME_PUBLISHED
+ };
+
+ /**
+ * List of Views which will be populated by Cursor data.
+ */
+ private static final int[] TO_FIELDS = new int[]{
+ android.R.id.text1,
+ android.R.id.text2};
+
+ /**
+ * Mandatory empty constructor for the fragment manager to instantiate the
+ * fragment (e.g. upon screen orientation changes).
+ */
+ public EntryListFragment() {}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ /**
+ * Create SyncAccount at launch, if needed.
+ *
+ * <p>This will create a new account with the system for our application, register our
+ * {@link SyncService} with it, and establish a sync schedule.
+ */
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ // Create account, if needed
+ SyncUtils.CreateSyncAccount(activity);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mAdapter = new SimpleCursorAdapter(
+ getActivity(), // Current context
+ android.R.layout.simple_list_item_activated_2, // Layout for individual rows
+ null, // Cursor
+ FROM_COLUMNS, // Cursor columns to use
+ TO_FIELDS, // Layout fields to use
+ 0 // No flags
+ );
+ mAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
+ @Override
+ public boolean setViewValue(View view, Cursor cursor, int i) {
+ if (i == COLUMN_PUBLISHED) {
+ // Convert timestamp to human-readable date
+ Time t = new Time();
+ t.set(cursor.getLong(i));
+ ((TextView) view).setText(t.format("%Y-%m-%d %H:%M"));
+ return true;
+ } else {
+ // Let SimpleCursorAdapter handle other fields automatically
+ return false;
+ }
+ }
+ });
+ setListAdapter(mAdapter);
+ setEmptyText(getText(R.string.loading));
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mSyncStatusObserver.onStatusChanged(0);
+
+ // Watch for sync state changes
+ final int mask = ContentResolver.SYNC_OBSERVER_TYPE_PENDING |
+ ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
+ mSyncObserverHandle = ContentResolver.addStatusChangeListener(mask, mSyncStatusObserver);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mSyncObserverHandle != null) {
+ ContentResolver.removeStatusChangeListener(mSyncObserverHandle);
+ mSyncObserverHandle = null;
+ }
+ }
+
+ /**
+ * Query the content provider for data.
+ *
+ * <p>Loaders do queries in a background thread. They also provide a ContentObserver that is
+ * triggered when data in the content provider changes. When the sync adapter updates the
+ * content provider, the ContentObserver responds by resetting the loader and then reloading
+ * it.
+ */
+ @Override
+ public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
+ // We only have one loader, so we can ignore the value of i.
+ // (It'll be '0', as set in onCreate().)
+ return new CursorLoader(getActivity(), // Context
+ FeedContract.Entry.CONTENT_URI, // URI
+ PROJECTION, // Projection
+ null, // Selection
+ null, // Selection args
+ FeedContract.Entry.COLUMN_NAME_PUBLISHED + " desc"); // Sort
+ }
+
+ /**
+ * Move the Cursor returned by the query into the ListView adapter. This refreshes the existing
+ * UI with the data in the Cursor.
+ */
+ @Override
+ public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
+ mAdapter.changeCursor(cursor);
+ }
+
+ /**
+ * Called when the ContentObserver defined for the content provider detects that data has
+ * changed. The ContentObserver resets the loader, and then re-runs the loader. In the adapter,
+ * set the Cursor value to null. This removes the reference to the Cursor, allowing it to be
+ * garbage-collected.
+ */
+ @Override
+ public void onLoaderReset(Loader<Cursor> cursorLoader) {
+ mAdapter.changeCursor(null);
+ }
+
+ /**
+ * Create the ActionBar.
+ */
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ super.onCreateOptionsMenu(menu, inflater);
+ mOptionsMenu = menu;
+ inflater.inflate(R.menu.main, menu);
+ }
+
+ /**
+ * Respond to user gestures on the ActionBar.
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ // If the user clicks the "Refresh" button.
+ case R.id.menu_refresh:
+ SyncUtils.TriggerRefresh();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Load an article in the default browser when selected by the user.
+ */
+ @Override
+ public void onListItemClick(ListView listView, View view, int position, long id) {
+ super.onListItemClick(listView, view, position, id);
+
+ // Get a URI for the selected item, then start an Activity that displays the URI. Any
+ // Activity that filters for ACTION_VIEW and a URI can accept this. In most cases, this will
+ // be a browser.
+
+ // Get the item at the selected position, in the form of a Cursor.
+ Cursor c = (Cursor) mAdapter.getItem(position);
+ // Get the link to the article represented by the item.
+ String articleUrlString = c.getString(COLUMN_URL_STRING);
+ if (articleUrlString == null) {
+ Log.e(TAG, "Attempt to launch entry with null link");
+ return;
+ }
+
+ Log.i(TAG, "Opening URL: " + articleUrlString);
+ // Get a Uri object for the URL string
+ Uri articleURL = Uri.parse(articleUrlString);
+ Intent i = new Intent(Intent.ACTION_VIEW, articleURL);
+ startActivity(i);
+ }
+
+ /**
+ * Set the state of the Refresh button. If a sync is active, turn on the ProgressBar widget.
+ * Otherwise, turn it off.
+ *
+ * @param refreshing True if an active sync is occuring, false otherwise
+ */
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ public void setRefreshActionButtonState(boolean refreshing) {
+ if (mOptionsMenu == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ return;
+ }
+
+ final MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh);
+ if (refreshItem != null) {
+ if (refreshing) {
+ refreshItem.setActionView(R.layout.actionbar_indeterminate_progress);
+ } else {
+ refreshItem.setActionView(null);
+ }
+ }
+ }
+
+ /**
+ * Crfate a new anonymous SyncStatusObserver. It's attached to the app's ContentResolver in
+ * onResume(), and removed in onPause(). If status changes, it sets the state of the Refresh
+ * button. If a sync is active or pending, the Refresh button is replaced by an indeterminate
+ * ProgressBar; otherwise, the button itself is displayed.
+ */
+ private SyncStatusObserver mSyncStatusObserver = new SyncStatusObserver() {
+ /** Callback invoked with the sync adapter status changes. */
+ @Override
+ public void onStatusChanged(int which) {
+ getActivity().runOnUiThread(new Runnable() {
+ /**
+ * The SyncAdapter runs on a background thread. To update the UI, onStatusChanged()
+ * runs on the UI thread.
+ */
+ @Override
+ public void run() {
+ // Create a handle to the account that was created by
+ // SyncService.CreateSyncAccount(). This will be used to query the system to
+ // see how the sync status has changed.
+ Account account = GenericAccountService.GetAccount(SyncUtils.ACCOUNT_TYPE);
+ if (account == null) {
+ // GetAccount() returned an invalid value. This shouldn't happen, but
+ // we'll set the status to "not refreshing".
+ setRefreshActionButtonState(false);
+ return;
+ }
+
+ // Test the ContentResolver to see if the sync adapter is active or pending.
+ // Set the state of the refresh button accordingly.
+ boolean syncActive = ContentResolver.isSyncActive(
+ account, FeedContract.CONTENT_AUTHORITY);
+ boolean syncPending = ContentResolver.isSyncPending(
+ account, FeedContract.CONTENT_AUTHORITY);
+ setRefreshActionButtonState(syncActive || syncPending);
+ }
+ });
+ }
+ };
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncAdapter.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncAdapter.java
new file mode 100644
index 0000000..da67107
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncAdapter.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2013 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.basicsyncadapter;
+
+import android.accounts.Account;
+import android.annotation.TargetApi;
+import android.content.AbstractThreadedSyncAdapter;
+import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.content.SyncResult;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.example.android.basicsyncadapter.net.FeedParser;
+import com.example.android.basicsyncadapter.provider.FeedContract;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Define a sync adapter for the app.
+ *
+ * <p>This class is instantiated in {@link SyncService}, which also binds SyncAdapter to the system.
+ * SyncAdapter should only be initialized in SyncService, never anywhere else.
+ *
+ * <p>The system calls onPerformSync() via an RPC call through the IBinder object supplied by
+ * SyncService.
+ */
+class SyncAdapter extends AbstractThreadedSyncAdapter {
+ public static final String TAG = "SyncAdapter";
+
+ /**
+ * URL to fetch content from during a sync.
+ *
+ * <p>This points to the Android Developers Blog. (Side note: We highly recommend reading the
+ * Android Developer Blog to stay up to date on the latest Android platform developments!)
+ */
+ private static final String FEED_URL = "http://android-developers.blogspot.com/atom.xml";
+
+ /**
+ * Network connection timeout, in milliseconds.
+ */
+ private static final int NET_CONNECT_TIMEOUT_MILLIS = 15000; // 15 seconds
+
+ /**
+ * Network read timeout, in milliseconds.
+ */
+ private static final int NET_READ_TIMEOUT_MILLIS = 10000; // 10 seconds
+
+ /**
+ * Content resolver, for performing database operations.
+ */
+ private final ContentResolver mContentResolver;
+
+ /**
+ * Project used when querying content provider. Returns all known fields.
+ */
+ private static final String[] PROJECTION = new String[] {
+ FeedContract.Entry._ID,
+ FeedContract.Entry.COLUMN_NAME_ENTRY_ID,
+ FeedContract.Entry.COLUMN_NAME_TITLE,
+ FeedContract.Entry.COLUMN_NAME_LINK,
+ FeedContract.Entry.COLUMN_NAME_PUBLISHED};
+
+ // Constants representing column positions from PROJECTION.
+ public static final int COLUMN_ID = 0;
+ public static final int COLUMN_ENTRY_ID = 1;
+ public static final int COLUMN_TITLE = 2;
+ public static final int COLUMN_LINK = 3;
+ public static final int COLUMN_PUBLISHED = 4;
+
+ /**
+ * Constructor. Obtains handle to content resolver for later use.
+ */
+ public SyncAdapter(Context context, boolean autoInitialize) {
+ super(context, autoInitialize);
+ mContentResolver = context.getContentResolver();
+ }
+
+ /**
+ * Constructor. Obtains handle to content resolver for later use.
+ */
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
+ super(context, autoInitialize, allowParallelSyncs);
+ mContentResolver = context.getContentResolver();
+ }
+
+ /**
+ * Called by the Android system in response to a request to run the sync adapter. The work
+ * required to read data from the network, parse it, and store it in the content provider is
+ * done here. Extending AbstractThreadedSyncAdapter ensures that all methods within SyncAdapter
+ * run on a background thread. For this reason, blocking I/O and other long-running tasks can be
+ * run <em>in situ</em>, and you don't have to set up a separate thread for them.
+ .
+ *
+ * <p>This is where we actually perform any work required to perform a sync.
+ * {@link android.content.AbstractThreadedSyncAdapter} guarantees that this will be called on a non-UI thread,
+ * so it is safe to peform blocking I/O here.
+ *
+ * <p>The syncResult argument allows you to pass information back to the method that triggered
+ * the sync.
+ */
+ @Override
+ public void onPerformSync(Account account, Bundle extras, String authority,
+ ContentProviderClient provider, SyncResult syncResult) {
+ Log.i(TAG, "Beginning network synchronization");
+ try {
+ final URL location = new URL(FEED_URL);
+ InputStream stream = null;
+
+ try {
+ Log.i(TAG, "Streaming data from network: " + location);
+ stream = downloadUrl(location);
+ updateLocalFeedData(stream, syncResult);
+ // Makes sure that the InputStream is closed after the app is
+ // finished using it.
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ } catch (MalformedURLException e) {
+ Log.e(TAG, "Feed URL is malformed", e);
+ syncResult.stats.numParseExceptions++;
+ return;
+ } catch (IOException e) {
+ Log.e(TAG, "Error reading from network: " + e.toString());
+ syncResult.stats.numIoExceptions++;
+ return;
+ } catch (XmlPullParserException e) {
+ Log.e(TAG, "Error parsing feed: " + e.toString());
+ syncResult.stats.numParseExceptions++;
+ return;
+ } catch (ParseException e) {
+ Log.e(TAG, "Error parsing feed: " + e.toString());
+ syncResult.stats.numParseExceptions++;
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error updating database: " + e.toString());
+ syncResult.databaseError = true;
+ return;
+ } catch (OperationApplicationException e) {
+ Log.e(TAG, "Error updating database: " + e.toString());
+ syncResult.databaseError = true;
+ return;
+ }
+ Log.i(TAG, "Network synchronization complete");
+ }
+
+ /**
+ * Read XML from an input stream, storing it into the content provider.
+ *
+ * <p>This is where incoming data is persisted, committing the results of a sync. In order to
+ * minimize (expensive) disk operations, we compare incoming data with what's already in our
+ * database, and compute a merge. Only changes (insert/update/delete) will result in a database
+ * write.
+ *
+ * <p>As an additional optimization, we use a batch operation to perform all database writes at
+ * once.
+ *
+ * <p>Merge strategy:
+ * 1. Get cursor to all items in feed<br/>
+ * 2. For each item, check if it's in the incoming data.<br/>
+ * a. YES: Remove from "incoming" list. Check if data has mutated, if so, perform
+ * database UPDATE.<br/>
+ * b. NO: Schedule DELETE from database.<br/>
+ * (At this point, incoming database only contains missing items.)<br/>
+ * 3. For any items remaining in incoming list, ADD to database.
+ */
+ public void updateLocalFeedData(final InputStream stream, final SyncResult syncResult)
+ throws IOException, XmlPullParserException, RemoteException,
+ OperationApplicationException, ParseException {
+ final FeedParser feedParser = new FeedParser();
+ final ContentResolver contentResolver = getContext().getContentResolver();
+
+ Log.i(TAG, "Parsing stream as Atom feed");
+ final List<FeedParser.Entry> entries = feedParser.parse(stream);
+ Log.i(TAG, "Parsing complete. Found " + entries.size() + " entries");
+
+
+ ArrayList<ContentProviderOperation> batch = new ArrayList<ContentProviderOperation>();
+
+ // Build hash table of incoming entries
+ HashMap<String, FeedParser.Entry> entryMap = new HashMap<String, FeedParser.Entry>();
+ for (FeedParser.Entry e : entries) {
+ entryMap.put(e.id, e);
+ }
+
+ // Get list of all items
+ Log.i(TAG, "Fetching local entries for merge");
+ Uri uri = FeedContract.Entry.CONTENT_URI; // Get all entries
+ Cursor c = contentResolver.query(uri, PROJECTION, null, null, null);
+ assert c != null;
+ Log.i(TAG, "Found " + c.getCount() + " local entries. Computing merge solution...");
+
+ // Find stale data
+ int id;
+ String entryId;
+ String title;
+ String link;
+ long published;
+ while (c.moveToNext()) {
+ syncResult.stats.numEntries++;
+ id = c.getInt(COLUMN_ID);
+ entryId = c.getString(COLUMN_ENTRY_ID);
+ title = c.getString(COLUMN_TITLE);
+ link = c.getString(COLUMN_LINK);
+ published = c.getLong(COLUMN_PUBLISHED);
+ FeedParser.Entry match = entryMap.get(entryId);
+ if (match != null) {
+ // Entry exists. Remove from entry map to prevent insert later.
+ entryMap.remove(entryId);
+ // Check to see if the entry needs to be updated
+ Uri existingUri = FeedContract.Entry.CONTENT_URI.buildUpon()
+ .appendPath(Integer.toString(id)).build();
+ if ((match.title != null && !match.title.equals(title)) ||
+ (match.link != null && !match.link.equals(link)) ||
+ (match.published != published)) {
+ // Update existing record
+ Log.i(TAG, "Scheduling update: " + existingUri);
+ batch.add(ContentProviderOperation.newUpdate(existingUri)
+ .withValue(FeedContract.Entry.COLUMN_NAME_TITLE, title)
+ .withValue(FeedContract.Entry.COLUMN_NAME_LINK, link)
+ .withValue(FeedContract.Entry.COLUMN_NAME_PUBLISHED, published)
+ .build());
+ syncResult.stats.numUpdates++;
+ } else {
+ Log.i(TAG, "No action: " + existingUri);
+ }
+ } else {
+ // Entry doesn't exist. Remove it from the database.
+ Uri deleteUri = FeedContract.Entry.CONTENT_URI.buildUpon()
+ .appendPath(Integer.toString(id)).build();
+ Log.i(TAG, "Scheduling delete: " + deleteUri);
+ batch.add(ContentProviderOperation.newDelete(deleteUri).build());
+ syncResult.stats.numDeletes++;
+ }
+ }
+ c.close();
+
+ // Add new items
+ for (FeedParser.Entry e : entryMap.values()) {
+ Log.i(TAG, "Scheduling insert: entry_id=" + e.id);
+ batch.add(ContentProviderOperation.newInsert(FeedContract.Entry.CONTENT_URI)
+ .withValue(FeedContract.Entry.COLUMN_NAME_ENTRY_ID, e.id)
+ .withValue(FeedContract.Entry.COLUMN_NAME_TITLE, e.title)
+ .withValue(FeedContract.Entry.COLUMN_NAME_LINK, e.link)
+ .withValue(FeedContract.Entry.COLUMN_NAME_PUBLISHED, e.published)
+ .build());
+ syncResult.stats.numInserts++;
+ }
+ Log.i(TAG, "Merge solution ready. Applying batch update");
+ mContentResolver.applyBatch(FeedContract.CONTENT_AUTHORITY, batch);
+ mContentResolver.notifyChange(
+ FeedContract.Entry.CONTENT_URI, // URI where data was modified
+ null, // No local observer
+ false); // IMPORTANT: Do not sync to network
+ // This sample doesn't support uploads, but if *your* code does, make sure you set
+ // syncToNetwork=false in the line above to prevent duplicate syncs.
+ }
+
+ /**
+ * Given a string representation of a URL, sets up a connection and gets an input stream.
+ */
+ private InputStream downloadUrl(final URL url) throws IOException {
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setReadTimeout(NET_READ_TIMEOUT_MILLIS /* milliseconds */);
+ conn.setConnectTimeout(NET_CONNECT_TIMEOUT_MILLIS /* milliseconds */);
+ conn.setRequestMethod("GET");
+ conn.setDoInput(true);
+ // Starts the query
+ conn.connect();
+ return conn.getInputStream();
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncService.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncService.java
new file mode 100644
index 0000000..41e9c03
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncService.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * 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.basicsyncadapter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+/** Service to handle sync requests.
+ *
+ * <p>This service is invoked in response to Intents with action android.content.SyncAdapter, and
+ * returns a Binder connection to SyncAdapter.
+ *
+ * <p>For performance, only one sync adapter will be initialized within this application's context.
+ *
+ * <p>Note: The SyncService itself is not notified when a new sync occurs. It's role is to
+ * manage the lifecycle of our {@link SyncAdapter} and provide a handle to said SyncAdapter to the
+ * OS on request.
+ */
+public class SyncService extends Service {
+ private static final String TAG = "SyncService";
+
+ private static final Object sSyncAdapterLock = new Object();
+ private static SyncAdapter sSyncAdapter = null;
+
+ /**
+ * Thread-safe constructor, creates static {@link SyncAdapter} instance.
+ */
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Log.i(TAG, "Service created");
+ synchronized (sSyncAdapterLock) {
+ if (sSyncAdapter == null) {
+ sSyncAdapter = new SyncAdapter(getApplicationContext(), true);
+ }
+ }
+ }
+
+ @Override
+ /**
+ * Logging-only destructor.
+ */
+ public void onDestroy() {
+ super.onDestroy();
+ Log.i(TAG, "Service destroyed");
+ }
+
+ /**
+ * Return Binder handle for IPC communication with {@link SyncAdapter}.
+ *
+ * <p>New sync requests will be sent directly to the SyncAdapter using this channel.
+ *
+ * @param intent Calling intent
+ * @return Binder handle for {@link SyncAdapter}
+ */
+ @Override
+ public IBinder onBind(Intent intent) {
+ return sSyncAdapter.getSyncAdapterBinder();
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncUtils.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncUtils.java
new file mode 100644
index 0000000..b327c72
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/SyncUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * 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.basicsyncadapter;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.annotation.TargetApi;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+
+import com.example.android.common.accounts.GenericAccountService;
+import com.example.android.basicsyncadapter.provider.FeedContract;
+
+/**
+ * Static helper methods for working with the sync framework.
+ */
+public class SyncUtils {
+ private static final long SYNC_FREQUENCY = 60 * 60; // 1 hour (in seconds)
+ private static final String CONTENT_AUTHORITY = FeedContract.CONTENT_AUTHORITY;
+ private static final String PREF_SETUP_COMPLETE = "setup_complete";
+ // Value below must match the account type specified in res/xml/syncadapter.xml
+ public static final String ACCOUNT_TYPE = "com.example.android.basicsyncadapter.account";
+
+ /**
+ * Create an entry for this application in the system account list, if it isn't already there.
+ *
+ * @param context Context
+ */
+ @TargetApi(Build.VERSION_CODES.FROYO)
+ public static void CreateSyncAccount(Context context) {
+ boolean newAccount = false;
+ boolean setupComplete = PreferenceManager
+ .getDefaultSharedPreferences(context).getBoolean(PREF_SETUP_COMPLETE, false);
+
+ // Create account, if it's missing. (Either first run, or user has deleted account.)
+ Account account = GenericAccountService.GetAccount(ACCOUNT_TYPE);
+ AccountManager accountManager =
+ (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
+ if (accountManager.addAccountExplicitly(account, null, null)) {
+ // Inform the system that this account supports sync
+ ContentResolver.setIsSyncable(account, CONTENT_AUTHORITY, 1);
+ // Inform the system that this account is eligible for auto sync when the network is up
+ ContentResolver.setSyncAutomatically(account, CONTENT_AUTHORITY, true);
+ // Recommend a schedule for automatic synchronization. The system may modify this based
+ // on other scheduled syncs and network utilization.
+ ContentResolver.addPeriodicSync(
+ account, CONTENT_AUTHORITY, new Bundle(),SYNC_FREQUENCY);
+ newAccount = true;
+ }
+
+ // Schedule an initial sync if we detect problems with either our account or our local
+ // data has been deleted. (Note that it's possible to clear app data WITHOUT affecting
+ // the account list, so wee need to check both.)
+ if (newAccount || !setupComplete) {
+ TriggerRefresh();
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putBoolean(PREF_SETUP_COMPLETE, true).commit();
+ }
+ }
+
+ /**
+ * Helper method to trigger an immediate sync ("refresh").
+ *
+ * <p>This should only be used when we need to preempt the normal sync schedule. Typically, this
+ * means the user has pressed the "refresh" button.
+ *
+ * Note that SYNC_EXTRAS_MANUAL will cause an immediate sync, without any optimization to
+ * preserve battery life. If you know new data is available (perhaps via a GCM notification),
+ * but the user is not actively waiting for that data, you should omit this flag; this will give
+ * the OS additional freedom in scheduling your sync request.
+ */
+ public static void TriggerRefresh() {
+ Bundle b = new Bundle();
+ // Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
+ b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+ b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+ ContentResolver.requestSync(
+ GenericAccountService.GetAccount(ACCOUNT_TYPE), // Sync account
+ FeedContract.CONTENT_AUTHORITY, // Content authority
+ b); // Extras
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/net/FeedParser.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/net/FeedParser.java
new file mode 100644
index 0000000..a778390
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/net/FeedParser.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2013 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.basicsyncadapter.net;
+
+import android.text.format.Time;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class parses generic Atom feeds.
+ *
+ * <p>Given an InputStream representation of a feed, it returns a List of entries,
+ * where each list element represents a single entry (post) in the XML feed.
+ *
+ * <p>An example of an Atom feed can be found at:
+ * http://en.wikipedia.org/w/index.php?title=Atom_(standard)&oldid=560239173#Example_of_an_Atom_1.0_feed
+ */
+public class FeedParser {
+
+ // Constants indicting XML element names that we're interested in
+ private static final int TAG_ID = 1;
+ private static final int TAG_TITLE = 2;
+ private static final int TAG_PUBLISHED = 3;
+ private static final int TAG_LINK = 4;
+
+ // We don't use XML namespaces
+ private static final String ns = null;
+
+ /** Parse an Atom feed, returning a collection of Entry objects.
+ *
+ * @param in Atom feed, as a stream.
+ * @return List of {@link com.example.android.basicsyncadapter.net.FeedParser.Entry} objects.
+ * @throws org.xmlpull.v1.XmlPullParserException on error parsing feed.
+ * @throws java.io.IOException on I/O error.
+ */
+ public List<Entry> parse(InputStream in)
+ throws XmlPullParserException, IOException, ParseException {
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
+ parser.setInput(in, null);
+ parser.nextTag();
+ return readFeed(parser);
+ } finally {
+ in.close();
+ }
+ }
+
+ /**
+ * Decode a feed attached to an XmlPullParser.
+ *
+ * @param parser Incoming XMl
+ * @return List of {@link com.example.android.basicsyncadapter.net.FeedParser.Entry} objects.
+ * @throws org.xmlpull.v1.XmlPullParserException on error parsing feed.
+ * @throws java.io.IOException on I/O error.
+ */
+ private List<Entry> readFeed(XmlPullParser parser)
+ throws XmlPullParserException, IOException, ParseException {
+ List<Entry> entries = new ArrayList<Entry>();
+
+ // Search for <feed> tags. These wrap the beginning/end of an Atom document.
+ //
+ // Example:
+ // <?xml version="1.0" encoding="utf-8"?>
+ // <feed xmlns="http://www.w3.org/2005/Atom">
+ // ...
+ // </feed>
+ parser.require(XmlPullParser.START_TAG, ns, "feed");
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ String name = parser.getName();
+ // Starts by looking for the <entry> tag. This tag repeates inside of <feed> for each
+ // article in the feed.
+ //
+ // Example:
+ // <entry>
+ // <title>Article title</title>
+ // <link rel="alternate" type="text/html" href="http://example.com/article/1234"/>
+ // <link rel="edit" href="http://example.com/admin/article/1234"/>
+ // <id>urn:uuid:218AC159-7F68-4CC6-873F-22AE6017390D</id>
+ // <published>2003-06-27T12:00:00Z</published>
+ // <updated>2003-06-28T12:00:00Z</updated>
+ // <summary>Article summary goes here.</summary>
+ // <author>
+ // <name>Rick Deckard</name>
+ // <email>deckard@example.com</email>
+ // </author>
+ // </entry>
+ if (name.equals("entry")) {
+ entries.add(readEntry(parser));
+ } else {
+ skip(parser);
+ }
+ }
+ return entries;
+ }
+
+ /**
+ * Parses the contents of an entry. If it encounters a title, summary, or link tag, hands them
+ * off to their respective "read" methods for processing. Otherwise, skips the tag.
+ */
+ private Entry readEntry(XmlPullParser parser)
+ throws XmlPullParserException, IOException, ParseException {
+ parser.require(XmlPullParser.START_TAG, ns, "entry");
+ String id = null;
+ String title = null;
+ String link = null;
+ long publishedOn = 0;
+
+ while (parser.next() != XmlPullParser.END_TAG) {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+ String name = parser.getName();
+ if (name.equals("id")){
+ // Example: <id>urn:uuid:218AC159-7F68-4CC6-873F-22AE6017390D</id>
+ id = readTag(parser, TAG_ID);
+ } else if (name.equals("title")) {
+ // Example: <title>Article title</title>
+ title = readTag(parser, TAG_TITLE);
+ } else if (name.equals("link")) {
+ // Example: <link rel="alternate" type="text/html" href="http://example.com/article/1234"/>
+ //
+ // Multiple link types can be included. readAlternateLink() will only return
+ // non-null when reading an "alternate"-type link. Ignore other responses.
+ String tempLink = readTag(parser, TAG_LINK);
+ if (tempLink != null) {
+ link = tempLink;
+ }
+ } else if (name.equals("published")) {
+ // Example: <published>2003-06-27T12:00:00Z</published>
+ Time t = new Time();
+ t.parse3339(readTag(parser, TAG_PUBLISHED));
+ publishedOn = t.toMillis(false);
+ } else {
+ skip(parser);
+ }
+ }
+ return new Entry(id, title, link, publishedOn);
+ }
+
+ /**
+ * Process an incoming tag and read the selected value from it.
+ */
+ private String readTag(XmlPullParser parser, int tagType)
+ throws IOException, XmlPullParserException {
+ String tag = null;
+ String endTag = null;
+
+ switch (tagType) {
+ case TAG_ID:
+ return readBasicTag(parser, "id");
+ case TAG_TITLE:
+ return readBasicTag(parser, "title");
+ case TAG_PUBLISHED:
+ return readBasicTag(parser, "published");
+ case TAG_LINK:
+ return readAlternateLink(parser);
+ default:
+ throw new IllegalArgumentException("Unknown tag type: " + tagType);
+ }
+ }
+
+ /**
+ * Reads the body of a basic XML tag, which is guaranteed not to contain any nested elements.
+ *
+ * <p>You probably want to call readTag().
+ *
+ * @param parser Current parser object
+ * @param tag XML element tag name to parse
+ * @return Body of the specified tag
+ * @throws java.io.IOException
+ * @throws org.xmlpull.v1.XmlPullParserException
+ */
+ private String readBasicTag(XmlPullParser parser, String tag)
+ throws IOException, XmlPullParserException {
+ parser.require(XmlPullParser.START_TAG, ns, tag);
+ String result = readText(parser);
+ parser.require(XmlPullParser.END_TAG, ns, tag);
+ return result;
+ }
+
+ /**
+ * Processes link tags in the feed.
+ */
+ private String readAlternateLink(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ String link = null;
+ parser.require(XmlPullParser.START_TAG, ns, "link");
+ String tag = parser.getName();
+ String relType = parser.getAttributeValue(null, "rel");
+ if (relType.equals("alternate")) {
+ link = parser.getAttributeValue(null, "href");
+ }
+ while (true) {
+ if (parser.nextTag() == XmlPullParser.END_TAG) break;
+ // Intentionally break; consumes any remaining sub-tags.
+ }
+ return link;
+ }
+
+ /**
+ * For the tags title and summary, extracts their text values.
+ */
+ private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
+ String result = null;
+ if (parser.next() == XmlPullParser.TEXT) {
+ result = parser.getText();
+ parser.nextTag();
+ }
+ return result;
+ }
+
+ /**
+ * Skips tags the parser isn't interested in. Uses depth to handle nested tags. i.e.,
+ * if the next tag after a START_TAG isn't a matching END_TAG, it keeps going until it
+ * finds the matching END_TAG (as indicated by the value of "depth" being 0).
+ */
+ private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ throw new IllegalStateException();
+ }
+ int depth = 1;
+ while (depth != 0) {
+ switch (parser.next()) {
+ case XmlPullParser.END_TAG:
+ depth--;
+ break;
+ case XmlPullParser.START_TAG:
+ depth++;
+ break;
+ }
+ }
+ }
+
+ /**
+ * This class represents a single entry (post) in the XML feed.
+ *
+ * <p>It includes the data members "title," "link," and "summary."
+ */
+ public static class Entry {
+ public final String id;
+ public final String title;
+ public final String link;
+ public final long published;
+
+ Entry(String id, String title, String link, long published) {
+ this.id = id;
+ this.title = title;
+ this.link = link;
+ this.published = published;
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedContract.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedContract.java
new file mode 100644
index 0000000..e29ec48
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedContract.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2013 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.basicsyncadapter.provider;
+
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Field and table name constants for
+ * {@link com.example.android.basicsyncadapter.provider.FeedProvider}.
+ */
+public class FeedContract {
+ private FeedContract() {
+ }
+
+ /**
+ * Content provider authority.
+ */
+ public static final String CONTENT_AUTHORITY = "com.example.android.basicsyncadapter";
+
+ /**
+ * Base URI. (content://com.example.android.basicsyncadapter)
+ */
+ public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
+
+ /**
+ * Path component for "entry"-type resources..
+ */
+ private static final String PATH_ENTRIES = "entries";
+
+ /**
+ * Columns supported by "entries" records.
+ */
+ public static class Entry implements BaseColumns {
+ /**
+ * MIME type for lists of entries.
+ */
+ public static final String CONTENT_TYPE =
+ ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.basicsyncadapter.entries";
+ /**
+ * MIME type for individual entries.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.basicsyncadapter.entry";
+
+ /**
+ * Fully qualified URI for "entry" resources.
+ */
+ public static final Uri CONTENT_URI =
+ BASE_CONTENT_URI.buildUpon().appendPath(PATH_ENTRIES).build();
+
+ /**
+ * Table name where records are stored for "entry" resources.
+ */
+ public static final String TABLE_NAME = "entry";
+ /**
+ * Atom ID. (Note: Not to be confused with the database primary key, which is _ID.
+ */
+ public static final String COLUMN_NAME_ENTRY_ID = "entry_id";
+ /**
+ * Article title
+ */
+ public static final String COLUMN_NAME_TITLE = "title";
+ /**
+ * Article hyperlink. Corresponds to the rel="alternate" link in the
+ * Atom spec.
+ */
+ public static final String COLUMN_NAME_LINK = "link";
+ /**
+ * Date article was published.
+ */
+ public static final String COLUMN_NAME_PUBLISHED = "published";
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedProvider.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedProvider.java
new file mode 100644
index 0000000..80bf1d3
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/basicsyncadapter/provider/FeedProvider.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2013 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.basicsyncadapter.provider;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.net.Uri;
+
+import com.example.android.common.db.SelectionBuilder;
+
+public class FeedProvider extends ContentProvider {
+ FeedDatabase mDatabaseHelper;
+
+ /**
+ * Content authority for this provider.
+ */
+ private static final String AUTHORITY = FeedContract.CONTENT_AUTHORITY;
+
+ // The constants below represent individual URI routes, as IDs. Every URI pattern recognized by
+ // this ContentProvider is defined using sUriMatcher.addURI(), and associated with one of these
+ // IDs.
+ //
+ // When a incoming URI is run through sUriMatcher, it will be tested against the defined
+ // URI patterns, and the corresponding route ID will be returned.
+ /**
+ * URI ID for route: /entries
+ */
+ public static final int ROUTE_ENTRIES = 1;
+
+ /**
+ * URI ID for route: /entries/{ID}
+ */
+ public static final int ROUTE_ENTRIES_ID = 2;
+
+ /**
+ * UriMatcher, used to decode incoming URIs.
+ */
+ private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ static {
+ sUriMatcher.addURI(AUTHORITY, "entries", ROUTE_ENTRIES);
+ sUriMatcher.addURI(AUTHORITY, "entries/*", ROUTE_ENTRIES_ID);
+ }
+
+ @Override
+ public boolean onCreate() {
+ mDatabaseHelper = new FeedDatabase(getContext());
+ return true;
+ }
+
+ /**
+ * Determine the mime type for entries returned by a given URI.
+ */
+ @Override
+ public String getType(Uri uri) {
+ final int match = sUriMatcher.match(uri);
+ switch (match) {
+ case ROUTE_ENTRIES:
+ return FeedContract.Entry.CONTENT_TYPE;
+ case ROUTE_ENTRIES_ID:
+ return FeedContract.Entry.CONTENT_ITEM_TYPE;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ }
+
+ /**
+ * Perform a database query by URI.
+ *
+ * <p>Currently supports returning all entries (/entries) and individual entries by ID
+ * (/entries/{ID}).
+ */
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
+ SelectionBuilder builder = new SelectionBuilder();
+ int uriMatch = sUriMatcher.match(uri);
+ switch (uriMatch) {
+ case ROUTE_ENTRIES_ID:
+ // Return a single entry, by ID.
+ String id = uri.getLastPathSegment();
+ builder.where(FeedContract.Entry._ID + "=?", id);
+ case ROUTE_ENTRIES:
+ // Return all known entries.
+ builder.table(FeedContract.Entry.TABLE_NAME)
+ .where(selection, selectionArgs);
+ Cursor c = builder.query(db, projection, sortOrder);
+ // Note: Notification URI must be manually set here for loaders to correctly
+ // register ContentObservers.
+ Context ctx = getContext();
+ assert ctx != null;
+ c.setNotificationUri(ctx.getContentResolver(), uri);
+ return c;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ }
+
+ /**
+ * Insert a new entry into the database.
+ */
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+ assert db != null;
+ final int match = sUriMatcher.match(uri);
+ Uri result;
+ switch (match) {
+ case ROUTE_ENTRIES:
+ long id = db.insertOrThrow(FeedContract.Entry.TABLE_NAME, null, values);
+ result = Uri.parse(FeedContract.Entry.CONTENT_URI + "/" + id);
+ break;
+ case ROUTE_ENTRIES_ID:
+ throw new UnsupportedOperationException("Insert not supported on URI: " + uri);
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ // Send broadcast to registered ContentObservers, to refresh UI.
+ Context ctx = getContext();
+ assert ctx != null;
+ ctx.getContentResolver().notifyChange(uri, null, false);
+ return result;
+ }
+
+ /**
+ * Delete an entry by database by URI.
+ */
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ SelectionBuilder builder = new SelectionBuilder();
+ final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+ final int match = sUriMatcher.match(uri);
+ int count;
+ switch (match) {
+ case ROUTE_ENTRIES:
+ count = builder.table(FeedContract.Entry.TABLE_NAME)
+ .where(selection, selectionArgs)
+ .delete(db);
+ break;
+ case ROUTE_ENTRIES_ID:
+ String id = uri.getLastPathSegment();
+ count = builder.table(FeedContract.Entry.TABLE_NAME)
+ .where(FeedContract.Entry._ID + "=?", id)
+ .where(selection, selectionArgs)
+ .delete(db);
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ // Send broadcast to registered ContentObservers, to refresh UI.
+ Context ctx = getContext();
+ assert ctx != null;
+ ctx.getContentResolver().notifyChange(uri, null, false);
+ return count;
+ }
+
+ /**
+ * Update an etry in the database by URI.
+ */
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ SelectionBuilder builder = new SelectionBuilder();
+ final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
+ final int match = sUriMatcher.match(uri);
+ int count;
+ switch (match) {
+ case ROUTE_ENTRIES:
+ count = builder.table(FeedContract.Entry.TABLE_NAME)
+ .where(selection, selectionArgs)
+ .update(db, values);
+ break;
+ case ROUTE_ENTRIES_ID:
+ String id = uri.getLastPathSegment();
+ count = builder.table(FeedContract.Entry.TABLE_NAME)
+ .where(FeedContract.Entry._ID + "=?", id)
+ .where(selection, selectionArgs)
+ .update(db, values);
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown uri: " + uri);
+ }
+ Context ctx = getContext();
+ assert ctx != null;
+ ctx.getContentResolver().notifyChange(uri, null, false);
+ return count;
+ }
+
+ /**
+ * SQLite backend for @{link FeedProvider}.
+ *
+ * Provides access to an disk-backed, SQLite datastore which is utilized by FeedProvider. This
+ * database should never be accessed by other parts of the application directly.
+ */
+ static class FeedDatabase extends SQLiteOpenHelper {
+ /** Schema version. */
+ public static final int DATABASE_VERSION = 1;
+ /** Filename for SQLite file. */
+ public static final String DATABASE_NAME = "feed.db";
+
+ private static final String TYPE_TEXT = " TEXT";
+ private static final String TYPE_INTEGER = " INTEGER";
+ private static final String COMMA_SEP = ",";
+ /** SQL statement to create "entry" table. */
+ private static final String SQL_CREATE_ENTRIES =
+ "CREATE TABLE " + FeedContract.Entry.TABLE_NAME + " (" +
+ FeedContract.Entry._ID + " INTEGER PRIMARY KEY," +
+ FeedContract.Entry.COLUMN_NAME_ENTRY_ID + TYPE_TEXT + COMMA_SEP +
+ FeedContract.Entry.COLUMN_NAME_TITLE + TYPE_TEXT + COMMA_SEP +
+ FeedContract.Entry.COLUMN_NAME_LINK + TYPE_TEXT + COMMA_SEP +
+ FeedContract.Entry.COLUMN_NAME_PUBLISHED + TYPE_INTEGER + ")";
+
+ /** SQL statement to drop "entry" table. */
+ private static final String SQL_DELETE_ENTRIES =
+ "DROP TABLE IF EXISTS " + FeedContract.Entry.TABLE_NAME;
+
+ public FeedDatabase(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(SQL_CREATE_ENTRIES);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ // This database is only a cache for online data, so its upgrade policy is
+ // to simply to discard the data and start over
+ db.execSQL(SQL_DELETE_ENTRIES);
+ onCreate(db);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/accounts/GenericAccountService.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/accounts/GenericAccountService.java
new file mode 100644
index 0000000..0cd499a
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/accounts/GenericAccountService.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2013 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.common.accounts;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.NetworkErrorException;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+
+public class GenericAccountService extends Service {
+ private static final String TAG = "GenericAccountService";
+ public static final String ACCOUNT_NAME = "Account";
+ private Authenticator mAuthenticator;
+
+ /**
+ * Obtain a handle to the {@link android.accounts.Account} used for sync in this application.
+ *
+ * <p>It is important that the accountType specified here matches the value in your sync adapter
+ * configuration XML file for android.accounts.AccountAuthenticator (often saved in
+ * res/xml/syncadapter.xml). If this is not set correctly, you'll receive an error indicating
+ * that "caller uid XXXXX is different than the authenticator's uid".
+ *
+ * @param accountType AccountType defined in the configuration XML file for
+ * android.accounts.AccountAuthenticator (e.g. res/xml/syncadapter.xml).
+ * @return Handle to application's account (not guaranteed to resolve unless CreateSyncAccount()
+ * has been called)
+ */
+ public static Account GetAccount(String accountType) {
+ // Note: Normally the account name is set to the user's identity (username or email
+ // address). However, since we aren't actually using any user accounts, it makes more sense
+ // to use a generic string in this case.
+ //
+ // This string should *not* be localized. If the user switches locale, we would not be
+ // able to locate the old account, and may erroneously register multiple accounts.
+ final String accountName = ACCOUNT_NAME;
+ return new Account(accountName, accountType);
+ }
+
+ @Override
+ public void onCreate() {
+ Log.i(TAG, "Service created");
+ mAuthenticator = new Authenticator(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ Log.i(TAG, "Service destroyed");
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mAuthenticator.getIBinder();
+ }
+
+ public class Authenticator extends AbstractAccountAuthenticator {
+ public Authenticator(Context context) {
+ super(context);
+ }
+
+ @Override
+ public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ String s) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Bundle addAccount(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ String s, String s2, String[] strings, Bundle bundle)
+ throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ Account account, Bundle bundle)
+ throws NetworkErrorException {
+ return null;
+ }
+
+ @Override
+ public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ Account account, String s, Bundle bundle)
+ throws NetworkErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getAuthTokenLabel(String s) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ Account account, String s, Bundle bundle)
+ throws NetworkErrorException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse,
+ Account account, String[] strings)
+ throws NetworkErrorException {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+}
+
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/db/SelectionBuilder.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/db/SelectionBuilder.java
new file mode 100644
index 0000000..a1964c5
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/db/SelectionBuilder.java
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2013 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.
+ */
+
+/*
+ * Modifications:
+ * -Imported from AOSP frameworks/base/core/java/com/android/internal/content
+ * -Changed package name
+ */
+
+package com.example.android.common.db;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Helper for building selection clauses for {@link SQLiteDatabase}.
+ *
+ * <p>This class provides a convenient frontend for working with SQL. Instead of composing statements
+ * manually using string concatenation, method calls are used to construct the statement one
+ * clause at a time. These methods can be chained together.
+ *
+ * <p>If multiple where() statements are provided, they're combined using {@code AND}.
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * SelectionBuilder builder = new SelectionBuilder();
+ * Cursor c = builder.table(FeedContract.Entry.TABLE_NAME) // String TABLE_NAME = "entry"
+ * .where(FeedContract.Entry._ID + "=?", id); // String _ID = "_ID"
+ * .query(db, projection, sortOrder)
+ *
+ * </pre>
+ *
+ * <p>In this example, the table name and filters ({@code WHERE} clauses) are both explicitly
+ * specified via method call. SelectionBuilder takes care of issuing a "query" command to the
+ * database, and returns the resulting {@link Cursor} object.
+ *
+ * <p>Inner {@code JOIN}s can be accomplished using the mapToTable() function. The map() function
+ * can be used to create new columns based on arbitrary (SQL-based) criteria. In advanced usage,
+ * entire subqueries can be passed into the map() function.
+ *
+ * <p>Advanced example:
+ *
+ * <pre>
+ * // String SESSIONS_JOIN_BLOCKS_ROOMS = "sessions "
+ * // + "LEFT OUTER JOIN blocks ON sessions.block_id=blocks.block_id "
+ * // + "LEFT OUTER JOIN rooms ON sessions.room_id=rooms.room_id";
+ *
+ * // String Subquery.BLOCK_NUM_STARRED_SESSIONS =
+ * // "(SELECT COUNT(1) FROM "
+ * // + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
+ * // + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1)";
+ *
+ * String Subqery.BLOCK_SESSIONS_COUNT =
+ * Cursor c = builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
+ * .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
+ * .mapToTable(Sessions._ID, Tables.SESSIONS)
+ * .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
+ * .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
+ * .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
+ * .where(Qualified.SESSIONS_BLOCK_ID + "=?", blockId);
+ * </pre>
+ *
+ * <p>In this example, we have two different types of {@code JOIN}s: a left outer join using a
+ * modified table name (since this class doesn't directly support these), and an inner join using
+ * the mapToTable() function. The map() function is used to insert a count based on specific
+ * criteria, executed as a sub-query.
+ *
+ * This class is <em>not</em> thread safe.
+ */
+public class SelectionBuilder {
+ private static final String TAG = "basicsyncadapter";
+
+ private String mTable = null;
+ private Map<String, String> mProjectionMap = new HashMap<String, String>();
+ private StringBuilder mSelection = new StringBuilder();
+ private ArrayList<String> mSelectionArgs = new ArrayList<String>();
+
+ /**
+ * Reset any internal state, allowing this builder to be recycled.
+ *
+ * <p>Calling this method is more efficient than creating a new SelectionBuilder object.
+ *
+ * @return Fluent interface
+ */
+ public SelectionBuilder reset() {
+ mTable = null;
+ mSelection.setLength(0);
+ mSelectionArgs.clear();
+ return this;
+ }
+
+ /**
+ * Append the given selection clause to the internal state. Each clause is
+ * surrounded with parenthesis and combined using {@code AND}.
+ *
+ * <p>In the most basic usage, simply provide a selection in SQL {@code WHERE} statement format.
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * .where("blog_posts.category = 'PROGRAMMING');
+ * </pre>
+ *
+ * <p>User input should never be directly supplied as as part of the selection statement.
+ * Instead, use positional parameters in your selection statement, then pass the user input
+ * in via the selectionArgs parameter. This prevents SQL escape characters in user input from
+ * causing unwanted side effects. (Failure to follow this convention may have security
+ * implications.)
+ *
+ * <p>Positional parameters are specified using the '?' character.
+ *
+ * <p>Example:
+ * <pre>
+ * .where("blog_posts.title contains ?, userSearchString);
+ * </pre>
+ *
+ * @param selection SQL where statement
+ * @param selectionArgs Values to substitute for positional parameters ('?' characters in
+ * {@code selection} statement. Will be automatically escaped.
+ * @return Fluent interface
+ */
+ public SelectionBuilder where(String selection, String... selectionArgs) {
+ if (TextUtils.isEmpty(selection)) {
+ if (selectionArgs != null && selectionArgs.length > 0) {
+ throw new IllegalArgumentException(
+ "Valid selection required when including arguments=");
+ }
+
+ // Shortcut when clause is empty
+ return this;
+ }
+
+ if (mSelection.length() > 0) {
+ mSelection.append(" AND ");
+ }
+
+ mSelection.append("(").append(selection).append(")");
+ if (selectionArgs != null) {
+ Collections.addAll(mSelectionArgs, selectionArgs);
+ }
+
+ return this;
+ }
+
+ /**
+ * Table name to use for SQL {@code FROM} statement.
+ *
+ * <p>This method may only be called once. If multiple tables are required, concatenate them
+ * in SQL-format (typically comma-separated).
+ *
+ * <p>If you need to do advanced {@code JOIN}s, they can also be specified here.
+ *
+ * See also: mapToTable()
+ *
+ * @param table Table name
+ * @return Fluent interface
+ */
+ public SelectionBuilder table(String table) {
+ mTable = table;
+ return this;
+ }
+
+ /**
+ * Verify that a table name has been supplied using table().
+ *
+ * @throws IllegalStateException if table not set
+ */
+ private void assertTable() {
+ if (mTable == null) {
+ throw new IllegalStateException("Table not specified");
+ }
+ }
+
+ /**
+ * Perform an inner join.
+ *
+ * <p>Map columns from a secondary table onto the current result set. References to the column
+ * specified in {@code column} will be replaced with {@code table.column} in the SQL {@code
+ * SELECT} clause.
+ *
+ * @param column Column name to join on. Must be the same in both tables.
+ * @param table Secondary table to join.
+ * @return Fluent interface
+ */
+ public SelectionBuilder mapToTable(String column, String table) {
+ mProjectionMap.put(column, table + "." + column);
+ return this;
+ }
+
+ /**
+ * Create a new column based on custom criteria (such as aggregate functions).
+ *
+ * <p>This adds a new column to the result set, based upon custom criteria in SQL format. This
+ * is equivalent to the SQL statement: {@code SELECT toClause AS fromColumn}
+ *
+ * <p>This method is useful for executing SQL sub-queries.
+ *
+ * @param fromColumn Name of column for mapping
+ * @param toClause SQL string representing data to be mapped
+ * @return Fluent interface
+ */
+ public SelectionBuilder map(String fromColumn, String toClause) {
+ mProjectionMap.put(fromColumn, toClause + " AS " + fromColumn);
+ return this;
+ }
+
+ /**
+ * Return selection string based on current internal state.
+ *
+ * @return Current selection as a SQL statement
+ * @see #getSelectionArgs()
+ */
+ public String getSelection() {
+ return mSelection.toString();
+
+ }
+
+ /**
+ * Return selection arguments based on current internal state.
+ *
+ * @see #getSelection()
+ */
+ public String[] getSelectionArgs() {
+ return mSelectionArgs.toArray(new String[mSelectionArgs.size()]);
+ }
+
+ /**
+ * Process user-supplied projection (column list).
+ *
+ * <p>In cases where a column is mapped to another data source (either another table, or an
+ * SQL sub-query), the column name will be replaced with a more specific, SQL-compatible
+ * representation.
+ *
+ * Assumes that incoming columns are non-null.
+ *
+ * <p>See also: map(), mapToTable()
+ *
+ * @param columns User supplied projection (column list).
+ */
+ private void mapColumns(String[] columns) {
+ for (int i = 0; i < columns.length; i++) {
+ final String target = mProjectionMap.get(columns[i]);
+ if (target != null) {
+ columns[i] = target;
+ }
+ }
+ }
+
+ /**
+ * Return a description of this builder's state. Does NOT output SQL.
+ *
+ * @return Human-readable internal state
+ */
+ @Override
+ public String toString() {
+ return "SelectionBuilder[table=" + mTable + ", selection=" + getSelection()
+ + ", selectionArgs=" + Arrays.toString(getSelectionArgs()) + "]";
+ }
+
+ /**
+ * Execute query (SQL {@code SELECT}) against specified database.
+ *
+ * <p>Using a null projection (column list) is not supported.
+ *
+ * @param db Database to query.
+ * @param columns Database projection (column list) to return, must be non-NULL.
+ * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the
+ * ORDER BY itself). Passing null will use the default sort order, which may be
+ * unordered.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ */
+ public Cursor query(SQLiteDatabase db, String[] columns, String orderBy) {
+ return query(db, columns, null, null, orderBy, null);
+ }
+
+ /**
+ * Execute query ({@code SELECT}) against database.
+ *
+ * <p>Using a null projection (column list) is not supported.
+ *
+ * @param db Database to query.
+ * @param columns Database projection (column list) to return, must be non-null.
+ * @param groupBy A filter declaring how to group rows, formatted as an SQL GROUP BY clause
+ * (excluding the GROUP BY itself). Passing null will cause the rows to not be
+ * grouped.
+ * @param having A filter declare which row groups to include in the cursor, if row grouping is
+ * being used, formatted as an SQL HAVING clause (excluding the HAVING itself).
+ * Passing null will cause all row groups to be included, and is required when
+ * row grouping is not being used.
+ * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause (excluding the
+ * ORDER BY itself). Passing null will use the default sort order, which may be
+ * unordered.
+ * @param limit Limits the number of rows returned by the query, formatted as LIMIT clause.
+ * Passing null denotes no LIMIT clause.
+ * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+ * {@link Cursor}s are not synchronized, see the documentation for more details.
+ */
+ public Cursor query(SQLiteDatabase db, String[] columns, String groupBy,
+ String having, String orderBy, String limit) {
+ assertTable();
+ if (columns != null) mapColumns(columns);
+ Log.v(TAG, "query(columns=" + Arrays.toString(columns) + ") " + this);
+ return db.query(mTable, columns, getSelection(), getSelectionArgs(), groupBy, having,
+ orderBy, limit);
+ }
+
+ /**
+ * Execute an {@code UPDATE} against database.
+ *
+ * @param db Database to query.
+ * @param values A map from column names to new column values. null is a valid value that will
+ * be translated to NULL
+ * @return The number of rows affected.
+ */
+ public int update(SQLiteDatabase db, ContentValues values) {
+ assertTable();
+ Log.v(TAG, "update() " + this);
+ return db.update(mTable, values, getSelection(), getSelectionArgs());
+ }
+
+ /**
+ * Execute {@code DELETE} against database.
+ *
+ * @param db Database to query.
+ * @return The number of rows affected.
+ */
+ public int delete(SQLiteDatabase db) {
+ assertTable();
+ Log.v(TAG, "delete() " + this);
+ return db.delete(mTable, getSelection(), getSelectionArgs());
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a0f7005
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..a085462
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_action_refresh.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
new file mode 100644
index 0000000..4f5d255
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_action_refresh.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..4f78eb8
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b198ee3
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/actionbar_indeterminate_progress.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/actionbar_indeterminate_progress.xml
new file mode 100644
index 0000000..b254013
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/actionbar_indeterminate_progress.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2012 Google Inc.
+
+ 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.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="@dimen/action_button_min_width"
+ android:minWidth="@dimen/action_button_min_width">
+
+ <ProgressBar android:layout_width="@dimen/indeterminate_progress_size"
+ android:layout_height="@dimen/indeterminate_progress_size"
+ android:layout_gravity="center"
+ style="?indeterminateProgressStyle" />
+</FrameLayout>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_entry_list.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_entry_list.xml
new file mode 100644
index 0000000..3c8c901
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_entry_list.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/entry_list"
+ android:name="com.example.android.basicsyncadapter.EntryListFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ tools:context=".EntryListActivity"
+ tools:layout="@android:layout/list_content" />
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/menu/main.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..63ad3d1
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/menu/main.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_refresh"
+ android:icon="@drawable/ic_action_refresh"
+ android:title="@string/description_refresh"
+ android:orderInCategory="1"
+ android:showAsAction="always" />
+</menu>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/attrs.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..6c15504
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/attrs.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<resources>
+ <!-- Specifies a style resource to use for an indeterminate progress spinner. -->
+ <attr name="indeterminateProgressStyle" format="reference"/>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..2670484
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BasicSyncAdapter</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates using SyncAdapter to fetch background data for an app that
+ doesn\'t require a user-visible account type or 2-way synchronization.
+
+ \n\nThis sample periodically downloads the feed from the Android Developer Blog and
+ caches the data in a content provider. At runtime, the cached feed data is displayed
+ inside a ListView.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/dimen.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/dimen.xml
new file mode 100644
index 0000000..d838c69
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/dimen.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<resources>
+ <dimen name="action_button_min_width">56dp</dimen>
+ <dimen name="indeterminate_progress_size">32dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/strings.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f4cade9
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<resources>
+ <string name="account_name">FeedSync Service</string>
+ <string name="title_entry_detail">Entry Detail</string>
+ <string name="loading">Waiting for sync...</string>
+ <string name="description_refresh">Refresh</string>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/authenticator.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/authenticator.xml
new file mode 100644
index 0000000..8b96907
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/authenticator.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
+ android:accountType="com.example.android.basicsyncadapter.account"
+ android:icon="@drawable/ic_launcher"
+ android:smallIcon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ />
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/syncadapter.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/syncadapter.xml
new file mode 100644
index 0000000..6e12882
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/src/main/res/xml/syncadapter.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
+ android:contentAuthority="com.example.android.basicsyncadapter"
+ android:accountType="com.example.android.basicsyncadapter.account"
+ android:userVisible="false"
+ android:supportsUploading="false"
+ android:allowParallelSyncs="false"
+ android:isAlwaysSyncable="true"
+ />
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/AndroidManifest.xml b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..44c910a
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.basicsyncadapter.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.basicsyncadapter"
+ android:label="Tests for com.example.android.basicsyncadapter" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/src/com/example/android/basicsyncadapter/tests/SampleTests.java b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/src/com/example/android/basicsyncadapter/tests/SampleTests.java
new file mode 100644
index 0000000..08798ba
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/BasicSyncAdapterSample/tests/src/com/example/android/basicsyncadapter/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.basicsyncadapter.tests;
+
+import com.example.android.basicsyncadapter.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for BasicSyncAdapter sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private BasicSyncAdapterFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (BasicSyncAdapterFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BasicSyncAdapter/README.txt b/prebuilts/gradle/BasicSyncAdapter/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BasicSyncAdapter/build.gradle b/prebuilts/gradle/BasicSyncAdapter/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BasicSyncAdapter/gradlew b/prebuilts/gradle/BasicSyncAdapter/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BasicSyncAdapter/gradlew.bat b/prebuilts/gradle/BasicSyncAdapter/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BasicSyncAdapter/settings.gradle b/prebuilts/gradle/BasicSyncAdapter/settings.gradle
new file mode 100644
index 0000000..a691e9e
--- /dev/null
+++ b/prebuilts/gradle/BasicSyncAdapter/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BasicSyncAdapterSample'
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/build.gradle b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/build.gradle
new file mode 100644
index 0000000..f73b206
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 19
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..2c4e4f2
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.batchstepsensor"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- This sample requires at least Android KitKat for sensor batching support -->
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+
+ <!-- Require the step counter and step detector sensors.
+ See the method BatchStepSensorFragment#isKitkatWithStepSensor() for a programmatic check if
+ support is optional and the application supports a case where these sensors are not available.
+ -->
+ <uses-feature android:name="android.hardware.sensor.stepcounter" />
+ <uses-feature android:name="android.hardware.sensor.stepdetector" />
+
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/BatchStepSensorFragment.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/BatchStepSensorFragment.java
new file mode 100644
index 0000000..aab0fc3
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/BatchStepSensorFragment.java
@@ -0,0 +1,588 @@
+/*
+* Copyright 2014 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package com.example.android.batchstepsensor;
+
+import android.app.Activity;
+import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+import com.example.android.common.logger.Log;
+
+public class BatchStepSensorFragment extends Fragment implements OnCardClickListener {
+
+ public static final String TAG = "StepSensorSample";
+ // Cards
+ private CardStreamFragment mCards = null;
+
+ // Card tags
+ public static final String CARD_INTRO = "intro";
+ public static final String CARD_REGISTER_DETECTOR = "register_detector";
+ public static final String CARD_REGISTER_COUNTER = "register_counter";
+ public static final String CARD_BATCHING_DESCRIPTION = "register_batching_description";
+ public static final String CARD_COUNTING = "counting";
+ public static final String CARD_EXPLANATION = "explanation";
+ public static final String CARD_NOBATCHSUPPORT = "error";
+
+ // Actions from REGISTER cards
+ public static final int ACTION_REGISTER_DETECT_NOBATCHING = 10;
+ public static final int ACTION_REGISTER_DETECT_BATCHING_5s = 11;
+ public static final int ACTION_REGISTER_DETECT_BATCHING_10s = 12;
+ public static final int ACTION_REGISTER_COUNT_NOBATCHING = 21;
+ public static final int ACTION_REGISTER_COUNT_BATCHING_5s = 22;
+ public static final int ACTION_REGISTER_COUNT_BATCHING_10s = 23;
+ // Action from COUNTING card
+ public static final int ACTION_UNREGISTER = 1;
+ // Actions from description cards
+ private static final int ACTION_BATCHING_DESCRIPTION_DISMISS = 2;
+ private static final int ACTION_EXPLANATION_DISMISS = 3;
+
+ // State of application, used to register for sensors when app is restored
+ public static final int STATE_OTHER = 0;
+ public static final int STATE_COUNTER = 1;
+ public static final int STATE_DETECTOR = 2;
+
+ // Bundle tags used to store data when restoring application state
+ private static final String BUNDLE_STATE = "state";
+ private static final String BUNDLE_LATENCY = "latency";
+ private static final String BUNDLE_STEPS = "steps";
+
+ // max batch latency is specified in microseconds
+ private static final int BATCH_LATENCY_0 = 0; // no batching
+ private static final int BATCH_LATENCY_10s = 10000000;
+ private static final int BATCH_LATENCY_5s = 5000000;
+
+ /*
+ For illustration we keep track of the last few events and show their delay from when the
+ event occurred until it was received by the event listener.
+ These variables keep track of the list of timestamps and the number of events.
+ */
+ // Number of events to keep in queue and display on card
+ private static final int EVENT_QUEUE_LENGTH = 10;
+ // List of timestamps when sensor events occurred
+ private float[] mEventDelays = new float[EVENT_QUEUE_LENGTH];
+
+ // number of events in event list
+ private int mEventLength = 0;
+ // pointer to next entry in sensor event list
+ private int mEventData = 0;
+
+ // Steps counted in current session
+ private int mSteps = 0;
+ // Value of the step counter sensor when the listener was registered.
+ // (Total steps are calculated from this value.)
+ private int mCounterSteps = 0;
+ // Steps counted by the step counter previously. Used to keep counter consistent across rotation
+ // changes
+ private int mPreviousCounterSteps = 0;
+ // State of the app (STATE_OTHER, STATE_COUNTER or STATE_DETECTOR)
+ private int mState = STATE_OTHER;
+ // When a listener is registered, the batch sensor delay in microseconds
+ private int mMaxDelay = 0;
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ CardStreamFragment stream = getCardStream();
+ if (stream.getVisibleCardCount() < 1) {
+ // No cards are visible, started for the first time
+ // Prepare all cards and show the intro card.
+ initialiseCards();
+ showIntroCard();
+ // Show the registration card if the hardware is supported, show an error otherwise
+ if (isKitkatWithStepSensor()) {
+ showRegisterCard();
+ } else {
+ showErrorCard();
+ }
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ // BEGIN_INCLUDE(onpause)
+ // Unregister the listener when the application is paused
+ unregisterListeners();
+ // END_INCLUDE(onpause)
+ }
+
+ /**
+ * Returns true if this device is supported. It needs to be running Android KitKat (4.4) or
+ * higher and has a step counter and step detector sensor.
+ * This check is useful when an app provides an alternative implementation or different
+ * functionality if the step sensors are not available or this code runs on a platform version
+ * below Android KitKat. If this functionality is required, then the minSDK parameter should
+ * be specified appropriately in the AndroidManifest.
+ *
+ * @return True iff the device can run this sample
+ */
+ private boolean isKitkatWithStepSensor() {
+ // BEGIN_INCLUDE(iskitkatsensor)
+ // Require at least Android KitKat
+ int currentApiVersion = android.os.Build.VERSION.SDK_INT;
+ // Check that the device supports the step counter and detector sensors
+ PackageManager packageManager = getActivity().getPackageManager();
+ return currentApiVersion >= android.os.Build.VERSION_CODES.KITKAT
+ && packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_COUNTER)
+ && packageManager.hasSystemFeature(PackageManager.FEATURE_SENSOR_STEP_DETECTOR);
+ // END_INCLUDE(iskitkatsensor)
+ }
+
+ /**
+ * Handles a click on a card action.
+ * Registers a SensorEventListener (see {@link #registerEventListener(int, int)}) with the
+ * selected delay, dismisses cards and unregisters the listener
+ * (see {@link #unregisterListeners()}).
+ * Actions are defined when a card is created.
+ *
+ * @param cardActionId
+ * @param cardTag
+ */
+ @Override
+ public void onCardClick(int cardActionId, String cardTag) {
+
+ switch (cardActionId) {
+ // BEGIN_INCLUDE(onclick)
+ // Register Step Counter card
+ case ACTION_REGISTER_COUNT_NOBATCHING:
+ registerEventListener(BATCH_LATENCY_0, Sensor.TYPE_STEP_COUNTER);
+ break;
+ case ACTION_REGISTER_COUNT_BATCHING_5s:
+ registerEventListener(BATCH_LATENCY_5s, Sensor.TYPE_STEP_COUNTER);
+ break;
+ case ACTION_REGISTER_COUNT_BATCHING_10s:
+ registerEventListener(BATCH_LATENCY_10s, Sensor.TYPE_STEP_COUNTER);
+ break;
+
+ // Register Step Detector card
+ case ACTION_REGISTER_DETECT_NOBATCHING:
+ registerEventListener(BATCH_LATENCY_0, Sensor.TYPE_STEP_DETECTOR);
+ break;
+ case ACTION_REGISTER_DETECT_BATCHING_5s:
+ registerEventListener(BATCH_LATENCY_5s, Sensor.TYPE_STEP_DETECTOR);
+ break;
+ case ACTION_REGISTER_DETECT_BATCHING_10s:
+ registerEventListener(BATCH_LATENCY_10s, Sensor.TYPE_STEP_DETECTOR);
+ break;
+
+ // Unregister card
+ case ACTION_UNREGISTER:
+ showRegisterCard();
+ unregisterListeners();
+ // reset the application state when explicitly unregistered
+ mState = STATE_OTHER;
+ break;
+ // END_INCLUDE(onclick)
+ // Explanation cards
+ case ACTION_BATCHING_DESCRIPTION_DISMISS:
+ // permanently remove the batch description card, it will not be shown again
+ getCardStream().removeCard(CARD_BATCHING_DESCRIPTION);
+ break;
+ case ACTION_EXPLANATION_DISMISS:
+ // permanently remove the explanation card, it will not be shown again
+ getCardStream().removeCard(CARD_EXPLANATION);
+ }
+
+ // For register cards, display the counting card
+ if (cardTag.equals(CARD_REGISTER_COUNTER) || cardTag.equals(CARD_REGISTER_DETECTOR)) {
+ showCountingCards();
+ }
+ }
+
+ /**
+ * Register a {@link android.hardware.SensorEventListener} for the sensor and max batch delay.
+ * The maximum batch delay specifies the maximum duration in microseconds for which subsequent
+ * sensor events can be temporarily stored by the sensor before they are delivered to the
+ * registered SensorEventListener. A larger delay allows the system to handle sensor events more
+ * efficiently, allowing the system to switch to a lower power state while the sensor is
+ * capturing events. Once the max delay is reached, all stored events are delivered to the
+ * registered listener. Note that this value only specifies the maximum delay, the listener may
+ * receive events quicker. A delay of 0 disables batch mode and registers the listener in
+ * continuous mode.
+ * The optimium batch delay depends on the application. For example, a delay of 5 seconds or
+ * higher may be appropriate for an application that does not update the UI in real time.
+ *
+ * @param maxdelay
+ * @param sensorType
+ */
+ private void registerEventListener(int maxdelay, int sensorType) {
+ // BEGIN_INCLUDE(register)
+
+ // Keep track of state so that the correct sensor type and batch delay can be set up when
+ // the app is restored (for example on screen rotation).
+ mMaxDelay = maxdelay;
+ if (sensorType == Sensor.TYPE_STEP_COUNTER) {
+ mState = STATE_COUNTER;
+ /*
+ Reset the initial step counter value, the first event received by the event listener is
+ stored in mCounterSteps and used to calculate the total number of steps taken.
+ */
+ mCounterSteps = 0;
+ Log.i(TAG, "Event listener for step counter sensor registered with a max delay of "
+ + mMaxDelay);
+ } else {
+ mState = STATE_DETECTOR;
+ Log.i(TAG, "Event listener for step detector sensor registered with a max delay of "
+ + mMaxDelay);
+ }
+
+ // Get the default sensor for the sensor type from the SenorManager
+ SensorManager sensorManager =
+ (SensorManager) getActivity().getSystemService(Activity.SENSOR_SERVICE);
+ // sensorType is either Sensor.TYPE_STEP_COUNTER or Sensor.TYPE_STEP_DETECTOR
+ Sensor sensor = sensorManager.getDefaultSensor(sensorType);
+
+ // Register the listener for this sensor in batch mode.
+ // If the max delay is 0, events will be delivered in continuous mode without batching.
+ final boolean batchMode = sensorManager.registerListener(
+ mListener, sensor, SensorManager.SENSOR_DELAY_NORMAL, maxdelay);
+
+ if (!batchMode) {
+ // Batch mode could not be enabled, show a warning message and switch to continuous mode
+ getCardStream().getCard(CARD_NOBATCHSUPPORT)
+ .setDescription(getString(R.string.warning_nobatching));
+ getCardStream().showCard(CARD_NOBATCHSUPPORT);
+ Log.w(TAG, "Could not register sensor listener in batch mode, " +
+ "falling back to continuous mode.");
+ }
+
+ if (maxdelay > 0 && batchMode) {
+ // Batch mode was enabled successfully, show a description card
+ getCardStream().showCard(CARD_BATCHING_DESCRIPTION);
+ }
+
+ // Show the explanation card
+ getCardStream().showCard(CARD_EXPLANATION);
+
+ // END_INCLUDE(register)
+
+ }
+
+ /**
+ * Unregisters the sensor listener if it is registered.
+ */
+ private void unregisterListeners() {
+ // BEGIN_INCLUDE(unregister)
+ SensorManager sensorManager =
+ (SensorManager) getActivity().getSystemService(Activity.SENSOR_SERVICE);
+ sensorManager.unregisterListener(mListener);
+ Log.i(TAG, "Sensor listener unregistered.");
+
+ // END_INCLUDE(unregister)
+ }
+
+ /**
+ * Resets the step counter by clearing all counting variables and lists.
+ */
+ private void resetCounter() {
+ // BEGIN_INCLUDE(reset)
+ mSteps = 0;
+ mCounterSteps = 0;
+ mEventLength = 0;
+ mEventDelays = new float[EVENT_QUEUE_LENGTH];
+ mPreviousCounterSteps = 0;
+ // END_INCLUDE(reset)
+ }
+
+
+ /**
+ * Listener that handles step sensor events for step detector and step counter sensors.
+ */
+ private final SensorEventListener mListener = new SensorEventListener() {
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ // BEGIN_INCLUDE(sensorevent)
+ // store the delay of this event
+ recordDelay(event);
+ final String delayString = getDelayString();
+
+ if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
+ // A step detector event is received for each step.
+ // This means we need to count steps ourselves
+
+ mSteps += event.values.length;
+
+ // Update the card with the latest step count
+ getCardStream().getCard(CARD_COUNTING)
+ .setTitle(getString(R.string.counting_title, mSteps))
+ .setDescription(getString(R.string.counting_description,
+ getString(R.string.sensor_detector), mMaxDelay, delayString));
+
+ Log.i(TAG,
+ "New step detected by STEP_DETECTOR sensor. Total step count: " + mSteps);
+
+ } else if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
+
+ /*
+ A step counter event contains the total number of steps since the listener
+ was first registered. We need to keep track of this initial value to calculate the
+ number of steps taken, as the first value a listener receives is undefined.
+ */
+ if (mCounterSteps < 1) {
+ // initial value
+ mCounterSteps = (int) event.values[0];
+ }
+
+ // Calculate steps taken based on first counter value received.
+ mSteps = (int) event.values[0] - mCounterSteps;
+
+ // Add the number of steps previously taken, otherwise the counter would start at 0.
+ // This is needed to keep the counter consistent across rotation changes.
+ mSteps = mSteps + mPreviousCounterSteps;
+
+ // Update the card with the latest step count
+ getCardStream().getCard(CARD_COUNTING)
+ .setTitle(getString(R.string.counting_title, mSteps))
+ .setDescription(getString(R.string.counting_description,
+ getString(R.string.sensor_counter), mMaxDelay, delayString));
+ Log.i(TAG, "New step detected by STEP_COUNTER sensor. Total step count: " + mSteps);
+ // END_INCLUDE(sensorevent)
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+ }
+ };
+
+ /**
+ * Records the delay for the event.
+ *
+ * @param event
+ */
+ private void recordDelay(SensorEvent event) {
+ // Calculate the delay from when event was recorded until it was received here in ms
+ // Event timestamp is recorded in us accuracy, but ms accuracy is sufficient here
+ mEventDelays[mEventData] = System.currentTimeMillis() - (event.timestamp / 1000000L);
+
+ // Increment length counter
+ mEventLength = Math.min(EVENT_QUEUE_LENGTH, mEventLength + 1);
+ // Move pointer to the next (oldest) location
+ mEventData = (mEventData + 1) % EVENT_QUEUE_LENGTH;
+ }
+
+ private final StringBuffer mDelayStringBuffer = new StringBuffer();
+
+ /**
+ * Returns a string describing the sensor delays recorded in
+ * {@link #recordDelay(android.hardware.SensorEvent)}.
+ *
+ * @return
+ */
+ private String getDelayString() {
+ // Empty the StringBuffer
+ mDelayStringBuffer.setLength(0);
+
+ // Loop over all recorded delays and append them to the buffer as a decimal
+ for (int i = 0; i < mEventLength; i++) {
+ if (i > 0) {
+ mDelayStringBuffer.append(", ");
+ }
+ final int index = (mEventData + i) % EVENT_QUEUE_LENGTH;
+ final float delay = mEventDelays[index] / 1000f; // convert delay from ms into s
+ mDelayStringBuffer.append(String.format("%1.1f", delay));
+ }
+
+ return mDelayStringBuffer.toString();
+ }
+
+ /**
+ * Records the state of the application into the {@link android.os.Bundle}.
+ *
+ * @param outState
+ */
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ // BEGIN_INCLUDE(saveinstance)
+ super.onSaveInstanceState(outState);
+ // Store all variables required to restore the state of the application
+ outState.putInt(BUNDLE_LATENCY, mMaxDelay);
+ outState.putInt(BUNDLE_STATE, mState);
+ outState.putInt(BUNDLE_STEPS, mSteps);
+ // END_INCLUDE(saveinstance)
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // BEGIN_INCLUDE(restore)
+ // Fragment is being restored, reinitialise its state with data from the bundle
+ if (savedInstanceState != null) {
+ resetCounter();
+ mSteps = savedInstanceState.getInt(BUNDLE_STEPS);
+ mState = savedInstanceState.getInt(BUNDLE_STATE);
+ mMaxDelay = savedInstanceState.getInt(BUNDLE_LATENCY);
+
+ // Register listeners again if in detector or counter states with restored delay
+ if (mState == STATE_DETECTOR) {
+ registerEventListener(mMaxDelay, Sensor.TYPE_STEP_DETECTOR);
+ } else if (mState == STATE_COUNTER) {
+ // store the previous number of steps to keep step counter count consistent
+ mPreviousCounterSteps = mSteps;
+ registerEventListener(mMaxDelay, Sensor.TYPE_STEP_COUNTER);
+ }
+ }
+ // END_INCLUDE(restore)
+ }
+
+ /**
+ * Hides the registration cards, reset the counter and show the step counting card.
+ */
+ private void showCountingCards() {
+ // Hide the registration cards
+ getCardStream().hideCard(CARD_REGISTER_DETECTOR);
+ getCardStream().hideCard(CARD_REGISTER_COUNTER);
+
+ // Show the explanation card if it has not been dismissed
+ getCardStream().showCard(CARD_EXPLANATION);
+
+ // Reset the step counter, then show the step counting card
+ resetCounter();
+
+ // Set the inital text for the step counting card before a step is recorded
+ String sensor = "-";
+ if (mState == STATE_COUNTER) {
+ sensor = getString(R.string.sensor_counter);
+ } else if (mState == STATE_DETECTOR) {
+ sensor = getString(R.string.sensor_detector);
+ }
+ // Set initial text
+ getCardStream().getCard(CARD_COUNTING)
+ .setTitle(getString(R.string.counting_title, 0))
+ .setDescription(getString(R.string.counting_description, sensor, mMaxDelay, "-"));
+
+ // Show the counting card and make it undismissable
+ getCardStream().showCard(CARD_COUNTING, false);
+
+ }
+
+ /**
+ * Show the introduction card
+ */
+ private void showIntroCard() {
+ Card c = new Card.Builder(this, CARD_INTRO)
+ .setTitle(getString(R.string.intro_title))
+ .setDescription(getString(R.string.intro_message))
+ .build(getActivity());
+ getCardStream().addCard(c, true);
+ }
+
+ /**
+ * Show two registration cards, one for the step detector and counter sensors.
+ */
+ private void showRegisterCard() {
+ // Hide the counting and explanation cards
+ getCardStream().hideCard(CARD_BATCHING_DESCRIPTION);
+ getCardStream().hideCard(CARD_EXPLANATION);
+ getCardStream().hideCard(CARD_COUNTING);
+
+ // Show two undismissable registration cards, one for each step sensor
+ getCardStream().showCard(CARD_REGISTER_DETECTOR, false);
+ getCardStream().showCard(CARD_REGISTER_COUNTER, false);
+ }
+
+ /**
+ * Show the error card.
+ */
+ private void showErrorCard() {
+ getCardStream().showCard(CARD_NOBATCHSUPPORT, false);
+ }
+
+ /**
+ * Initialise Cards.
+ */
+ private void initialiseCards() {
+ // Step counting
+ Card c = new Card.Builder(this, CARD_COUNTING)
+ .setTitle("Steps")
+ .setDescription("")
+ .addAction("Unregister Listener", ACTION_UNREGISTER, Card.ACTION_NEGATIVE)
+ .build(getActivity());
+ getCardStream().addCard(c);
+
+ // Register step detector listener
+ c = new Card.Builder(this, CARD_REGISTER_DETECTOR)
+ .setTitle(getString(R.string.register_detector_title))
+ .setDescription(getString(R.string.register_detector_description))
+ .addAction(getString(R.string.register_0),
+ ACTION_REGISTER_DETECT_NOBATCHING, Card.ACTION_NEUTRAL)
+ .addAction(getString(R.string.register_5),
+ ACTION_REGISTER_DETECT_BATCHING_5s, Card.ACTION_NEUTRAL)
+ .addAction(getString(R.string.register_10),
+ ACTION_REGISTER_DETECT_BATCHING_10s, Card.ACTION_NEUTRAL)
+ .build(getActivity());
+ getCardStream().addCard(c);
+
+ // Register step counter listener
+ c = new Card.Builder(this, CARD_REGISTER_COUNTER)
+ .setTitle(getString(R.string.register_counter_title))
+ .setDescription(getString(R.string.register_counter_description))
+ .addAction(getString(R.string.register_0),
+ ACTION_REGISTER_COUNT_NOBATCHING, Card.ACTION_NEUTRAL)
+ .addAction(getString(R.string.register_5),
+ ACTION_REGISTER_COUNT_BATCHING_5s, Card.ACTION_NEUTRAL)
+ .addAction(getString(R.string.register_10),
+ ACTION_REGISTER_COUNT_BATCHING_10s, Card.ACTION_NEUTRAL)
+ .build(getActivity());
+ getCardStream().addCard(c);
+
+
+ // Batching description
+ c = new Card.Builder(this, CARD_BATCHING_DESCRIPTION)
+ .setTitle(getString(R.string.batching_queue_title))
+ .setDescription(getString(R.string.batching_queue_description))
+ .addAction(getString(R.string.action_notagain),
+ ACTION_BATCHING_DESCRIPTION_DISMISS, Card.ACTION_POSITIVE)
+ .build(getActivity());
+ getCardStream().addCard(c);
+
+ // Explanation
+ c = new Card.Builder(this, CARD_EXPLANATION)
+ .setDescription(getString(R.string.explanation_description))
+ .addAction(getString(R.string.action_notagain),
+ ACTION_EXPLANATION_DISMISS, Card.ACTION_POSITIVE)
+ .build(getActivity());
+ getCardStream().addCard(c);
+
+ // Error
+ c = new Card.Builder(this, CARD_NOBATCHSUPPORT)
+ .setTitle(getString(R.string.error_title))
+ .setDescription(getString(R.string.error_nosensor))
+ .build(getActivity());
+ getCardStream().addCard(c);
+ }
+
+ /**
+ * Returns the cached CardStreamFragment used to show cards.
+ *
+ * @return
+ */
+ private CardStreamFragment getCardStream() {
+ if (mCards == null) {
+ mCards = ((CardStream) getActivity()).getCardStream();
+ }
+ return mCards;
+ }
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/Card.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/Card.java
new file mode 100644
index 0000000..fb885c7
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/Card.java
@@ -0,0 +1,750 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * A Card contains a description and has a visual state. Optionally a card also contains a title,
+ * progress indicator and zero or more actions. It is constructed through the {@link Builder}.
+ */
+public class Card {
+
+ public static final int ACTION_POSITIVE = 1;
+ public static final int ACTION_NEGATIVE = 2;
+ public static final int ACTION_NEUTRAL = 3;
+
+ public static final int PROGRESS_TYPE_NO_PROGRESS = 0;
+ public static final int PROGRESS_TYPE_NORMAL = 1;
+ public static final int PROGRESS_TYPE_INDETERMINATE = 2;
+ public static final int PROGRESS_TYPE_LABEL = 3;
+
+ private OnCardClickListener mClickListener;
+
+
+ // The card model contains a reference to its desired layout (for extensibility), title,
+ // description, zero to many action buttons, and zero or 1 progress indicators.
+ private int mLayoutId = R.layout.card;
+
+ /**
+ * Tag that uniquely identifies this card.
+ */
+ private String mTag = null;
+
+ private String mTitle = null;
+ private String mDescription = null;
+
+ private View mCardView = null;
+ private View mOverlayView = null;
+ private TextView mTitleView = null;
+ private TextView mDescView = null;
+ private View mActionAreaView = null;
+
+ private Animator mOngoingAnimator = null;
+
+ /**
+ * Visual state, either {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED} or
+ * {@link #CARD_STATE_INACTIVE}.
+ */
+ private int mCardState = CARD_STATE_NORMAL;
+ public static final int CARD_STATE_NORMAL = 1;
+ public static final int CARD_STATE_FOCUSED = 2;
+ public static final int CARD_STATE_INACTIVE = 3;
+
+ /**
+ * Represent actions that can be taken from the card. Stylistically the developer can
+ * designate the action as positive, negative (ok/cancel, for instance), or neutral.
+ * This "type" can be used as a UI hint.
+ * @see com.example.android.sensors.batchstepsensor.Card.CardAction
+ */
+ private ArrayList<CardAction> mCardActions = new ArrayList<CardAction>();
+
+ /**
+ * Some cards will have a sense of "progress" which should be associated with, but separated
+ * from its "parent" card. To push for simplicity in samples, Cards are designed to have
+ * a maximum of one progress indicator per Card.
+ */
+ private CardProgress mCardProgress = null;
+
+ public Card() {
+ }
+
+ public String getTag() {
+ return mTag;
+ }
+
+ public View getView() {
+ return mCardView;
+ }
+
+
+ public Card setDescription(String desc) {
+ if (mDescView != null) {
+ mDescription = desc;
+ mDescView.setText(desc);
+ }
+ return this;
+ }
+
+ public Card setTitle(String title) {
+ if (mTitleView != null) {
+ mTitle = title;
+ mTitleView.setText(title);
+ }
+ return this;
+ }
+
+
+ /**
+ * Return the UI state, either {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED}
+ * or {@link #CARD_STATE_INACTIVE}.
+ */
+ public int getState() {
+ return mCardState;
+ }
+
+ /**
+ * Set the UI state. The parameter describes the state and must be either
+ * {@link #CARD_STATE_NORMAL}, {@link #CARD_STATE_FOCUSED} or {@link #CARD_STATE_INACTIVE}.
+ * Note: This method must be called from the UI Thread.
+ * @param state
+ * @return The card itself, allows for chaining of calls
+ */
+ public Card setState(int state) {
+ mCardState = state;
+ if (null != mOverlayView) {
+ if (null != mOngoingAnimator) {
+ mOngoingAnimator.end();
+ mOngoingAnimator = null;
+ }
+ switch (state) {
+ case CARD_STATE_NORMAL: {
+ mOverlayView.setVisibility(View.GONE);
+ mOverlayView.setAlpha(1.f);
+ break;
+ }
+ case CARD_STATE_FOCUSED: {
+ mOverlayView.setVisibility(View.VISIBLE);
+ mOverlayView.setBackgroundResource(R.drawable.card_overlay_focused);
+ ObjectAnimator animator = ObjectAnimator.ofFloat(mOverlayView, "alpha", 0.f);
+ animator.setRepeatMode(ObjectAnimator.REVERSE);
+ animator.setRepeatCount(ObjectAnimator.INFINITE);
+ animator.setDuration(1000);
+ animator.start();
+ mOngoingAnimator = animator;
+ break;
+ }
+ case CARD_STATE_INACTIVE: {
+ mOverlayView.setVisibility(View.VISIBLE);
+ mOverlayView.setAlpha(1.f);
+ mOverlayView.setBackgroundColor(Color.argb(0xaa, 0xcc, 0xcc, 0xcc));
+ break;
+ }
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Set the type of progress indicator.
+ * The progress type can only be changed if the Card was initially build with a progress
+ * indicator.
+ * See {@link Builder#setProgressType(int)}.
+ * Must be a value of either {@link #PROGRESS_TYPE_NORMAL},
+ * {@link #PROGRESS_TYPE_INDETERMINATE}, {@link #PROGRESS_TYPE_LABEL} or
+ * {@link #PROGRESS_TYPE_NO_PROGRESS}.
+ * @param progressType
+ * @return The card itself, allows for chaining of calls
+ */
+ public Card setProgressType(int progressType) {
+ if (mCardProgress == null) {
+ mCardProgress = new CardProgress();
+ }
+ mCardProgress.setProgressType(progressType);
+ return this;
+ }
+
+ /**
+ * Return the progress indicator type. A value of either {@link #PROGRESS_TYPE_NORMAL},
+ * {@link #PROGRESS_TYPE_INDETERMINATE}, {@link #PROGRESS_TYPE_LABEL}. Otherwise if no progress
+ * indicator is enabled, {@link #PROGRESS_TYPE_NO_PROGRESS} is returned.
+ * @return
+ */
+ public int getProgressType() {
+ if (mCardProgress == null) {
+ return PROGRESS_TYPE_NO_PROGRESS;
+ }
+ return mCardProgress.progressType;
+ }
+
+ /**
+ * Set the progress to the specified value. Only applicable if the card has a
+ * {@link #PROGRESS_TYPE_NORMAL} progress type.
+ * @param progress
+ * @return
+ * @see #setMaxProgress(int)
+ */
+ public Card setProgress(int progress) {
+ if (mCardProgress != null) {
+ mCardProgress.setProgress(progress);
+ }
+ return this;
+ }
+
+ /**
+ * Set the range of the progress to 0...max. Only applicable if the card has a
+ * {@link #PROGRESS_TYPE_NORMAL} progress type.
+ * @return
+ */
+ public Card setMaxProgress(int max){
+ if (mCardProgress != null) {
+ mCardProgress.setMax(max);
+ }
+ return this;
+ }
+
+ /**
+ * Set the label text for the progress if the card has a progress type of
+ * {@link #PROGRESS_TYPE_NORMAL}, {@link #PROGRESS_TYPE_INDETERMINATE} or
+ * {@link #PROGRESS_TYPE_LABEL}
+ * @param text
+ * @return
+ */
+ public Card setProgressLabel(String text) {
+ if (mCardProgress != null) {
+ mCardProgress.setProgressLabel(text);
+ }
+ return this;
+ }
+
+ /**
+ * Toggle the visibility of the progress section of the card. Only applicable if
+ * the card has a progress type of
+ * {@link #PROGRESS_TYPE_NORMAL}, {@link #PROGRESS_TYPE_INDETERMINATE} or
+ * {@link #PROGRESS_TYPE_LABEL}.
+ * @param isVisible
+ * @return
+ */
+ public Card setProgressVisibility(boolean isVisible) {
+ if (mCardProgress.progressView == null) {
+ return this; // Card does not have progress
+ }
+ mCardProgress.progressView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
+
+ return this;
+ }
+
+ /**
+ * Adds an action to this card during build time.
+ *
+ * @param label
+ * @param id
+ * @param type
+ */
+ private void addAction(String label, int id, int type) {
+ CardAction cardAction = new CardAction();
+ cardAction.label = label;
+ cardAction.id = id;
+ cardAction.type = type;
+ mCardActions.add(cardAction);
+ }
+
+ /**
+ * Toggles the visibility of a card action.
+ * @param actionId
+ * @param isVisible
+ * @return
+ */
+ public Card setActionVisibility(int actionId, boolean isVisible) {
+ int visibilityFlag = isVisible ? View.VISIBLE : View.GONE;
+ for (CardAction action : mCardActions) {
+ if (action.id == actionId && action.actionView != null) {
+ action.actionView.setVisibility(visibilityFlag);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * Toggles visibility of the action area of this Card through an animation.
+ * @param isVisible
+ * @return
+ */
+ public Card setActionAreaVisibility(boolean isVisible) {
+ if (mActionAreaView == null) {
+ return this; // Card does not have an action area
+ }
+
+ if (isVisible) {
+ // Show the action area
+ mActionAreaView.setVisibility(View.VISIBLE);
+ mActionAreaView.setPivotY(0.f);
+ mActionAreaView.setPivotX(mCardView.getWidth() / 2.f);
+ mActionAreaView.setAlpha(0.5f);
+ mActionAreaView.setRotationX(-90.f);
+ mActionAreaView.animate().rotationX(0.f).alpha(1.f).setDuration(400);
+ } else {
+ // Hide the action area
+ mActionAreaView.setPivotY(0.f);
+ mActionAreaView.setPivotX(mCardView.getWidth() / 2.f);
+ mActionAreaView.animate().rotationX(-90.f).alpha(0.f).setDuration(400).setListener(
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mActionAreaView.setVisibility(View.GONE);
+ }
+ });
+ }
+ return this;
+ }
+
+
+ /**
+ * Creates a shallow clone of the card. Shallow means all values are present, but no views.
+ * This is useful for saving/restoring in the case of configuration changes, like screen
+ * rotation.
+ *
+ * @return A shallow clone of the card instance
+ */
+ public Card createShallowClone() {
+ Card cloneCard = new Card();
+
+ // Outer card values
+ cloneCard.mTitle = mTitle;
+ cloneCard.mDescription = mDescription;
+ cloneCard.mTag = mTag;
+ cloneCard.mLayoutId = mLayoutId;
+ cloneCard.mCardState = mCardState;
+
+ // Progress
+ if (mCardProgress != null) {
+ cloneCard.mCardProgress = mCardProgress.createShallowClone();
+ }
+
+ // Actions
+ for (CardAction action : mCardActions) {
+ cloneCard.mCardActions.add(action.createShallowClone());
+ }
+
+ return cloneCard;
+ }
+
+
+ /**
+ * Prepare the card to be stored for configuration change.
+ */
+ public void prepareForConfigurationChange() {
+ // Null out views.
+ mCardView = null;
+ for (CardAction action : mCardActions) {
+ action.actionView = null;
+ }
+ mCardProgress.progressView = null;
+ }
+
+ /**
+ * Creates a new {@link #Card}.
+ */
+ public static class Builder {
+ private Card mCard;
+
+ /**
+ * Instantiate the builder with data from a shallow clone.
+ * @param listener
+ * @param card
+ * @see Card#createShallowClone()
+ */
+ protected Builder(OnCardClickListener listener, Card card) {
+ mCard = card;
+ mCard.mClickListener = listener;
+ }
+
+ /**
+ * Instantiate the builder with the tag of the card.
+ * @param listener
+ * @param tag
+ */
+ public Builder(OnCardClickListener listener, String tag) {
+ mCard = new Card();
+ mCard.mTag = tag;
+ mCard.mClickListener = listener;
+ }
+
+ public Builder setTitle(String title) {
+ mCard.mTitle = title;
+ return this;
+ }
+
+ public Builder setDescription(String desc) {
+ mCard.mDescription = desc;
+ return this;
+ }
+
+ /**
+ * Add an action.
+ * The type describes how this action will be displayed. Accepted values are
+ * {@link #ACTION_NEUTRAL}, {@link #ACTION_POSITIVE} or {@link #ACTION_NEGATIVE}.
+ *
+ * @param label The text to display for this action
+ * @param id Identifier for this action, supplied in the click listener
+ * @param type UI style of action
+ * @return
+ */
+ public Builder addAction(String label, int id, int type) {
+ mCard.addAction(label, id, type);
+ return this;
+ }
+
+ /**
+ * Override the default layout.
+ * The referenced layout file has to contain the same identifiers as defined in the default
+ * layout configuration.
+ * @param layout
+ * @return
+ * @see R.layout.card
+ */
+ public Builder setLayout(int layout) {
+ mCard.mLayoutId = layout;
+ return this;
+ }
+
+ /**
+ * Set the type of progress bar to display.
+ * Accepted values are:
+ * <ul>
+ * <li>{@link #PROGRESS_TYPE_NO_PROGRESS} disables the progress indicator</li>
+ * <li>{@link #PROGRESS_TYPE_NORMAL}
+ * displays a standard, linear progress indicator.</li>
+ * <li>{@link #PROGRESS_TYPE_INDETERMINATE} displays an indeterminate (infite) progress
+ * indicator.</li>
+ * <li>{@link #PROGRESS_TYPE_LABEL} only displays a label text in the progress area
+ * of the card.</li>
+ * </ul>
+ *
+ * @param progressType
+ * @return
+ */
+ public Builder setProgressType(int progressType) {
+ mCard.setProgressType(progressType);
+ return this;
+ }
+
+ public Builder setProgressLabel(String label) {
+ // ensure the progress layout has been initialized, use 'no progress' by default
+ if (mCard.mCardProgress == null) {
+ mCard.setProgressType(PROGRESS_TYPE_NO_PROGRESS);
+ }
+ mCard.mCardProgress.label = label;
+ return this;
+ }
+
+ public Builder setProgressMaxValue(int maxValue) {
+ // ensure the progress layout has been initialized, use 'no progress' by default
+ if (mCard.mCardProgress == null) {
+ mCard.setProgressType(PROGRESS_TYPE_NO_PROGRESS);
+ }
+ mCard.mCardProgress.maxValue = maxValue;
+ return this;
+ }
+
+ public Builder setStatus(int status) {
+ mCard.setState(status);
+ return this;
+ }
+
+ public Card build(Activity activity) {
+ LayoutInflater inflater = activity.getLayoutInflater();
+ // Inflating the card.
+ ViewGroup cardView = (ViewGroup) inflater.inflate(mCard.mLayoutId,
+ (ViewGroup) activity.findViewById(R.id.card_stream), false);
+
+ // Check that the layout contains a TextView with the card_title id
+ View viewTitle = cardView.findViewById(R.id.card_title);
+ if (mCard.mTitle != null && viewTitle != null) {
+ mCard.mTitleView = (TextView) viewTitle;
+ mCard.mTitleView.setText(mCard.mTitle);
+ } else if (viewTitle != null) {
+ viewTitle.setVisibility(View.GONE);
+ }
+
+ // Check that the layout contains a TextView with the card_content id
+ View viewDesc = cardView.findViewById(R.id.card_content);
+ if (mCard.mDescription != null && viewDesc != null) {
+ mCard.mDescView = (TextView) viewDesc;
+ mCard.mDescView.setText(mCard.mDescription);
+ } else if (viewDesc != null) {
+ cardView.findViewById(R.id.card_content).setVisibility(View.GONE);
+ }
+
+
+ ViewGroup actionArea = (ViewGroup) cardView.findViewById(R.id.card_actionarea);
+
+ // Inflate Progress
+ initializeProgressView(inflater, actionArea);
+
+ // Inflate all action views.
+ initializeActionViews(inflater, cardView, actionArea);
+
+ mCard.mCardView = cardView;
+ mCard.mOverlayView = cardView.findViewById(R.id.card_overlay);
+
+ return mCard;
+ }
+
+ /**
+ * Initialize data from the given card.
+ * @param card
+ * @return
+ * @see Card#createShallowClone()
+ */
+ public Builder cloneFromCard(Card card) {
+ mCard = card.createShallowClone();
+ return this;
+ }
+
+ /**
+ * Build the action views by inflating the appropriate layouts and setting the text and
+ * values.
+ * @param inflater
+ * @param cardView
+ * @param actionArea
+ */
+ private void initializeActionViews(LayoutInflater inflater, ViewGroup cardView,
+ ViewGroup actionArea) {
+ if (!mCard.mCardActions.isEmpty()) {
+ // Set action area to visible only when actions are visible
+ actionArea.setVisibility(View.VISIBLE);
+ mCard.mActionAreaView = actionArea;
+ }
+
+ // Inflate all card actions
+ for (final CardAction action : mCard.mCardActions) {
+
+ int useActionLayout = 0;
+ switch (action.type) {
+ case Card.ACTION_POSITIVE:
+ useActionLayout = R.layout.card_button_positive;
+ break;
+ case Card.ACTION_NEGATIVE:
+ useActionLayout = R.layout.card_button_negative;
+ break;
+ case Card.ACTION_NEUTRAL:
+ default:
+ useActionLayout = R.layout.card_button_neutral;
+ break;
+ }
+
+ action.actionView = inflater.inflate(useActionLayout, actionArea, false);
+ Button actionButton = (Button) action.actionView.findViewById(R.id.card_button);
+
+ actionButton.setText(action.label);
+ actionButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCard.mClickListener.onCardClick(action.id, mCard.mTag);
+ }
+ });
+ actionArea.addView(action.actionView);
+ }
+ }
+
+ /**
+ * Build the progress view into the given ViewGroup.
+ *
+ * @param inflater
+ * @param actionArea
+ */
+ private void initializeProgressView(LayoutInflater inflater, ViewGroup actionArea) {
+
+ // Only inflate progress layout if a progress type other than NO_PROGRESS was set.
+ if (mCard.mCardProgress != null) {
+ //Setup progress card.
+ View progressView = inflater.inflate(R.layout.card_progress, actionArea, false);
+ ProgressBar progressBar =
+ (ProgressBar) progressView.findViewById(R.id.card_progress);
+ ((TextView) progressView.findViewById(R.id.card_progress_text))
+ .setText(mCard.mCardProgress.label);
+ progressBar.setMax(mCard.mCardProgress.maxValue);
+ progressBar.setProgress(0);
+ mCard.mCardProgress.progressView = progressView;
+ mCard.mCardProgress.setProgressType(mCard.getProgressType());
+ actionArea.addView(progressView);
+ }
+ }
+ }
+
+ /**
+ * Represents a clickable action, accessible from the bottom of the card.
+ * Fields include the label, an ID to specify the action that was performed in the callback,
+ * an action type (positive, negative, neutral), and the callback.
+ */
+ public class CardAction {
+
+ public String label;
+ public int id;
+ public int type;
+ public View actionView;
+
+ public CardAction createShallowClone() {
+ CardAction actionClone = new CardAction();
+ actionClone.label = label;
+ actionClone.id = id;
+ actionClone.type = type;
+ return actionClone;
+ // Not the view. Never the view (don't want to hold view references for
+ // onConfigurationChange.
+ }
+
+ }
+
+ /**
+ * Describes the progress of a {@link Card}.
+ * Three types of progress are supported:
+ * <ul><li>{@link Card#PROGRESS_TYPE_NORMAL: Standard progress bar with label text</li>
+ * <li>{@link Card#PROGRESS_TYPE_INDETERMINATE}: Indeterminate progress bar with label txt</li>
+ * <li>{@link Card#PROGRESS_TYPE_LABEL}: Label only, no progresss bar</li>
+ * </ul>
+ */
+ public class CardProgress {
+ private int progressType = Card.PROGRESS_TYPE_NO_PROGRESS;
+ private String label = "";
+ private int currProgress = 0;
+ private int maxValue = 100;
+
+ public View progressView = null;
+ private ProgressBar progressBar = null;
+ private TextView progressLabel = null;
+
+ public CardProgress createShallowClone() {
+ CardProgress progressClone = new CardProgress();
+ progressClone.label = label;
+ progressClone.currProgress = currProgress;
+ progressClone.maxValue = maxValue;
+ progressClone.progressType = progressType;
+ return progressClone;
+ }
+
+ /**
+ * Set the progress. Only useful for the type {@link #PROGRESS_TYPE_NORMAL}.
+ * @param progress
+ * @see android.widget.ProgressBar#setProgress(int)
+ */
+ public void setProgress(int progress) {
+ currProgress = progress;
+ final ProgressBar bar = getProgressBar();
+ if (bar != null) {
+ bar.setProgress(currProgress);
+ bar.invalidate();
+ }
+ }
+
+ /**
+ * Set the range of the progress to 0...max.
+ * Only useful for the type {@link #PROGRESS_TYPE_NORMAL}.
+ * @param max
+ * @see android.widget.ProgressBar#setMax(int)
+ */
+ public void setMax(int max) {
+ maxValue = max;
+ final ProgressBar bar = getProgressBar();
+ if (bar != null) {
+ bar.setMax(maxValue);
+ }
+ }
+
+ /**
+ * Set the label text that appears near the progress indicator.
+ * @param text
+ */
+ public void setProgressLabel(String text) {
+ label = text;
+ final TextView labelView = getProgressLabel();
+ if (labelView != null) {
+ labelView.setText(text);
+ }
+ }
+
+ /**
+ * Set how progress is displayed. The parameter must be one of three supported types:
+ * <ul><li>{@link Card#PROGRESS_TYPE_NORMAL: Standard progress bar with label text</li>
+ * <li>{@link Card#PROGRESS_TYPE_INDETERMINATE}:
+ * Indeterminate progress bar with label txt</li>
+ * <li>{@link Card#PROGRESS_TYPE_LABEL}: Label only, no progresss bar</li>
+ * @param type
+ */
+ public void setProgressType(int type) {
+ progressType = type;
+ if (progressView != null) {
+ switch (type) {
+ case PROGRESS_TYPE_NO_PROGRESS: {
+ progressView.setVisibility(View.GONE);
+ break;
+ }
+ case PROGRESS_TYPE_NORMAL: {
+ progressView.setVisibility(View.VISIBLE);
+ getProgressBar().setIndeterminate(false);
+ break;
+ }
+ case PROGRESS_TYPE_INDETERMINATE: {
+ progressView.setVisibility(View.VISIBLE);
+ getProgressBar().setIndeterminate(true);
+ break;
+ }
+ }
+ }
+ }
+
+ private TextView getProgressLabel() {
+ if (progressLabel != null) {
+ return progressLabel;
+ } else if (progressView != null) {
+ progressLabel = (TextView) progressView.findViewById(R.id.card_progress_text);
+ return progressLabel;
+ } else {
+ return null;
+ }
+ }
+
+ private ProgressBar getProgressBar() {
+ if (progressBar != null) {
+ return progressBar;
+ } else if (progressView != null) {
+ progressBar = (ProgressBar) progressView.findViewById(R.id.card_progress);
+ return progressBar;
+ } else {
+ return null;
+ }
+ }
+
+ }
+}
+
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardActionButton.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardActionButton.java
new file mode 100644
index 0000000..ea37e66
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardActionButton.java
@@ -0,0 +1,69 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.animation.BounceInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.Button;
+
+/**
+ * Custom Button with a special 'pressed' effect for touch events.
+ */
+public class CardActionButton extends Button {
+
+ public CardActionButton(Context context) {
+ super(context);
+ }
+
+ public CardActionButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CardActionButton(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+
+ switch(event.getAction()){
+ case MotionEvent.ACTION_DOWN:
+ setPressed(true);
+ animate().scaleX(0.98f).scaleY(0.98f).alpha(0.8f).setDuration(100).
+ setInterpolator(new DecelerateInterpolator());
+ break;
+ case MotionEvent.ACTION_UP:
+ animate().scaleX(1.0f).scaleY(1.f).alpha(1.0f).setDuration(50).
+ setInterpolator(new BounceInterpolator());
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ animate().scaleX(1.0f).scaleY(1.f).alpha(1.0f).setDuration(50).
+ setInterpolator(new BounceInterpolator());
+ break;
+ }
+
+ return super.onTouchEvent(event);
+ }
+
+}
+
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardLayout.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardLayout.java
new file mode 100644
index 0000000..8215275
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardLayout.java
@@ -0,0 +1,94 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.widget.RelativeLayout;
+
+/**
+ * Custom Button with a special 'pressed' effect for touch events.
+ */
+public class CardLayout extends RelativeLayout {
+
+ private boolean mSwiping = false;
+ private float mDownX = 0.f;
+ private float mDownY = 0.f;
+ private float mTouchSlop = 0.f;
+
+ public CardLayout(Context context) {
+ super(context);
+ init();
+ }
+
+ public CardLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public CardLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ private void init(){
+ setFocusable(true);
+ setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+ setWillNotDraw(false);
+ setClickable(true);
+
+ mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop() * 2.f;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ switch(event.getAction()){
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ mSwiping = false;
+ break;
+ }
+ return super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+
+ switch(event.getAction()){
+ case MotionEvent.ACTION_MOVE:
+ if( !mSwiping ){
+ mSwiping = Math.abs(mDownX - event.getX()) > mTouchSlop;
+ }
+ break;
+ case MotionEvent.ACTION_DOWN:
+ mDownX = event.getX();
+ mDownY = event.getY();
+ mSwiping = false;
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ mSwiping = false;
+ break;
+ }
+ return mSwiping;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStream.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStream.java
new file mode 100644
index 0000000..5de9852
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStream.java
@@ -0,0 +1,25 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+public interface CardStream {
+ public CardStreamFragment getCardStream();
+}
+
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamAnimator.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamAnimator.java
new file mode 100644
index 0000000..a22ddd7
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamAnimator.java
@@ -0,0 +1,120 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.view.View;
+
+/**
+ * An abstract class which defines animators for CardStreamLinearLayout.
+ */
+abstract class CardStreamAnimator {
+
+ protected float mSpeedFactor = 1.f;
+
+ /**
+ * Set speed factor of animations. Higher value means longer duration & slow animation.
+ *
+ * @param speedFactor speed type 1: SLOW, 2: NORMAL, 3:FAST
+ */
+ public void setSpeedFactor(float speedFactor) {
+ mSpeedFactor = speedFactor;
+ }
+
+ /**
+ * Define initial animation of each child which fired when a user rotate a screen.
+ *
+ * @param context
+ * @return ObjectAnimator for initial animation
+ */
+ public abstract ObjectAnimator getInitalAnimator(Context context);
+
+ /**
+ * Define disappearing animation of a child which fired when a view is removed programmatically
+ *
+ * @param context
+ * @return ObjectAnimator for disappearing animation
+ */
+ public abstract ObjectAnimator getDisappearingAnimator(Context context);
+
+ /**
+ * Define appearing animation of a child which fired when a view is added programmatically
+ *
+ * @param context
+ * @return ObjectAnimator for appearing animation
+ */
+ public abstract ObjectAnimator getAppearingAnimator(Context context);
+
+ /**
+ * Define swipe-in (back to the origin position) animation of a child
+ * which fired when a view is not moved enough to be removed.
+ *
+ * @param view target view
+ * @param deltaX delta distance by x-axis
+ * @param deltaY delta distance by y-axis
+ * @return ObjectAnimator for swipe-in animation
+ */
+ public abstract ObjectAnimator getSwipeInAnimator(View view, float deltaX, float deltaY);
+
+ /**
+ * Define swipe-out animation of a child
+ * which fired when a view is removing by a user swipe action.
+ *
+ * @param view target view
+ * @param deltaX delta distance by x-axis
+ * @param deltaY delta distance by y-axis
+ * @return ObjectAnimator for swipe-out animation
+ */
+ public abstract ObjectAnimator getSwipeOutAnimator(View view, float deltaX, float deltaY);
+
+ /**
+ * A simple CardStreamAnimator implementation which is used to turn animations off.
+ */
+ public static class EmptyAnimator extends CardStreamAnimator {
+
+ @Override
+ public ObjectAnimator getInitalAnimator(Context context) {
+ return null;
+ }
+
+ @Override
+ public ObjectAnimator getDisappearingAnimator(Context context) {
+ return null;
+ }
+
+ @Override
+ public ObjectAnimator getAppearingAnimator(Context context) {
+ return null;
+ }
+
+ @Override
+ public ObjectAnimator getSwipeInAnimator(View view, float deltaX, float deltaY) {
+ return null;
+ }
+
+ @Override
+ public ObjectAnimator getSwipeOutAnimator(View view, float deltaX, float deltaY) {
+ return null;
+ }
+ }
+
+}
+
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamFragment.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamFragment.java
new file mode 100644
index 0000000..9f8b7cb
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamFragment.java
@@ -0,0 +1,275 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+
+
+/**
+ * A Fragment that handles a stream of cards.
+ * Cards can be shown or hidden. When a card is shown it can also be marked as not-dismissible, see
+ * {@link CardStreamLinearLayout#addCard(android.view.View, boolean)}.
+ */
+public class CardStreamFragment extends Fragment {
+
+ private static final int INITIAL_SIZE = 15;
+ private CardStreamLinearLayout mLayout = null;
+ private LinkedHashMap<String, Card> mVisibleCards = new LinkedHashMap<String, Card>(INITIAL_SIZE);
+ private HashMap<String, Card> mHiddenCards = new HashMap<String, Card>(INITIAL_SIZE);
+ private HashSet<String> mDismissibleCards = new HashSet<String>(INITIAL_SIZE);
+
+ // Set the listener to handle dismissed cards by moving them to the hidden cards map.
+ private CardStreamLinearLayout.OnDissmissListener mCardDismissListener =
+ new CardStreamLinearLayout.OnDissmissListener() {
+ @Override
+ public void onDismiss(String tag) {
+ dismissCard(tag);
+ }
+ };
+
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View view = inflater.inflate(R.layout.cardstream, container, false);
+ mLayout = (CardStreamLinearLayout) view.findViewById(R.id.card_stream);
+ mLayout.setOnDismissListener(mCardDismissListener);
+
+ return view;
+ }
+
+ /**
+ * Add a visible, dismissible card to the card stream.
+ *
+ * @param card
+ */
+ public void addCard(Card card) {
+ final String tag = card.getTag();
+
+ if (!mVisibleCards.containsKey(tag) && !mHiddenCards.containsKey(tag)) {
+ final View view = card.getView();
+ view.setTag(tag);
+ mHiddenCards.put(tag, card);
+ }
+ }
+
+ /**
+ * Add and show a card.
+ *
+ * @param card
+ * @param show
+ */
+ public void addCard(Card card, boolean show) {
+ addCard(card);
+ if (show) {
+ showCard(card.getTag());
+ }
+ }
+
+ /**
+ * Remove a card and return true if it has been successfully removed.
+ *
+ * @param tag
+ * @return
+ */
+ public boolean removeCard(String tag) {
+ // Attempt to remove a visible card first
+ Card card = mVisibleCards.get(tag);
+ if (card != null) {
+ // Card is visible, also remove from layout
+ mVisibleCards.remove(tag);
+ mLayout.removeView(card.getView());
+ return true;
+ } else {
+ // Card is hidden, no need to remove from layout
+ card = mHiddenCards.remove(tag);
+ return card != null;
+ }
+ }
+
+ /**
+ * Show a dismissible card, returns false if the card could not be shown.
+ *
+ * @param tag
+ * @return
+ */
+ public boolean showCard(String tag) {
+ return showCard(tag, true);
+ }
+
+ /**
+ * Show a card, returns false if the card could not be shown.
+ *
+ * @param tag
+ * @param dismissible
+ * @return
+ */
+ public boolean showCard(String tag, boolean dismissible) {
+ final Card card = mHiddenCards.get(tag);
+ // ensure the card is hidden and not already visible
+ if (card != null && !mVisibleCards.containsValue(tag)) {
+ mHiddenCards.remove(tag);
+ mVisibleCards.put(tag, card);
+ mLayout.addCard(card.getView(), dismissible);
+ if (dismissible) {
+ mDismissibleCards.add(tag);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Hides the card, returns false if the card could not be hidden.
+ *
+ * @param tag
+ * @return
+ */
+ public boolean hideCard(String tag) {
+ final Card card = mVisibleCards.get(tag);
+ if (card != null) {
+ mVisibleCards.remove(tag);
+ mDismissibleCards.remove(tag);
+ mHiddenCards.put(tag, card);
+
+ mLayout.removeView(card.getView());
+ return true;
+ }
+ return mHiddenCards.containsValue(tag);
+ }
+
+
+ private void dismissCard(String tag) {
+ final Card card = mVisibleCards.get(tag);
+ if (card != null) {
+ mDismissibleCards.remove(tag);
+ mVisibleCards.remove(tag);
+ mHiddenCards.put(tag, card);
+ }
+ }
+
+
+ public boolean isCardVisible(String tag) {
+ return mVisibleCards.containsValue(tag);
+ }
+
+ /**
+ * Returns true if the card is shown and is dismissible.
+ *
+ * @param tag
+ * @return
+ */
+ public boolean isCardDismissible(String tag) {
+ return mDismissibleCards.contains(tag);
+ }
+
+ /**
+ * Returns the Card for this tag.
+ *
+ * @param tag
+ * @return
+ */
+ public Card getCard(String tag) {
+ final Card card = mVisibleCards.get(tag);
+ if (card != null) {
+ return card;
+ } else {
+ return mHiddenCards.get(tag);
+ }
+ }
+
+ /**
+ * Moves the view port to show the card with this tag.
+ *
+ * @param tag
+ * @see CardStreamLinearLayout#setFirstVisibleCard(String)
+ */
+ public void setFirstVisibleCard(String tag) {
+ final Card card = mVisibleCards.get(tag);
+ if (card != null) {
+ mLayout.setFirstVisibleCard(tag);
+ }
+ }
+
+ public int getVisibleCardCount() {
+ return mVisibleCards.size();
+ }
+
+ public Collection<Card> getVisibleCards() {
+ return mVisibleCards.values();
+ }
+
+ public void restoreState(CardStreamState state, OnCardClickListener callback) {
+ // restore hidden cards
+ for (Card c : state.hiddenCards) {
+ Card card = new Card.Builder(callback,c).build(getActivity());
+ mHiddenCards.put(card.getTag(), card);
+ }
+
+ // temporarily set up list of dismissible
+ final HashSet<String> dismissibleCards = state.dismissibleCards;
+
+ //restore shown cards
+ for (Card c : state.visibleCards) {
+ Card card = new Card.Builder(callback,c).build(getActivity());
+ addCard(card);
+ final String tag = card.getTag();
+ showCard(tag, dismissibleCards.contains(tag));
+ }
+
+ // move to first visible card
+ final String firstShown = state.shownTag;
+ if (firstShown != null) {
+ mLayout.setFirstVisibleCard(firstShown);
+ }
+
+ mLayout.triggerShowInitialAnimation();
+ }
+
+ public CardStreamState dumpState() {
+ final Card[] visible = cloneCards(mVisibleCards.values());
+ final Card[] hidden = cloneCards(mHiddenCards.values());
+ final HashSet<String> dismissible = new HashSet<String>(mDismissibleCards);
+ final String firstVisible = mLayout.getFirstVisibleCardTag();
+
+ return new CardStreamState(visible, hidden, dismissible, firstVisible);
+ }
+
+ private Card[] cloneCards(Collection<Card> cards) {
+ Card[] cardArray = new Card[cards.size()];
+ int i = 0;
+ for (Card c : cards) {
+ cardArray[i++] = c.createShallowClone();
+ }
+
+ return cardArray;
+ }
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamLinearLayout.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamLinearLayout.java
new file mode 100644
index 0000000..aeab770
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamLinearLayout.java
@@ -0,0 +1,569 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.animation.Animator;
+import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+
+import com.example.android.common.logger.Log;
+
+import java.util.ArrayList;
+
+/**
+ * A Layout that contains a stream of card views.
+ */
+public class CardStreamLinearLayout extends LinearLayout {
+
+ public static final int ANIMATION_SPEED_SLOW = 1001;
+ public static final int ANIMATION_SPEED_NORMAL = 1002;
+ public static final int ANIMATION_SPEED_FAST = 1003;
+
+ private static final String TAG = "CardStreamLinearLayout";
+ private final ArrayList<View> mFixedViewList = new ArrayList<View>();
+ private final Rect mChildRect = new Rect();
+ private CardStreamAnimator mAnimators;
+ private OnDissmissListener mDismissListener = null;
+ private boolean mLayouted = false;
+ private boolean mSwiping = false;
+ private String mFirstVisibleCardTag = null;
+ private boolean mShowInitialAnimation = false;
+
+ /**
+ * Handle touch events to fade/move dragged items as they are swiped out
+ */
+ private OnTouchListener mTouchListener = new OnTouchListener() {
+
+ private float mDownX;
+ private float mDownY;
+
+ @Override
+ public boolean onTouch(final View v, MotionEvent event) {
+
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mDownX = event.getX();
+ mDownY = event.getY();
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ resetAnimatedView(v);
+ mSwiping = false;
+ mDownX = 0.f;
+ mDownY = 0.f;
+ break;
+ case MotionEvent.ACTION_MOVE: {
+
+ float x = event.getX() + v.getTranslationX();
+ float y = event.getY() + v.getTranslationY();
+
+ mDownX = mDownX == 0.f ? x : mDownX;
+ mDownY = mDownY == 0.f ? x : mDownY;
+
+ float deltaX = x - mDownX;
+ float deltaY = y - mDownY;
+
+ if (!mSwiping && isSwiping(deltaX, deltaY)) {
+ mSwiping = true;
+ v.getParent().requestDisallowInterceptTouchEvent(true);
+ } else {
+ swipeView(v, deltaX, deltaY);
+ }
+ }
+ break;
+ case MotionEvent.ACTION_UP: {
+ // User let go - figure out whether to animate the view out, or back into place
+ if (mSwiping) {
+ float x = event.getX() + v.getTranslationX();
+ float y = event.getY() + v.getTranslationY();
+
+ float deltaX = x - mDownX;
+ float deltaY = y - mDownX;
+ float deltaXAbs = Math.abs(deltaX);
+
+ // User let go - figure out whether to animate the view out, or back into place
+ boolean remove = deltaXAbs > v.getWidth() / 4 && !isFixedView(v);
+ if( remove )
+ handleViewSwipingOut(v, deltaX, deltaY);
+ else
+ handleViewSwipingIn(v, deltaX, deltaY);
+ }
+ mDownX = 0.f;
+ mDownY = 0.f;
+ mSwiping = false;
+ }
+ break;
+ default:
+ return false;
+ }
+ return false;
+ }
+ };
+ private int mSwipeSlop = -1;
+ /**
+ * Handle end-transition animation event of each child and launch a following animation.
+ */
+ private LayoutTransition.TransitionListener mTransitionListener
+ = new LayoutTransition.TransitionListener() {
+
+ @Override
+ public void startTransition(LayoutTransition transition, ViewGroup container, View
+ view, int transitionType) {
+ Log.d(TAG, "Start LayoutTransition animation:" + transitionType);
+ }
+
+ @Override
+ public void endTransition(LayoutTransition transition, ViewGroup container,
+ final View view, int transitionType) {
+
+ Log.d(TAG, "End LayoutTransition animation:" + transitionType);
+ if (transitionType == LayoutTransition.APPEARING) {
+ final View area = view.findViewById(R.id.card_actionarea);
+ if (area != null) {
+ runShowActionAreaAnimation(container, area);
+ }
+ }
+ }
+ };
+ /**
+ * Handle a hierarchy change event
+ * when a new child is added, scroll to bottom and hide action area..
+ */
+ private OnHierarchyChangeListener mOnHierarchyChangeListener
+ = new OnHierarchyChangeListener() {
+ @Override
+ public void onChildViewAdded(final View parent, final View child) {
+
+ Log.d(TAG, "child is added: " + child);
+
+ ViewParent scrollView = parent.getParent();
+ if (scrollView != null && scrollView instanceof ScrollView) {
+ ((ScrollView) scrollView).fullScroll(FOCUS_DOWN);
+ }
+
+ if (getLayoutTransition() != null) {
+ View view = child.findViewById(R.id.card_actionarea);
+ if (view != null)
+ view.setAlpha(0.f);
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ Log.d(TAG, "child is removed: " + child);
+ mFixedViewList.remove(child);
+ }
+ };
+ private int mLastDownX;
+
+ public CardStreamLinearLayout(Context context) {
+ super(context);
+ initialize(null, 0);
+ }
+
+ public CardStreamLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize(attrs, 0);
+ }
+
+ @SuppressLint("NewApi")
+ public CardStreamLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initialize(attrs, defStyle);
+ }
+
+ /**
+ * add a card view w/ canDismiss flag.
+ *
+ * @param cardView a card view
+ * @param canDismiss flag to indicate this card is dismissible or not.
+ */
+ public void addCard(View cardView, boolean canDismiss) {
+ if (cardView.getParent() == null) {
+ initCard(cardView, canDismiss);
+
+ ViewGroup.LayoutParams param = cardView.getLayoutParams();
+ if(param == null)
+ param = generateDefaultLayoutParams();
+
+ super.addView(cardView, -1, param);
+ }
+ }
+
+ @Override
+ public void addView(View child, int index, ViewGroup.LayoutParams params) {
+ if (child.getParent() == null) {
+ initCard(child, true);
+ super.addView(child, index, params);
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ Log.d(TAG, "onLayout: " + changed);
+
+ if( changed && !mLayouted ){
+ mLayouted = true;
+
+ ObjectAnimator animator;
+ LayoutTransition layoutTransition = new LayoutTransition();
+
+ animator = mAnimators.getDisappearingAnimator(getContext());
+ layoutTransition.setAnimator(LayoutTransition.DISAPPEARING, animator);
+
+ animator = mAnimators.getAppearingAnimator(getContext());
+ layoutTransition.setAnimator(LayoutTransition.APPEARING, animator);
+
+ layoutTransition.addTransitionListener(mTransitionListener);
+
+ if( animator != null )
+ layoutTransition.setDuration(animator.getDuration());
+
+ setLayoutTransition(layoutTransition);
+
+ if( mShowInitialAnimation )
+ runInitialAnimations();
+
+ if (mFirstVisibleCardTag != null) {
+ scrollToCard(mFirstVisibleCardTag);
+ mFirstVisibleCardTag = null;
+ }
+ }
+ }
+
+ /**
+ * Check whether a user moved enough distance to start a swipe action or not.
+ *
+ * @param deltaX
+ * @param deltaY
+ * @return true if a user is swiping.
+ */
+ protected boolean isSwiping(float deltaX, float deltaY) {
+
+ if (mSwipeSlop < 0) {
+ //get swipping slop from ViewConfiguration;
+ mSwipeSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ }
+
+ boolean swipping = false;
+ float absDeltaX = Math.abs(deltaX);
+
+ if( absDeltaX > mSwipeSlop )
+ return true;
+
+ return swipping;
+ }
+
+ /**
+ * Swipe a view by moving distance
+ *
+ * @param child a target view
+ * @param deltaX x moving distance by x-axis.
+ * @param deltaY y moving distance by y-axis.
+ */
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ protected void swipeView(View child, float deltaX, float deltaY) {
+ if (isFixedView(child)){
+ deltaX = deltaX / 4;
+ }
+
+ float deltaXAbs = Math.abs(deltaX);
+ float fractionCovered = deltaXAbs / (float) child.getWidth();
+
+ child.setTranslationX(deltaX);
+ child.setAlpha(1.f - fractionCovered);
+
+ if (deltaX > 0)
+ child.setRotationY(-15.f * fractionCovered);
+ else
+ child.setRotationY(15.f * fractionCovered);
+ }
+
+ protected void notifyOnDismissEvent( View child ){
+ if( child == null || mDismissListener == null )
+ return;
+
+ mDismissListener.onDismiss((String) child.getTag());
+ }
+
+ /**
+ * get the tag of the first visible child in this layout
+ *
+ * @return tag of the first visible child or null
+ */
+ public String getFirstVisibleCardTag() {
+
+ final int count = getChildCount();
+
+ if (count == 0)
+ return null;
+
+ for (int index = 0; index < count; ++index) {
+ //check the position of each view.
+ View child = getChildAt(index);
+ if (child.getGlobalVisibleRect(mChildRect) == true)
+ return (String) child.getTag();
+ }
+
+ return null;
+ }
+
+ /**
+ * Set the first visible card of this linear layout.
+ *
+ * @param tag tag of a card which should already added to this layout.
+ */
+ public void setFirstVisibleCard(String tag) {
+ if (tag == null)
+ return; //do nothing.
+
+ if (mLayouted) {
+ scrollToCard(tag);
+ } else {
+ //keep the tag for next use.
+ mFirstVisibleCardTag = tag;
+ }
+ }
+
+ /**
+ * If this flag is set,
+ * after finishing initial onLayout event, an initial animation which is defined in DefaultCardStreamAnimator is launched.
+ */
+ public void triggerShowInitialAnimation(){
+ mShowInitialAnimation = true;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ public void setCardStreamAnimator( CardStreamAnimator animators ){
+
+ if( animators == null )
+ mAnimators = new CardStreamAnimator.EmptyAnimator();
+ else
+ mAnimators = animators;
+
+ LayoutTransition layoutTransition = getLayoutTransition();
+
+ if( layoutTransition != null ){
+ layoutTransition.setAnimator( LayoutTransition.APPEARING,
+ mAnimators.getAppearingAnimator(getContext()) );
+ layoutTransition.setAnimator( LayoutTransition.DISAPPEARING,
+ mAnimators.getDisappearingAnimator(getContext()) );
+ }
+ }
+
+ /**
+ * set a OnDismissListener which called when user dismiss a card.
+ *
+ * @param listener
+ */
+ public void setOnDismissListener(OnDissmissListener listener) {
+ mDismissListener = listener;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private void initialize(AttributeSet attrs, int defStyle) {
+
+ float speedFactor = 1.f;
+
+ if (attrs != null) {
+ TypedArray a = getContext().obtainStyledAttributes(attrs,
+ R.styleable.CardStream, defStyle, 0);
+
+ if( a != null ){
+ int speedType = a.getInt(R.styleable.CardStream_animationDuration, 1001);
+ switch (speedType){
+ case ANIMATION_SPEED_FAST:
+ speedFactor = 0.5f;
+ break;
+ case ANIMATION_SPEED_NORMAL:
+ speedFactor = 1.f;
+ break;
+ case ANIMATION_SPEED_SLOW:
+ speedFactor = 2.f;
+ break;
+ }
+
+ String animatorName = a.getString(R.styleable.CardStream_animators);
+
+ try {
+ if( animatorName != null )
+ mAnimators = (CardStreamAnimator) getClass().getClassLoader()
+ .loadClass(animatorName).newInstance();
+ } catch (Exception e) {
+ Log.e(TAG, "Fail to load animator:" + animatorName, e);
+ } finally {
+ if(mAnimators == null)
+ mAnimators = new DefaultCardStreamAnimator();
+ }
+ a.recycle();
+ }
+ }
+
+ mAnimators.setSpeedFactor(speedFactor);
+ mSwipeSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ setOnHierarchyChangeListener(mOnHierarchyChangeListener);
+ }
+
+ private void initCard(View cardView, boolean canDismiss) {
+ resetAnimatedView(cardView);
+ cardView.setOnTouchListener(mTouchListener);
+ if (!canDismiss)
+ mFixedViewList.add(cardView);
+ }
+
+ private boolean isFixedView(View v) {
+ return mFixedViewList.contains(v);
+ }
+
+ private void resetAnimatedView(View child) {
+ child.setAlpha(1.f);
+ child.setTranslationX(0.f);
+ child.setTranslationY(0.f);
+ child.setRotation(0.f);
+ child.setRotationY(0.f);
+ child.setRotationX(0.f);
+ child.setScaleX(1.f);
+ child.setScaleY(1.f);
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private void runInitialAnimations() {
+ if( mAnimators == null )
+ return;
+
+ final int count = getChildCount();
+
+ for (int index = 0; index < count; ++index) {
+ final View child = getChildAt(index);
+ ObjectAnimator animator = mAnimators.getInitalAnimator(getContext());
+ if( animator != null ){
+ animator.setTarget(child);
+ animator.start();
+ }
+ }
+ }
+
+ private void runShowActionAreaAnimation(View parent, View area) {
+ area.setPivotY(0.f);
+ area.setPivotX(parent.getWidth() / 2.f);
+
+ area.setAlpha(0.5f);
+ area.setRotationX(-90.f);
+ area.animate().rotationX(0.f).alpha(1.f).setDuration(400);
+ }
+
+ private void handleViewSwipingOut(final View child, float deltaX, float deltaY) {
+ ObjectAnimator animator = mAnimators.getSwipeOutAnimator(child, deltaX, deltaY);
+ if( animator != null ){
+ animator.addListener(new EndAnimationWrapper() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ removeView(child);
+ notifyOnDismissEvent(child);
+ }
+ });
+ } else {
+ removeView(child);
+ notifyOnDismissEvent(child);
+ }
+
+ if( animator != null ){
+ animator.setTarget(child);
+ animator.start();
+ }
+ }
+
+ private void handleViewSwipingIn(final View child, float deltaX, float deltaY) {
+ ObjectAnimator animator = mAnimators.getSwipeInAnimator(child, deltaX, deltaY);
+ if( animator != null ){
+ animator.addListener(new EndAnimationWrapper() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ child.setTranslationY(0.f);
+ child.setTranslationX(0.f);
+ }
+ });
+ } else {
+ child.setTranslationY(0.f);
+ child.setTranslationX(0.f);
+ }
+
+ if( animator != null ){
+ animator.setTarget(child);
+ animator.start();
+ }
+ }
+
+ private void scrollToCard(String tag) {
+
+
+ final int count = getChildCount();
+ for (int index = 0; index < count; ++index) {
+ View child = getChildAt(index);
+
+ if (tag.equals(child.getTag())) {
+
+ ViewParent parent = getParent();
+ if( parent != null && parent instanceof ScrollView ){
+ ((ScrollView)parent).smoothScrollTo(
+ 0, child.getTop() - getPaddingTop() - child.getPaddingTop());
+ }
+ return;
+ }
+ }
+ }
+
+ public interface OnDissmissListener {
+ public void onDismiss(String tag);
+ }
+
+ /**
+ * Empty default AnimationListener
+ */
+ private abstract class EndAnimationWrapper implements Animator.AnimatorListener {
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ }
+ }//end of inner class
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamState.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamState.java
new file mode 100644
index 0000000..08432a9
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/CardStreamState.java
@@ -0,0 +1,40 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import java.util.HashSet;
+
+/**
+ * A struct object that holds the state of a {@link CardStreamFragment}.
+ */
+class CardStreamState{
+ protected Card[] visibleCards;
+ protected Card[] hiddenCards;
+ protected HashSet<String> dismissibleCards;
+ protected String shownTag;
+
+ protected CardStreamState(Card[] visible, Card[] hidden, HashSet<String> dismissible, String shownTag) {
+ visibleCards = visible;
+ hiddenCards = hidden;
+ dismissibleCards = dismissible;
+ this.shownTag = shownTag;
+ }
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/DefaultCardStreamAnimator.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/DefaultCardStreamAnimator.java
new file mode 100644
index 0000000..19ef43b
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/DefaultCardStreamAnimator.java
@@ -0,0 +1,124 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Point;
+import android.os.Build;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.BounceInterpolator;
+
+class DefaultCardStreamAnimator extends CardStreamAnimator {
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ public ObjectAnimator getDisappearingAnimator(Context context){
+
+ ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(new Object(),
+ PropertyValuesHolder.ofFloat("alpha", 1.f, 0.f),
+ PropertyValuesHolder.ofFloat("scaleX", 1.f, 0.f),
+ PropertyValuesHolder.ofFloat("scaleY", 1.f, 0.f),
+ PropertyValuesHolder.ofFloat("rotation", 0.f, 270.f));
+
+ animator.setDuration((long) (200 * mSpeedFactor));
+ return animator;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ @Override
+ public ObjectAnimator getAppearingAnimator(Context context){
+
+ final Point outPoint = new Point();
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ wm.getDefaultDisplay().getSize(outPoint);
+
+ ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(new Object(),
+ PropertyValuesHolder.ofFloat("alpha", 0.f, 1.f),
+ PropertyValuesHolder.ofFloat("translationY", outPoint.y / 2.f, 0.f),
+ PropertyValuesHolder.ofFloat("rotation", -45.f, 0.f));
+
+ animator.setDuration((long) (200 * mSpeedFactor));
+ return animator;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
+ @Override
+ public ObjectAnimator getInitalAnimator(Context context){
+
+ ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(new Object(),
+ PropertyValuesHolder.ofFloat("alpha", 0.5f, 1.f),
+ PropertyValuesHolder.ofFloat("rotation", 60.f, 0.f));
+
+ animator.setDuration((long) (200 * mSpeedFactor));
+ return animator;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ public ObjectAnimator getSwipeInAnimator(View view, float deltaX, float deltaY){
+
+ float deltaXAbs = Math.abs(deltaX);
+
+ float fractionCovered = 1.f - (deltaXAbs / view.getWidth());
+ long duration = Math.abs((int) ((1 - fractionCovered) * 200 * mSpeedFactor));
+
+ // Animate position and alpha of swiped item
+
+ ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view,
+ PropertyValuesHolder.ofFloat("alpha", 1.f),
+ PropertyValuesHolder.ofFloat("translationX", 0.f),
+ PropertyValuesHolder.ofFloat("rotationY", 0.f));
+
+ animator.setDuration(duration).setInterpolator(new BounceInterpolator());
+
+ return animator;
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ public ObjectAnimator getSwipeOutAnimator(View view, float deltaX, float deltaY){
+
+ float endX;
+ float endRotationY;
+
+ float deltaXAbs = Math.abs(deltaX);
+
+ float fractionCovered = 1.f - (deltaXAbs / view.getWidth());
+ long duration = Math.abs((int) ((1 - fractionCovered) * 200 * mSpeedFactor));
+
+ endX = deltaX < 0 ? -view.getWidth() : view.getWidth();
+ if (deltaX > 0)
+ endRotationY = -15.f;
+ else
+ endRotationY = 15.f;
+
+ // Animate position and alpha of swiped item
+ return ObjectAnimator.ofPropertyValuesHolder(view,
+ PropertyValuesHolder.ofFloat("alpha", 0.f),
+ PropertyValuesHolder.ofFloat("translationX", endX),
+ PropertyValuesHolder.ofFloat("rotationY", endRotationY)).setDuration(duration);
+
+ }
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/MainActivity.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/MainActivity.java
new file mode 100644
index 0000000..bb1f9a1
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/MainActivity.java
@@ -0,0 +1,91 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+
+public class MainActivity extends SampleActivityBase implements CardStream {
+ public static final String TAG = "MainActivity";
+ public static final String FRAGTAG = "BatchStepSensorFragment";
+
+ private CardStreamFragment mCardStreamFragment;
+
+ private StreamRetentionFragment mRetentionFragment;
+ private static final String RETENTION_TAG = "retention";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentManager fm = getSupportFragmentManager();
+ BatchStepSensorFragment fragment =
+ (BatchStepSensorFragment) fm.findFragmentByTag(FRAGTAG);
+
+ if (fragment == null) {
+ FragmentTransaction transaction = fm.beginTransaction();
+ fragment = new BatchStepSensorFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+
+ // Use fragment as click listener for cards, but must implement correct interface
+ if(!(fragment instanceof OnCardClickListener)){
+ throw new ClassCastException("BatchStepSensorFragment must " +
+ "implement OnCardClickListener interface.");
+ }
+ OnCardClickListener clickListener = (OnCardClickListener) fm.findFragmentByTag(FRAGTAG);
+
+ mRetentionFragment = (StreamRetentionFragment) fm.findFragmentByTag(RETENTION_TAG);
+ if (mRetentionFragment == null) {
+ mRetentionFragment = new StreamRetentionFragment();
+ fm.beginTransaction().add(mRetentionFragment, RETENTION_TAG).commit();
+ } else {
+ // If the retention fragment already existed, we need to pull some state.
+ // pull state out
+ CardStreamState state = mRetentionFragment.getCardStream();
+
+ // dump it in CardStreamFragment.
+ mCardStreamFragment =
+ (CardStreamFragment) fm.findFragmentById(R.id.fragment_cardstream);
+ mCardStreamFragment.restoreState(state, clickListener);
+ }
+ }
+
+ public CardStreamFragment getCardStream() {
+ if (mCardStreamFragment == null) {
+ mCardStreamFragment = (CardStreamFragment)
+ getSupportFragmentManager().findFragmentById(R.id.fragment_cardstream);
+ }
+ return mCardStreamFragment;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ CardStreamState state = getCardStream().dumpState();
+ mRetentionFragment.storeCardStream(state);
+ }
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/OnCardClickListener.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/OnCardClickListener.java
new file mode 100644
index 0000000..f024110
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/OnCardClickListener.java
@@ -0,0 +1,24 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+public interface OnCardClickListener {
+ public void onCardClick(int cardActionId, String cardTag);
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/StreamRetentionFragment.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/StreamRetentionFragment.java
new file mode 100644
index 0000000..7cd7f2b
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/batchstepsensor/StreamRetentionFragment.java
@@ -0,0 +1,41 @@
+/*
+* Copyright 2013 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.batchstepsensor;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+
+public class StreamRetentionFragment extends Fragment {
+
+ CardStreamState mState;
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setRetainInstance(true);
+ }
+
+ public void storeCardStream(CardStreamState state) {
+ mState = state;
+ }
+
+ public CardStreamState getCardStream() {
+ return mState;
+ }
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_action_cancel.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_action_cancel.png
new file mode 100644
index 0000000..f889617
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..564742c
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_action_cancel.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_action_cancel.png
new file mode 100644
index 0000000..d5a9384
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..08abe57
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/card_bg.9.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/card_bg.9.png
new file mode 100644
index 0000000..23b30c1
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/card_bg.9.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative.png
new file mode 100644
index 0000000..1e6a64e
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative_pressed.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative_pressed.png
new file mode 100644
index 0000000..13c105e
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_negative_pressed.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral.png
new file mode 100644
index 0000000..f8874cd
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral_pressed.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral_pressed.png
new file mode 100644
index 0000000..a8f5e67
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_neutral_pressed.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive.png
new file mode 100644
index 0000000..b0a68c3
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive_pressed.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive_pressed.png
new file mode 100644
index 0000000..528b5aa
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_cardaction_positive_pressed.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..15bafae
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_action_cancel.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_action_cancel.png
new file mode 100644
index 0000000..331c545
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..40bdd35
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg.xml
new file mode 100644
index 0000000..f86cf2f
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@color/card_action" android:state_pressed="true" />
+ <item android:drawable="@color/card_action_focused" android:state_focused="true" />
+ <item android:drawable="@color/card_action_item_bg" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_negative.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_negative.xml
new file mode 100644
index 0000000..05d38ac
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_negative.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@color/card_action_negative" android:state_pressed="true" />
+ <item android:drawable="@color/card_action_negative_focused" android:state_focused="true" />
+ <item android:drawable="@color/card_action_item_bg" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_positive.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_positive.xml
new file mode 100644
index 0000000..4e92f24
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_bg_positive.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@color/card_action_positive" android:state_pressed="true" />
+ <item android:drawable="@color/card_action_positive_focused" android:state_focused="true" />
+ <item android:drawable="@color/card_action_item_bg" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_negative.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_negative.xml
new file mode 100644
index 0000000..6a797dc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_negative.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/ic_cardaction_negative_pressed" android:state_pressed="true" />
+ <item android:drawable="@drawable/ic_cardaction_negative" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_neutral.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_neutral.xml
new file mode 100644
index 0000000..73e9214
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_neutral.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/ic_cardaction_neutral_pressed" android:state_pressed="true" />
+ <item android:drawable="@drawable/ic_cardaction_neutral" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_positive.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_positive.xml
new file mode 100644
index 0000000..63f82d6
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_icon_positive.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/ic_cardaction_positive_pressed" android:state_pressed="true" />
+ <item android:drawable="@drawable/ic_cardaction_positive" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text.xml
new file mode 100644
index 0000000..cddf5cd
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="@color/card_action_inverted" />
+ <item android:state_focused="true" android:color="@color/card_action_inverted" />
+ <item android:color="@color/card_action" />
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_negative.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_negative.xml
new file mode 100644
index 0000000..90f2c05
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_negative.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="@color/card_action_inverted"/>
+ <item android:state_focused="true" android:color="@color/card_action_inverted"/>
+ <item android:color="@color/card_action_negative"/>
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_positive.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_positive.xml
new file mode 100644
index 0000000..c3ff402
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_action_text_positive.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="@color/card_action_inverted"/>
+ <item android:state_focused="true" android:color="@color/card_action_inverted"/>
+ <item android:color="@color/card_action_positive"/>
+</selector>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_overlay_focused.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_overlay_focused.xml
new file mode 100644
index 0000000..787167d
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_overlay_focused.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <stroke
+ android:width="5dp"
+ android:color="#aa99CC00"/>
+</shape>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_separator.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_separator.xml
new file mode 100644
index 0000000..6bb5630
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/drawable/card_separator.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="line">
+ <stroke android:color="#CCC" />
+ <size android:height="1dp" />
+</shape>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..b8a123e
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<fragment
+ android:id="@+id/fragment_cardstream"
+ android:name="com.example.android.batchstepsensor.CardStreamFragment"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity"
+ tools:layout="@layout/cardstream"/>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card.xml
new file mode 100644
index 0000000..24bffeb
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<com.example.android.batchstepsensor.CardLayout
+ android:id="@+id/card_layout"
+ style="@style/Card"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:id="@+id/card_actionarea"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/card_contentarea"
+ android:background="@color/card_action_bg"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/card_action_margin"
+ android:visibility="gone"
+ >
+ <include layout="@layout/card_button_seperator"/>
+ </LinearLayout>
+
+
+ <LinearLayout
+ android:id="@id/card_contentarea"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ style="@style/CardContentArea">
+
+ <TextView
+ android:id="@+id/card_title"
+ style="@style/CardTitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <TextView
+ android:id="@+id/card_content"
+ style="@style/CardContent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/card_title"/>
+
+ </LinearLayout>
+
+ <View
+ android:id="@+id/card_overlay"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignBottom="@id/card_contentarea"
+ android:layout_alignLeft="@id/card_contentarea"
+ android:layout_alignRight="@id/card_contentarea"
+ android:layout_alignTop="@id/card_contentarea"
+ android:layout_alignWithParentIfMissing="false"
+ android:visibility="invisible"/>
+
+</com.example.android.batchstepsensor.CardLayout>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_negative.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_negative.xml
new file mode 100644
index 0000000..bf66150
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_negative.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/card_button"
+ style="@style/CardActionNegative"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical" />
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_neutral.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_neutral.xml
new file mode 100644
index 0000000..7f759fc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_neutral.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/card_button"
+ style="@style/CardActionNeutral"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical" />
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_positive.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_positive.xml
new file mode 100644
index 0000000..2011f9c
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_positive.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<com.example.android.batchstepsensor.CardActionButton xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/card_button"
+ style="@style/CardActionPositive"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical" />
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_seperator.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_seperator.xml
new file mode 100644
index 0000000..6731242
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_button_seperator.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <ImageView
+ android:id="@+id/card_separator"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:src="@drawable/card_separator" />
+
+</merge>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_progress.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_progress.xml
new file mode 100644
index 0000000..1bf349f
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/card_progress.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ style="@style/CardProgressLayout">
+
+ <TextView
+ android:id="@+id/card_progress_text"
+ style="@style/CardProgressText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ />
+
+ <ProgressBar
+ android:id="@+id/card_progress"
+ style="@android:style/Widget.Holo.ProgressBar.Horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/cardstream.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/cardstream.xml
new file mode 100644
index 0000000..463af5c
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/layout/cardstream.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="true">
+
+ <com.example.android.batchstepsensor.CardStreamLinearLayout
+ style="@style/CardStream"
+ android:id="@+id/card_stream"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ </com.example.android.batchstepsensor.CardStreamLinearLayout>
+</ScrollView>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..00059fc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v11/styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..3c02242
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..a91fd03
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v16/styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v16/styles.xml
new file mode 100644
index 0000000..2b380aa
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values-v16/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <style name="CardTitle" parent="@style/CardTitleBase">
+ <item name="android:fontFamily">sans-serif-condensed</item>
+ </style>
+
+ <style name="CardContent" parent="@style/CardContentBase">
+ <item name="android:fontFamily">sans-serif-light</item>
+ </style>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/attrs.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..16b5260
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/attrs.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <declare-styleable name="CardStream">
+ <attr name="animationDuration" format="enum">
+ <enum name="slow" value="1001"/>
+ <enum name="normal" value="1002"/>
+ <enum name="fast" value="1003"/>
+ </attr>
+ <attr name="animators" format="string"/>
+ </declare-styleable>
+
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..341b6bc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BatchStepSensor</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates the use of the two step sensors (step detector and counter) and
+ sensor batching.\n\n It shows how to register a SensorEventListener with and without
+ batching and shows how these events are received.\n\nThe Step Detector sensor fires an
+ event when a step is detected, while the step counter returns the total number of
+ steps since a listener was first registered for this sensor.
+ Both sensors only count steps while a listener is registered. This sample only covers the
+ basic case, where a listener is only registered while the app is running. Likewise,
+ batched sensors can be used in the background (when the CPU is suspended), which
+ requires manually flushing the sensor event queue before it overflows, which is not
+ covered in this sample.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/color.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/color.xml
new file mode 100644
index 0000000..98717d8
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/color.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <color name="card_action_inverted">@android:color/white</color>
+
+ <color name="card_content_textcolor">#444</color>
+
+ <color name="card_action_bg">#DDD</color>
+ <color name="card_action_item_bg">#F4F4F4</color>
+
+ <!-- Neutral Actions -->
+ <color name="card_action_focused">#FFE3F4FC</color>
+ <color name="card_action">#FF47B4EA</color>
+
+ <!-- Negative Actions -->
+ <color name="card_action_negative_focused">#FFFBCBCA</color>
+ <color name="card_action_negative">#FFF64940</color>
+
+ <!-- Positive Actions -->
+ <color name="card_action_positive_focused">#FFE4F0AF</color>
+ <color name="card_action_positive">#FFA0CC00</color>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/dimens.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..b025f1f
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/dimens.xml
@@ -0,0 +1,14 @@
+<resources>
+
+ <dimen name="card_content_text">14sp</dimen>
+ <dimen name="card_content_title">24sp</dimen>
+
+ <dimen name="card_padding">15dp</dimen>
+ <dimen name="card_margin">10dp</dimen>
+
+ <dimen name="card_action_margin">3dp</dimen>
+ <dimen name="card_action_padding">8dp</dimen>
+
+ <dimen name="card_stream_bottom_padding">90dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/ids.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/ids.xml
new file mode 100644
index 0000000..c5d1b78
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/ids.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <item name="card_layout" type="id"/>
+ <item name="card_actionarea" type="id"/>
+ <item name="card_contentarea" type="id"/>
+ <item name="card_title" type="id"/>
+ <item name="card_content" type="id"/>
+ <item name="card_overlay" type="id"/>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/strings.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9c0a8ad
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/strings.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string name="intro_title">Introduction</string>
+
+ <string name="batching_queue_title">Background sensor batching</string>
+ <string name="batching_queue_description">Batching allows the sensor to report sensor events at
+ a specified frequency.\n\nThe system delays calls to the SensorEventListener and deliver
+ them in intervals, based on the maximum report latency specified when the listener is
+ registered. Note that this only means that the call to onSensorChanged() is delayed, the
+ total number of calls is identical as if no batching was used. Sensors only deliver events
+ while the CPU is awake. If the CPU is asleep and a batched sensor event listener is still
+ registered, the sensor will continue to collect events until it runs out of memory and
+ overwrites old values. This use case is not covered by this sample. (The sensor event queue
+ should be flushed using a scheduled background thread.) \n\nIn this sample app data is only
+ collected while the app is running and the CPU is awake. In this case the sensor will
+ deliver events before the queue fills up.
+ </string>
+
+ <string name="explanation_description">The age of a sensor event describes the delay between
+ when it was recorded by the sensor until it was delivered to the SensorEventListener.
+ </string>
+
+ <string name="register_detector_title">Register step detector sensor</string>
+ <string name="register_detector_description">Register a listener for the STEP DETECTOR
+ sensor.\n\nThis sensor delivers an event when the user takes a step. One event is received
+ per step.
+ </string>
+
+ <string name="register_counter_title">Register step counter sensor</string>
+ <string name="register_counter_description">Register a listener for the STEP COUNTER
+ sensor.\n\nThis sensor triggers events when a step is detected, but applies algorithms to
+ filter out false positives. Events from this sensor have higher latency than the step
+ detector and contain the total number of steps taken since the sensor was first registered.
+ </string>
+
+ <string name="register_0">No batching (delay=0)</string>
+ <string name="register_5">5s batching (delay=5000ms)</string>
+ <string name="register_10">10s batching (delay=10000ms)</string>
+
+ <string name="counting_title">Total Steps: %1$d</string>
+ <string name="sensor_counter">Step Counter</string>
+ <string name="sensor_detector">Step Detector</string>
+ <string name="counting_description">Sensor: %1$s\nMax sensor event delay: %2$,d \u00B5s\nAge of
+ events in s:\n%3$s
+ </string>
+
+ <string name="error_title">Error</string>
+ <string name="error_nosensor">This sample requires at least Android KitKat (4.4) and a device
+ with the step sensor.\n\nThis device does not appear to meet these requirements, as an
+ alternative you may want to consider using the gyro sensor and implement your own step
+ recognition as a fallback.
+ </string>
+ <string name="warning_nobatching">The listener has been registered, but batch mode could not be
+ enabled.\n\nIt is likely that it is not supported by this device.\n\nSensor events will be
+ delivered in continuous mode.
+ </string>
+
+ <string name="action_notagain">Do not show again</string>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..23e8181
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/styles.xml
@@ -0,0 +1,92 @@
+<resources>
+
+ <!-- Card Stream -->
+ <style name="CardStream">
+ <item name="android:paddingBottom">@dimen/card_stream_bottom_padding</item>
+ <item name="android:divider">@null</item>
+ <item name="android:orientation">vertical</item>
+ </style>
+
+ <!-- Main card -->
+ <style name="Card">
+ <item name="android:background">@drawable/card_bg</item>
+ <item name="android:layout_margin">@dimen/card_margin</item>
+ </style>
+
+ <style name="CardContentArea">
+ <item name="android:paddingBottom">@dimen/card_padding</item>
+ </style>
+
+ <style name="CardActionArea">
+ <item name="android:background">@color/card_action_bg</item>
+ <item name="android:orientation">vertical</item>
+ <item name="android:paddingBottom">@dimen/card_action_margin</item>
+ </style>
+
+ <style name="CardElement">
+ <item name="android:paddingLeft">@dimen/card_padding</item>
+ <item name="android:paddingRight">@dimen/card_padding</item>
+ </style>
+
+ <!-- Content of main card -->
+ <style name="CardTitleBase" parent="@style/CardElement">
+ <item name="android:paddingTop">@dimen/card_padding</item>
+ <item name="android:textSize">@dimen/card_content_title</item>
+ </style>
+
+ <style name="CardTitle" parent="@style/CardTitleBase">
+ </style>
+
+ <style name="CardContentBase" parent="@style/CardElement">
+ <item name="android:paddingTop">@dimen/card_padding</item>
+ <item name="android:textSize">@dimen/card_content_text</item>
+ <item name="android:textColor">@color/card_content_textcolor</item>
+ </style>
+
+ <style name="CardContent" parent="@style/CardContentBase">
+ </style>
+
+ <!-- Action Area Items -->
+ <style name="CardAction">
+ <item name="android:textSize">17sp</item>
+ <item name="android:layout_marginTop">@dimen/card_action_margin</item>
+ <item name="android:layout_marginLeft">@dimen/card_action_margin</item>
+ <item name="android:layout_marginRight">@dimen/card_action_margin</item>
+ <item name="android:paddingLeft">@dimen/card_action_padding</item>
+ <item name="android:drawablePadding">@dimen/card_action_padding</item>
+ </style>
+
+ <style name="CardActionNeutral" parent="@style/CardAction">
+ <item name="android:background">@drawable/card_action_bg</item>
+ <item name="android:drawableStart">@drawable/card_action_icon_neutral</item>
+ <item name="android:textColor">@drawable/card_action_text</item>
+ </style>
+
+ <style name="CardActionNegative" parent="@style/CardAction">
+ <item name="android:background">@drawable/card_action_bg_negative</item>
+ <item name="android:drawableStart">@drawable/card_action_icon_negative</item>
+ <item name="android:textColor">@drawable/card_action_text_negative</item>
+ </style>
+
+ <style name="CardActionPositive" parent="@style/CardAction">
+ <item name="android:background">@drawable/card_action_bg_positive</item>
+ <item name="android:drawableStart">@drawable/card_action_icon_positive</item>
+ <item name="android:textColor">@drawable/card_action_text_positive</item>
+ </style>
+
+ <!-- Card Action Progress -->
+ <style name="CardProgressLayout" parent="@style/CardAction">
+ <item name="android:layout_marginLeft">@dimen/card_action_margin</item>
+ <item name="android:layout_marginRight">@dimen/card_action_margin</item>
+ <item name="android:paddingLeft">@dimen/card_action_padding</item>
+ <item name="android:paddingRight">@dimen/card_action_padding</item>
+ <item name="android:background">#EEE</item>
+ </style>
+
+ <style name="CardProgressText" parent="@style/CardAction">
+ <item name="android:textColor">#77000000</item>
+ <item name="android:textSize">12sp</item>
+ <item name="android:paddingLeft">0dp</item>
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/BatchStepSensorSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BatchStepSensor/README.txt b/prebuilts/gradle/BatchStepSensor/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BatchStepSensor/build.gradle b/prebuilts/gradle/BatchStepSensor/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..56f685a
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/BatchStepSensor/gradlew b/prebuilts/gradle/BatchStepSensor/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BatchStepSensor/gradlew.bat b/prebuilts/gradle/BatchStepSensor/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BatchStepSensor/settings.gradle b/prebuilts/gradle/BatchStepSensor/settings.gradle
new file mode 100644
index 0000000..18ebefc
--- /dev/null
+++ b/prebuilts/gradle/BatchStepSensor/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BatchStepSensorSample'
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/build.gradle b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/build.gradle
new file mode 100644
index 0000000..7bfc9ad
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 18
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..babd6df
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.bluetoothlegatt"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="18"
+ android:targetSdkVersion="18"/>
+ <!-- Declare this required feature if you want to make the app available to BLE-capable
+ devices only. If you want to make your app available to devices that don't support BLE,
+ you should omit this in the manifest. Instead, determine BLE capability by using
+ PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) -->
+ <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
+
+ <uses-permission android:name="android.permission.BLUETOOTH"/>
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@android:style/Theme.Holo.Light">
+ <activity android:name=".DeviceScanActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+ <activity android:name=".DeviceControlActivity"/>
+ <service android:name=".BluetoothLeService" android:enabled="true"/>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/BluetoothLeService.java b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/BluetoothLeService.java
new file mode 100644
index 0000000..694faaf
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/BluetoothLeService.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2013 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.bluetoothlegatt;
+
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattService;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Service for managing connection and data communication with a GATT server hosted on a
+ * given Bluetooth LE device.
+ */
+public class BluetoothLeService extends Service {
+ private final static String TAG = BluetoothLeService.class.getSimpleName();
+
+ private BluetoothManager mBluetoothManager;
+ private BluetoothAdapter mBluetoothAdapter;
+ private String mBluetoothDeviceAddress;
+ private BluetoothGatt mBluetoothGatt;
+ private int mConnectionState = STATE_DISCONNECTED;
+
+ private static final int STATE_DISCONNECTED = 0;
+ private static final int STATE_CONNECTING = 1;
+ private static final int STATE_CONNECTED = 2;
+
+ public final static String ACTION_GATT_CONNECTED =
+ "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
+ public final static String ACTION_GATT_DISCONNECTED =
+ "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
+ public final static String ACTION_GATT_SERVICES_DISCOVERED =
+ "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
+ public final static String ACTION_DATA_AVAILABLE =
+ "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
+ public final static String EXTRA_DATA =
+ "com.example.bluetooth.le.EXTRA_DATA";
+
+ public final static UUID UUID_HEART_RATE_MEASUREMENT =
+ UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
+
+ // Implements callback methods for GATT events that the app cares about. For example,
+ // connection change and services discovered.
+ private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
+ @Override
+ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+ String intentAction;
+ if (newState == BluetoothProfile.STATE_CONNECTED) {
+ intentAction = ACTION_GATT_CONNECTED;
+ mConnectionState = STATE_CONNECTED;
+ broadcastUpdate(intentAction);
+ Log.i(TAG, "Connected to GATT server.");
+ // Attempts to discover services after successful connection.
+ Log.i(TAG, "Attempting to start service discovery:" +
+ mBluetoothGatt.discoverServices());
+
+ } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
+ intentAction = ACTION_GATT_DISCONNECTED;
+ mConnectionState = STATE_DISCONNECTED;
+ Log.i(TAG, "Disconnected from GATT server.");
+ broadcastUpdate(intentAction);
+ }
+ }
+
+ @Override
+ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+ if (status == BluetoothGatt.GATT_SUCCESS) {
+ broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
+ } else {
+ Log.w(TAG, "onServicesDiscovered received: " + status);
+ }
+ }
+
+ @Override
+ public void onCharacteristicRead(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic,
+ int status) {
+ if (status == BluetoothGatt.GATT_SUCCESS) {
+ broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
+ }
+ }
+
+ @Override
+ public void onCharacteristicChanged(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic) {
+ broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
+ }
+ };
+
+ private void broadcastUpdate(final String action) {
+ final Intent intent = new Intent(action);
+ sendBroadcast(intent);
+ }
+
+ private void broadcastUpdate(final String action,
+ final BluetoothGattCharacteristic characteristic) {
+ final Intent intent = new Intent(action);
+
+ // This is special handling for the Heart Rate Measurement profile. Data parsing is
+ // carried out as per profile specifications:
+ // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
+ if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
+ int flag = characteristic.getProperties();
+ int format = -1;
+ if ((flag & 0x01) != 0) {
+ format = BluetoothGattCharacteristic.FORMAT_UINT16;
+ Log.d(TAG, "Heart rate format UINT16.");
+ } else {
+ format = BluetoothGattCharacteristic.FORMAT_UINT8;
+ Log.d(TAG, "Heart rate format UINT8.");
+ }
+ final int heartRate = characteristic.getIntValue(format, 1);
+ Log.d(TAG, String.format("Received heart rate: %d", heartRate));
+ intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
+ } else {
+ // For all other profiles, writes the data formatted in HEX.
+ final byte[] data = characteristic.getValue();
+ if (data != null && data.length > 0) {
+ final StringBuilder stringBuilder = new StringBuilder(data.length);
+ for(byte byteChar : data)
+ stringBuilder.append(String.format("%02X ", byteChar));
+ intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
+ }
+ }
+ sendBroadcast(intent);
+ }
+
+ public class LocalBinder extends Binder {
+ BluetoothLeService getService() {
+ return BluetoothLeService.this;
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ // After using a given device, you should make sure that BluetoothGatt.close() is called
+ // such that resources are cleaned up properly. In this particular example, close() is
+ // invoked when the UI is disconnected from the Service.
+ close();
+ return super.onUnbind(intent);
+ }
+
+ private final IBinder mBinder = new LocalBinder();
+
+ /**
+ * Initializes a reference to the local Bluetooth adapter.
+ *
+ * @return Return true if the initialization is successful.
+ */
+ public boolean initialize() {
+ // For API level 18 and above, get a reference to BluetoothAdapter through
+ // BluetoothManager.
+ if (mBluetoothManager == null) {
+ mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ if (mBluetoothManager == null) {
+ Log.e(TAG, "Unable to initialize BluetoothManager.");
+ return false;
+ }
+ }
+
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ if (mBluetoothAdapter == null) {
+ Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Connects to the GATT server hosted on the Bluetooth LE device.
+ *
+ * @param address The device address of the destination device.
+ *
+ * @return Return true if the connection is initiated successfully. The connection result
+ * is reported asynchronously through the
+ * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
+ * callback.
+ */
+ public boolean connect(final String address) {
+ if (mBluetoothAdapter == null || address == null) {
+ Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
+ return false;
+ }
+
+ // Previously connected device. Try to reconnect.
+ if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
+ && mBluetoothGatt != null) {
+ Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
+ if (mBluetoothGatt.connect()) {
+ mConnectionState = STATE_CONNECTING;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
+ if (device == null) {
+ Log.w(TAG, "Device not found. Unable to connect.");
+ return false;
+ }
+ // We want to directly connect to the device, so we are setting the autoConnect
+ // parameter to false.
+ mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
+ Log.d(TAG, "Trying to create a new connection.");
+ mBluetoothDeviceAddress = address;
+ mConnectionState = STATE_CONNECTING;
+ return true;
+ }
+
+ /**
+ * Disconnects an existing connection or cancel a pending connection. The disconnection result
+ * is reported asynchronously through the
+ * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
+ * callback.
+ */
+ public void disconnect() {
+ if (mBluetoothAdapter == null || mBluetoothGatt == null) {
+ Log.w(TAG, "BluetoothAdapter not initialized");
+ return;
+ }
+ mBluetoothGatt.disconnect();
+ }
+
+ /**
+ * After using a given BLE device, the app must call this method to ensure resources are
+ * released properly.
+ */
+ public void close() {
+ if (mBluetoothGatt == null) {
+ return;
+ }
+ mBluetoothGatt.close();
+ mBluetoothGatt = null;
+ }
+
+ /**
+ * Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
+ * asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
+ * callback.
+ *
+ * @param characteristic The characteristic to read from.
+ */
+ public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
+ if (mBluetoothAdapter == null || mBluetoothGatt == null) {
+ Log.w(TAG, "BluetoothAdapter not initialized");
+ return;
+ }
+ mBluetoothGatt.readCharacteristic(characteristic);
+ }
+
+ /**
+ * Enables or disables notification on a give characteristic.
+ *
+ * @param characteristic Characteristic to act on.
+ * @param enabled If true, enable notification. False otherwise.
+ */
+ public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
+ boolean enabled) {
+ if (mBluetoothAdapter == null || mBluetoothGatt == null) {
+ Log.w(TAG, "BluetoothAdapter not initialized");
+ return;
+ }
+ mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
+
+ // This is specific to Heart Rate Measurement.
+ if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
+ BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
+ UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
+ descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
+ mBluetoothGatt.writeDescriptor(descriptor);
+ }
+ }
+
+ /**
+ * Retrieves a list of supported GATT services on the connected device. This should be
+ * invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
+ *
+ * @return A {@code List} of supported services.
+ */
+ public List<BluetoothGattService> getSupportedGattServices() {
+ if (mBluetoothGatt == null) return null;
+
+ return mBluetoothGatt.getServices();
+ }
+}
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceControlActivity.java b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceControlActivity.java
new file mode 100644
index 0000000..dc2f90b
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceControlActivity.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2013 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.bluetoothlegatt;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattService;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ExpandableListView;
+import android.widget.SimpleExpandableListAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * For a given BLE device, this Activity provides the user interface to connect, display data,
+ * and display GATT services and characteristics supported by the device. The Activity
+ * communicates with {@code BluetoothLeService}, which in turn interacts with the
+ * Bluetooth LE API.
+ */
+public class DeviceControlActivity extends Activity {
+ private final static String TAG = DeviceControlActivity.class.getSimpleName();
+
+ public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
+ public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
+
+ private TextView mConnectionState;
+ private TextView mDataField;
+ private String mDeviceName;
+ private String mDeviceAddress;
+ private ExpandableListView mGattServicesList;
+ private BluetoothLeService mBluetoothLeService;
+ private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
+ new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
+ private boolean mConnected = false;
+ private BluetoothGattCharacteristic mNotifyCharacteristic;
+
+ private final String LIST_NAME = "NAME";
+ private final String LIST_UUID = "UUID";
+
+ // Code to manage Service lifecycle.
+ private final ServiceConnection mServiceConnection = new ServiceConnection() {
+
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder service) {
+ mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
+ if (!mBluetoothLeService.initialize()) {
+ Log.e(TAG, "Unable to initialize Bluetooth");
+ finish();
+ }
+ // Automatically connects to the device upon successful start-up initialization.
+ mBluetoothLeService.connect(mDeviceAddress);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) {
+ mBluetoothLeService = null;
+ }
+ };
+
+ // Handles various events fired by the Service.
+ // ACTION_GATT_CONNECTED: connected to a GATT server.
+ // ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
+ // ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
+ // ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read
+ // or notification operations.
+ private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
+ mConnected = true;
+ updateConnectionState(R.string.connected);
+ invalidateOptionsMenu();
+ } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
+ mConnected = false;
+ updateConnectionState(R.string.disconnected);
+ invalidateOptionsMenu();
+ clearUI();
+ } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
+ // Show all the supported services and characteristics on the user interface.
+ displayGattServices(mBluetoothLeService.getSupportedGattServices());
+ } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
+ displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
+ }
+ }
+ };
+
+ // If a given GATT characteristic is selected, check for supported features. This sample
+ // demonstrates 'Read' and 'Notify' features. See
+ // http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
+ // list of supported characteristic features.
+ private final ExpandableListView.OnChildClickListener servicesListClickListner =
+ new ExpandableListView.OnChildClickListener() {
+ @Override
+ public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
+ int childPosition, long id) {
+ if (mGattCharacteristics != null) {
+ final BluetoothGattCharacteristic characteristic =
+ mGattCharacteristics.get(groupPosition).get(childPosition);
+ final int charaProp = characteristic.getProperties();
+ if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
+ // If there is an active notification on a characteristic, clear
+ // it first so it doesn't update the data field on the user interface.
+ if (mNotifyCharacteristic != null) {
+ mBluetoothLeService.setCharacteristicNotification(
+ mNotifyCharacteristic, false);
+ mNotifyCharacteristic = null;
+ }
+ mBluetoothLeService.readCharacteristic(characteristic);
+ }
+ if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
+ mNotifyCharacteristic = characteristic;
+ mBluetoothLeService.setCharacteristicNotification(
+ characteristic, true);
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ private void clearUI() {
+ mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
+ mDataField.setText(R.string.no_data);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.gatt_services_characteristics);
+
+ final Intent intent = getIntent();
+ mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
+ mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
+
+ // Sets up UI references.
+ ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
+ mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
+ mGattServicesList.setOnChildClickListener(servicesListClickListner);
+ mConnectionState = (TextView) findViewById(R.id.connection_state);
+ mDataField = (TextView) findViewById(R.id.data_value);
+
+ getActionBar().setTitle(mDeviceName);
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
+ bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
+ if (mBluetoothLeService != null) {
+ final boolean result = mBluetoothLeService.connect(mDeviceAddress);
+ Log.d(TAG, "Connect request result=" + result);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ unregisterReceiver(mGattUpdateReceiver);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unbindService(mServiceConnection);
+ mBluetoothLeService = null;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.gatt_services, menu);
+ if (mConnected) {
+ menu.findItem(R.id.menu_connect).setVisible(false);
+ menu.findItem(R.id.menu_disconnect).setVisible(true);
+ } else {
+ menu.findItem(R.id.menu_connect).setVisible(true);
+ menu.findItem(R.id.menu_disconnect).setVisible(false);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_connect:
+ mBluetoothLeService.connect(mDeviceAddress);
+ return true;
+ case R.id.menu_disconnect:
+ mBluetoothLeService.disconnect();
+ return true;
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void updateConnectionState(final int resourceId) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mConnectionState.setText(resourceId);
+ }
+ });
+ }
+
+ private void displayData(String data) {
+ if (data != null) {
+ mDataField.setText(data);
+ }
+ }
+
+ // Demonstrates how to iterate through the supported GATT Services/Characteristics.
+ // In this sample, we populate the data structure that is bound to the ExpandableListView
+ // on the UI.
+ private void displayGattServices(List<BluetoothGattService> gattServices) {
+ if (gattServices == null) return;
+ String uuid = null;
+ String unknownServiceString = getResources().getString(R.string.unknown_service);
+ String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
+ ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
+ ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
+ = new ArrayList<ArrayList<HashMap<String, String>>>();
+ mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
+
+ // Loops through available GATT Services.
+ for (BluetoothGattService gattService : gattServices) {
+ HashMap<String, String> currentServiceData = new HashMap<String, String>();
+ uuid = gattService.getUuid().toString();
+ currentServiceData.put(
+ LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
+ currentServiceData.put(LIST_UUID, uuid);
+ gattServiceData.add(currentServiceData);
+
+ ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
+ new ArrayList<HashMap<String, String>>();
+ List<BluetoothGattCharacteristic> gattCharacteristics =
+ gattService.getCharacteristics();
+ ArrayList<BluetoothGattCharacteristic> charas =
+ new ArrayList<BluetoothGattCharacteristic>();
+
+ // Loops through available Characteristics.
+ for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
+ charas.add(gattCharacteristic);
+ HashMap<String, String> currentCharaData = new HashMap<String, String>();
+ uuid = gattCharacteristic.getUuid().toString();
+ currentCharaData.put(
+ LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
+ currentCharaData.put(LIST_UUID, uuid);
+ gattCharacteristicGroupData.add(currentCharaData);
+ }
+ mGattCharacteristics.add(charas);
+ gattCharacteristicData.add(gattCharacteristicGroupData);
+ }
+
+ SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
+ this,
+ gattServiceData,
+ android.R.layout.simple_expandable_list_item_2,
+ new String[] {LIST_NAME, LIST_UUID},
+ new int[] { android.R.id.text1, android.R.id.text2 },
+ gattCharacteristicData,
+ android.R.layout.simple_expandable_list_item_2,
+ new String[] {LIST_NAME, LIST_UUID},
+ new int[] { android.R.id.text1, android.R.id.text2 }
+ );
+ mGattServicesList.setAdapter(gattServiceAdapter);
+ }
+
+ private static IntentFilter makeGattUpdateIntentFilter() {
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
+ intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
+ intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
+ intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
+ return intentFilter;
+ }
+}
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceScanActivity.java b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceScanActivity.java
new file mode 100644
index 0000000..9b86f7a
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/DeviceScanActivity.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2013 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.bluetoothlegatt;
+
+import android.app.Activity;
+import android.app.ListActivity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+
+/**
+ * Activity for scanning and displaying available Bluetooth LE devices.
+ */
+public class DeviceScanActivity extends ListActivity {
+ private LeDeviceListAdapter mLeDeviceListAdapter;
+ private BluetoothAdapter mBluetoothAdapter;
+ private boolean mScanning;
+ private Handler mHandler;
+
+ private static final int REQUEST_ENABLE_BT = 1;
+ // Stops scanning after 10 seconds.
+ private static final long SCAN_PERIOD = 10000;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getActionBar().setTitle(R.string.title_devices);
+ mHandler = new Handler();
+
+ // Use this check to determine whether BLE is supported on the device. Then you can
+ // selectively disable BLE-related features.
+ if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
+ Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+
+ // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
+ // BluetoothAdapter through BluetoothManager.
+ final BluetoothManager bluetoothManager =
+ (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ mBluetoothAdapter = bluetoothManager.getAdapter();
+
+ // Checks if Bluetooth is supported on the device.
+ if (mBluetoothAdapter == null) {
+ Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
+ finish();
+ return;
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ if (!mScanning) {
+ menu.findItem(R.id.menu_stop).setVisible(false);
+ menu.findItem(R.id.menu_scan).setVisible(true);
+ menu.findItem(R.id.menu_refresh).setActionView(null);
+ } else {
+ menu.findItem(R.id.menu_stop).setVisible(true);
+ menu.findItem(R.id.menu_scan).setVisible(false);
+ menu.findItem(R.id.menu_refresh).setActionView(
+ R.layout.actionbar_indeterminate_progress);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_scan:
+ mLeDeviceListAdapter.clear();
+ scanLeDevice(true);
+ break;
+ case R.id.menu_stop:
+ scanLeDevice(false);
+ break;
+ }
+ return true;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
+ // fire an intent to display a dialog asking the user to grant permission to enable it.
+ if (!mBluetoothAdapter.isEnabled()) {
+ if (!mBluetoothAdapter.isEnabled()) {
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ }
+ }
+
+ // Initializes list view adapter.
+ mLeDeviceListAdapter = new LeDeviceListAdapter();
+ setListAdapter(mLeDeviceListAdapter);
+ scanLeDevice(true);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // User chose not to enable Bluetooth.
+ if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
+ finish();
+ return;
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ scanLeDevice(false);
+ mLeDeviceListAdapter.clear();
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ final BluetoothDevice device = mLeDeviceListAdapter.getDevice(position);
+ if (device == null) return;
+ final Intent intent = new Intent(this, DeviceControlActivity.class);
+ intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_NAME, device.getName());
+ intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
+ if (mScanning) {
+ mBluetoothAdapter.stopLeScan(mLeScanCallback);
+ mScanning = false;
+ }
+ startActivity(intent);
+ }
+
+ private void scanLeDevice(final boolean enable) {
+ if (enable) {
+ // Stops scanning after a pre-defined scan period.
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mScanning = false;
+ mBluetoothAdapter.stopLeScan(mLeScanCallback);
+ invalidateOptionsMenu();
+ }
+ }, SCAN_PERIOD);
+
+ mScanning = true;
+ mBluetoothAdapter.startLeScan(mLeScanCallback);
+ } else {
+ mScanning = false;
+ mBluetoothAdapter.stopLeScan(mLeScanCallback);
+ }
+ invalidateOptionsMenu();
+ }
+
+ // Adapter for holding devices found through scanning.
+ private class LeDeviceListAdapter extends BaseAdapter {
+ private ArrayList<BluetoothDevice> mLeDevices;
+ private LayoutInflater mInflator;
+
+ public LeDeviceListAdapter() {
+ super();
+ mLeDevices = new ArrayList<BluetoothDevice>();
+ mInflator = DeviceScanActivity.this.getLayoutInflater();
+ }
+
+ public void addDevice(BluetoothDevice device) {
+ if(!mLeDevices.contains(device)) {
+ mLeDevices.add(device);
+ }
+ }
+
+ public BluetoothDevice getDevice(int position) {
+ return mLeDevices.get(position);
+ }
+
+ public void clear() {
+ mLeDevices.clear();
+ }
+
+ @Override
+ public int getCount() {
+ return mLeDevices.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return mLeDevices.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ ViewHolder viewHolder;
+ // General ListView optimization code.
+ if (view == null) {
+ view = mInflator.inflate(R.layout.listitem_device, null);
+ viewHolder = new ViewHolder();
+ viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
+ viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
+ view.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
+ }
+
+ BluetoothDevice device = mLeDevices.get(i);
+ final String deviceName = device.getName();
+ if (deviceName != null && deviceName.length() > 0)
+ viewHolder.deviceName.setText(deviceName);
+ else
+ viewHolder.deviceName.setText(R.string.unknown_device);
+ viewHolder.deviceAddress.setText(device.getAddress());
+
+ return view;
+ }
+ }
+
+ // Device scan callback.
+ private BluetoothAdapter.LeScanCallback mLeScanCallback =
+ new BluetoothAdapter.LeScanCallback() {
+
+ @Override
+ public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mLeDeviceListAdapter.addDevice(device);
+ mLeDeviceListAdapter.notifyDataSetChanged();
+ }
+ });
+ }
+ };
+
+ static class ViewHolder {
+ TextView deviceName;
+ TextView deviceAddress;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/SampleGattAttributes.java b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/SampleGattAttributes.java
new file mode 100644
index 0000000..e8db74c
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/java/com/example/android/bluetoothlegatt/SampleGattAttributes.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2013 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.bluetoothlegatt;
+
+import java.util.HashMap;
+
+/**
+ * This class includes a small subset of standard GATT attributes for demonstration purposes.
+ */
+public class SampleGattAttributes {
+ private static HashMap<String, String> attributes = new HashMap();
+ public static String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb";
+ public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
+
+ static {
+ // Sample Services.
+ attributes.put("0000180d-0000-1000-8000-00805f9b34fb", "Heart Rate Service");
+ attributes.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information Service");
+ // Sample Characteristics.
+ attributes.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement");
+ attributes.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String");
+ }
+
+ public static String lookup(String uuid, String defaultName) {
+ String name = attributes.get(uuid);
+ return name == null ? defaultName : name;
+ }
+}
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..15367c0
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..ba810a7
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..14f1d74
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..81ff9cc
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/actionbar_indeterminate_progress.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/actionbar_indeterminate_progress.xml
new file mode 100644
index 0000000..a950833
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/actionbar_indeterminate_progress.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 Google Inc.
+
+ 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.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="wrap_content"
+ android:layout_width="56dp"
+ android:minWidth="56dp">
+ <ProgressBar android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:layout_gravity="center"/>
+</FrameLayout>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/gatt_services_characteristics.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/gatt_services_characteristics.xml
new file mode 100644
index 0000000..2f31061
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/gatt_services_characteristics.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp">
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp">
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/label_device_address"
+ android:textSize="18sp"/>
+ <Space android:layout_width="5dp"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/device_address"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"/>
+ </LinearLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp">
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/label_state"
+ android:textSize="18sp"/>
+ <Space android:layout_width="5dp"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/connection_state"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/disconnected"
+ android:textSize="18sp"/>
+ </LinearLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp">
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/label_data"
+ android:textSize="18sp"/>
+ <Space android:layout_width="5dp"
+ android:layout_height="wrap_content"/>
+ <TextView android:id="@+id/data_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/no_data"
+ android:textSize="18sp"/>
+ </LinearLayout>
+ <ExpandableListView android:id="@+id/gatt_services_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/listitem_device.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/listitem_device.xml
new file mode 100644
index 0000000..eff44fc
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/layout/listitem_device.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <TextView android:id="@+id/device_name"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="24dp"/>
+ <TextView android:id="@+id/device_address"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="12dp"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/gatt_services.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/gatt_services.xml
new file mode 100644
index 0000000..464d32f
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/gatt_services.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_refresh"
+ android:checkable="false"
+ android:orderInCategory="1"
+ android:showAsAction="ifRoom"/>
+ <item android:id="@+id/menu_connect"
+ android:title="@string/menu_connect"
+ android:orderInCategory="100"
+ android:showAsAction="ifRoom|withText"/>
+ <item android:id="@+id/menu_disconnect"
+ android:title="@string/menu_disconnect"
+ android:orderInCategory="101"
+ android:showAsAction="ifRoom|withText"/>
+</menu>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/main.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..39dd66a
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/menu/main.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_refresh"
+ android:checkable="false"
+ android:orderInCategory="1"
+ android:showAsAction="ifRoom"/>
+ <item android:id="@+id/menu_scan"
+ android:title="@string/menu_scan"
+ android:orderInCategory="100"
+ android:showAsAction="ifRoom|withText"/>
+ <item android:id="@+id/menu_stop"
+ android:title="@string/menu_stop"
+ android:orderInCategory="101"
+ android:showAsAction="ifRoom|withText"/>
+</menu>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..58b49a9
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BluetoothLeGatt</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to use the Bluetooth LE Generic Attribute Profile (GATT)
+ to transmit arbitrary data between devices.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/strings.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..19f3dce
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<resources>
+ <string name="ble_not_supported">BLE is not supported</string>
+ <string name="label_data">Data:</string>
+ <string name="label_device_address">Device address:</string>
+ <string name="label_state">State:</string>
+ <string name="no_data">No data</string>
+ <string name="connected">Connected</string>
+ <string name="disconnected">Disconnected</string>
+ <string name="title_devices">BLE Device Scan</string>
+ <string name="error_bluetooth_not_supported">Bluetooth not supported.</string>
+
+ <string name="unknown_device">Unknown device</string>
+ <string name="unknown_characteristic">Unknown characteristic</string>
+ <string name="unknown_service">Unknown service</string>
+
+ <!-- Menu items -->
+ <string name="menu_connect">Connect</string>
+ <string name="menu_disconnect">Disconnect</string>
+ <string name="menu_scan">Scan</string>
+ <string name="menu_stop">Stop</string>
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/BluetoothLeGattSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BluetoothLeGatt/README.txt b/prebuilts/gradle/BluetoothLeGatt/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BluetoothLeGatt/build.gradle b/prebuilts/gradle/BluetoothLeGatt/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BluetoothLeGatt/gradlew b/prebuilts/gradle/BluetoothLeGatt/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BluetoothLeGatt/gradlew.bat b/prebuilts/gradle/BluetoothLeGatt/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BluetoothLeGatt/settings.gradle b/prebuilts/gradle/BluetoothLeGatt/settings.gradle
new file mode 100644
index 0000000..05cae43
--- /dev/null
+++ b/prebuilts/gradle/BluetoothLeGatt/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BluetoothLeGattSample'
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/build.gradle b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/build.gradle
new file mode 100644
index 0000000..506795f
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 14
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/AndroidManifest.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..34b2898
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.borderlessbuttons"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!--
+ This sample requires API 11 for use of theme attributes such as ?android:buttonBarStyle
+ and ?android:borderlessButtonStyle, as well as LinearLayout's android:showDividers attribute.
+ A similar effect can be achieved by setting a clickable view's background to
+ ?android:selectableItemBackground.
+
+ This sample requires API 14 for use of theme attributes such as
+ ?android:listPreferredItemPaddingLeft.
+ -->
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.Sample"
+ android:allowBackup="true">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/borderlessbuttons/MainActivity.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/borderlessbuttons/MainActivity.java
new file mode 100755
index 0000000..04105f4
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/borderlessbuttons/MainActivity.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2013 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.borderlessbuttons;
+
+import android.app.ListActivity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.Toast;
+
+/**
+ * This activity demonstrates the <b>borderless button</b> styling from the Holo visual language.
+ * The most interesting bits in this sample are in the layout files (res/layout/).
+ * <p>
+ * See <a href="http://developer.android.com/design/building-blocks/buttons.html#borderless">
+ * borderless buttons</a> at the Android Design guide for a discussion of this visual style.
+ */
+public class MainActivity extends ListActivity {
+ private static final Uri DOCS_URI = Uri.parse(
+ "http://developer.android.com/design/building-blocks/buttons.html#borderless");
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ setListAdapter(mListAdapter);
+
+ findViewById(R.id.cancel_button).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ });
+
+ findViewById(R.id.ok_button).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ });
+ }
+
+ private BaseAdapter mListAdapter = new BaseAdapter() {
+ @Override
+ public int getCount() {
+ return 10;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position + 1;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
+ }
+
+ // Because the list item contains multiple touch targets, you should not override
+ // onListItemClick. Instead, set a click listener for each target individually.
+
+ convertView.findViewById(R.id.primary_target).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Toast.makeText(MainActivity.this,
+ R.string.touched_primary_message,
+ Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ convertView.findViewById(R.id.secondary_action).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Toast.makeText(MainActivity.this,
+ R.string.touched_secondary_message,
+ Toast.LENGTH_SHORT).show();
+ }
+ });
+ return convertView;
+ }
+ };
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.docs_link:
+ try {
+ startActivity(new Intent(Intent.ACTION_VIEW, DOCS_URI));
+ } catch (ActivityNotFoundException ignored) {
+ }
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_action_delete.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_action_delete.png
new file mode 100644
index 0000000..e9ce89e
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_action_delete.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_action_delete.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_action_delete.png
new file mode 100644
index 0000000..cedb108
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_action_delete.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_action_delete.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_action_delete.png
new file mode 100644
index 0000000..98c73da
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_action_delete.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/list_item.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..1966be9
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/list_item.xml
@@ -0,0 +1,87 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<!--
+ For list items that contain secondary actions (in this case, 'delete'),
+ it's important to use dividers to distinguish the primary touch target from
+ the secondary action. This is done using android:showDividers and its
+ related attributes.
+
+ The android:dividerPadding attribute insets the divider line by the given
+ amount on each side (in this case, top and bottom). Divider padding helps
+ establish visual hierarchy when several dividers are used in a screen. In
+ this case, the padding helps separate this vertical divider from horizontal
+ list item separators in the main ListView, and establishes a stronger
+ relationship between the delete action and the primary target to its left.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:listPreferredItemHeight"
+ android:divider="?android:dividerVertical"
+ android:dividerPadding="8dp"
+ android:showDividers="middle">
+
+ <!--
+ Any view or view group can become interactive by simply setting the
+ android:clickable and android:focusable attributes to true.
+
+ When doing this, make sure to provide adequate touch feedback by also
+ setting the view background to ?android:selectableItemBackground. When
+ using the Holo theme, this drawable is transparent by default, but
+ changes to a translucent color overlay when the view is pressed or
+ focused.
+ -->
+ <LinearLayout android:id="@+id/primary_target"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:paddingLeft="?android:listPreferredItemPaddingLeft"
+ android:paddingRight="?android:listPreferredItemPaddingRight"
+ android:clickable="true"
+ android:focusable="true"
+ android:gravity="center_vertical"
+ android:background="?android:selectableItemBackground">
+
+ <TextView style="?android:textAppearanceListItemSmall"
+ android:id="@android:id/text1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dummy_title" />
+
+ <TextView style="?android:textAppearanceSmall"
+ android:id="@android:id/text2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dummy_subtitle" />
+
+ </LinearLayout>
+
+ <!--
+ When using the Holo theme, setting a Button or ImageButton to
+ ?android:borderlessButtonStyle removes its border and sets the
+ background to ?android:selectableItemBackground, as described above.
+ -->
+ <ImageButton android:id="@+id/secondary_action"
+ style="?android:borderlessButtonStyle"
+ android:layout_width="@dimen/standard_touch_target_size"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_action_delete"
+ android:contentDescription="@string/delete_content_description" />
+
+</LinearLayout>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/sample_main.xml
new file mode 100755
index 0000000..eacbf4b
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,87 @@
+<!--
+ Copyright 2013 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 top-level LinearLayout uses a horizontal divider to visually
+ distinguish the top description box, list, and bottom button bar.
+
+ android:showDividers="middle" draws dividers between each child view and
+ android:divider="?android:dividerHorizontal" indicates that the standard
+ horizontal system divider (set in the activity's theme) should be used to
+ draw the divider.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:divider="?android:dividerHorizontal"
+ android:showDividers="middle">
+
+ <TextView style="@style/Widget.DescriptionBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_message" />
+
+ <!--
+ Remember to use padding on your ListViews to adhere to the standard
+ metrics described in the Android Design guidelines. When doing so,
+ you should set the android:scrollbarStyle such that the scrollbar
+ doesn'isn't inset.
+ -->
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/page_margin"
+ android:paddingRight="@dimen/page_margin"
+ android:scrollbarStyle="outsideOverlay" />
+
+ <!--
+ When using the Holo theme (setting your activity or app theme to
+ Theme.Holo or one of its descendants), a LinearLayout with the
+ ?android:buttonBarStyle will draw dividers (with padding) between
+ buttons.
+ -->
+ <LinearLayout style="?android:buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <!--
+ Make sure to apply the ?android:buttonBarStyle to each button
+ in the button bar.
+
+ In the Holo theme, this style is very similar to
+ ?android:borderlessButtonStyle, but designed for use specifically
+ in horizontal button bars.
+ -->
+ <Button style="?android:buttonBarButtonStyle"
+ android:id="@+id/cancel_button"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/cancel" />
+
+ <Button style="?android:buttonBarButtonStyle"
+ android:id="@+id/ok_button"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/ok" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/menu/main.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..54f0d3f
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/menu/main.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/docs_link"
+ android:title="@string/docs_link_title"
+ android:showAsAction="never" />
+</menu>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..efbd14d
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">BorderlessButtons</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates the use of borderless buttons, bottom button bars
+ (OK and Cancel) and dividers to establish visual structure.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/dimens.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..71a1fc7
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/dimens.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <dimen name="standard_touch_target_size">48dp</dimen>
+
+ <!-- Meta-dimension that switches on screen size -->
+
+ <dimen name="page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/strings.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..fb141d2
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/strings.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <string name="cancel">Cancel</string>
+ <string name="ok">OK</string>
+
+ <string name="dummy_title">Dummy title</string>
+ <string name="dummy_subtitle">Dummy subtitle</string>
+
+ <string name="delete_content_description">Delete</string>
+
+ <string name="touched_primary_message">Touched primary list item target.</string>
+ <string name="touched_secondary_message">Touched secondary list item target (delete).</string>
+
+ <string name="docs_link_title">Design docs: borderless buttons</string>
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/styles.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..36e0445
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/styles.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Widget styling -->
+
+ <style name="Widget.DescriptionBar">
+ <item name="android:background">#fb3</item>
+ <item name="android:paddingTop">@dimen/margin_medium</item>
+ <item name="android:paddingBottom">@dimen/margin_medium</item>
+ <item name="android:paddingLeft">@dimen/page_margin</item>
+ <item name="android:paddingRight">@dimen/page_margin</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/BorderlessButtonsSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/BorderlessButtons/README.txt b/prebuilts/gradle/BorderlessButtons/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/BorderlessButtons/build.gradle b/prebuilts/gradle/BorderlessButtons/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/BorderlessButtons/gradlew b/prebuilts/gradle/BorderlessButtons/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/BorderlessButtons/gradlew.bat b/prebuilts/gradle/BorderlessButtons/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/BorderlessButtons/settings.gradle b/prebuilts/gradle/BorderlessButtons/settings.gradle
new file mode 100644
index 0000000..f5220c4
--- /dev/null
+++ b/prebuilts/gradle/BorderlessButtons/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'BorderlessButtonsSample'
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/build.gradle b/prebuilts/gradle/CardEmulation/CardEmulationSample/build.gradle
new file mode 100644
index 0000000..f73b206
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 19
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/AndroidManifest.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4a4af08
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.cardemulation"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- Card emulation was introduced in API 19. -->
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+ <uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
+ <uses-permission android:name="android.permission.NFC" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <!-- Basic UI for sample discoverability. -->
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- BEGIN_INCLUDE(CardEmulationManifest) -->
+ <!-- Service for handling communication with NFC terminal. -->
+ <service android:name=".CardService"
+ android:exported="true"
+ android:permission="android.permission.BIND_NFC_SERVICE">
+ <!-- Intent filter indicating that we support card emulation. -->
+ <intent-filter>
+ <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ <!-- Required XML configuration file, listing the AIDs that we are emulating cards
+ for. This defines what protocols our card emulation service supports. -->
+ <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
+ android:resource="@xml/aid_list"/>
+ </service>
+ <!-- END_INCLUDE(CardEmulationManifest) -->
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/AccountStorage.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/AccountStorage.java
new file mode 100644
index 0000000..e02d480
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/AccountStorage.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 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.cardemulation;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+/**
+ * Utility class for persisting account numbers to disk.
+ *
+ * <p>The default SharedPreferences instance is used as the backing storage. Values are cached
+ * in memory for performance.
+ *
+ * <p>This class is thread-safe.
+ */
+public class AccountStorage {
+ private static final String PREF_ACCOUNT_NUMBER = "account_number";
+ private static final String DEFAULT_ACCOUNT_NUMBER = "00000000";
+ private static final String TAG = "AccountStorage";
+ private static String sAccount = null;
+ private static final Object sAccountLock = new Object();
+
+ public static void SetAccount(Context c, String s) {
+ synchronized(sAccountLock) {
+ Log.i(TAG, "Setting account number: " + s);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
+ prefs.edit().putString(PREF_ACCOUNT_NUMBER, s).commit();
+ sAccount = s;
+ }
+ }
+
+ public static String GetAccount(Context c) {
+ synchronized (sAccountLock) {
+ if (sAccount == null) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
+ String account = prefs.getString(PREF_ACCOUNT_NUMBER, DEFAULT_ACCOUNT_NUMBER);
+ sAccount = account;
+ }
+ return sAccount;
+ }
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardEmulationFragment.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardEmulationFragment.java
new file mode 100644
index 0000000..f26efda
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardEmulationFragment.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 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.cardemulation;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+/**
+ * Generic UI for sample discovery.
+ */
+public class CardEmulationFragment extends Fragment {
+
+ public static final String TAG = "CardEmulationFragment";
+
+ /** Called when sample is created. Displays generic UI with welcome text. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View v = inflater.inflate(R.layout.main_fragment, container, false);
+ EditText account = (EditText) v.findViewById(R.id.card_account_field);
+ account.setText(AccountStorage.GetAccount(getActivity()));
+ account.addTextChangedListener(new AccountUpdater());
+ return v;
+ }
+
+
+ private class AccountUpdater implements TextWatcher {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // Not implemented.
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // Not implemented.
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ String account = s.toString();
+ AccountStorage.SetAccount(getActivity(), account);
+ }
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardService.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardService.java
new file mode 100644
index 0000000..a409d28
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/CardService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 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.cardemulation;
+
+import android.nfc.cardemulation.HostApduService;
+import android.os.Bundle;
+import com.example.android.common.logger.Log;
+
+import java.util.Arrays;
+
+/**
+ * This is a sample APDU Service which demonstrates how to interface with the card emulation support
+ * added in Android 4.4, KitKat.
+ *
+ * <p>This sample replies to any requests sent with the string "Hello World". In real-world
+ * situations, you would need to modify this code to implement your desired communication
+ * protocol.
+ *
+ * <p>This sample will be invoked for any terminals selecting AIDs of 0xF11111111, 0xF22222222, or
+ * 0xF33333333. See src/main/res/xml/aid_list.xml for more details.
+ *
+ * <p class="note">Note: This is a low-level interface. Unlike the NdefMessage many developers
+ * are familiar with for implementing Android Beam in apps, card emulation only provides a
+ * byte-array based communication channel. It is left to developers to implement higher level
+ * protocol support as needed.
+ */
+public class CardService extends HostApduService {
+ private static final String TAG = "CardService";
+ // AID for our loyalty card service.
+ private static final String SAMPLE_LOYALTY_CARD_AID = "F222222222";
+ // ISO-DEP command HEADER for selecting an AID.
+ // Format: [Class | Instruction | Parameter 1 | Parameter 2]
+ private static final String SELECT_APDU_HEADER = "00A40400";
+ // "OK" status word sent in response to SELECT AID command (0x9000)
+ private static final byte[] SELECT_OK_SW = HexStringToByteArray("9000");
+ // "UNKNOWN" status word sent in response to invalid APDU command (0x0000)
+ private static final byte[] UNKNOWN_CMD_SW = HexStringToByteArray("0000");
+ private static final byte[] SELECT_APDU = BuildSelectApdu(SAMPLE_LOYALTY_CARD_AID);
+
+ /**
+ * Called if the connection to the NFC card is lost, in order to let the application know the
+ * cause for the disconnection (either a lost link, or another AID being selected by the
+ * reader).
+ *
+ * @param reason Either DEACTIVATION_LINK_LOSS or DEACTIVATION_DESELECTED
+ */
+ @Override
+ public void onDeactivated(int reason) { }
+
+ /**
+ * This method will be called when a command APDU has been received from a remote device. A
+ * response APDU can be provided directly by returning a byte-array in this method. In general
+ * response APDUs must be sent as quickly as possible, given the fact that the user is likely
+ * holding his device over an NFC reader when this method is called.
+ *
+ * <p class="note">If there are multiple services that have registered for the same AIDs in
+ * their meta-data entry, you will only get called if the user has explicitly selected your
+ * service, either as a default or just for the next tap.
+ *
+ * <p class="note">This method is running on the main thread of your application. If you
+ * cannot return a response APDU immediately, return null and use the {@link
+ * #sendResponseApdu(byte[])} method later.
+ *
+ * @param commandApdu The APDU that received from the remote device
+ * @param extras A bundle containing extra data. May be null.
+ * @return a byte-array containing the response APDU, or null if no response APDU can be sent
+ * at this point.
+ */
+ // BEGIN_INCLUDE(processCommandApdu)
+ @Override
+ public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
+ Log.i(TAG, "Received APDU: " + ByteArrayToHexString(commandApdu));
+ // If the APDU matches the SELECT AID command for this service,
+ // send the loyalty card account number, followed by a SELECT_OK status trailer (0x9000).
+ if (Arrays.equals(SELECT_APDU, commandApdu)) {
+ String account = AccountStorage.GetAccount(this);
+ byte[] accountBytes = account.getBytes();
+ Log.i(TAG, "Sending account number: " + account);
+ return ConcatArrays(accountBytes, SELECT_OK_SW);
+ } else {
+ return UNKNOWN_CMD_SW;
+ }
+ }
+ // END_INCLUDE(processCommandApdu)
+
+ /**
+ * Build APDU for SELECT AID command. This command indicates which service a reader is
+ * interested in communicating with. See ISO 7816-4.
+ *
+ * @param aid Application ID (AID) to select
+ * @return APDU for SELECT AID command
+ */
+ public static byte[] BuildSelectApdu(String aid) {
+ // Format: [CLASS | INSTRUCTION | PARAMETER 1 | PARAMETER 2 | LENGTH | DATA]
+ return HexStringToByteArray(SELECT_APDU_HEADER + String.format("%02X",
+ aid.length() / 2) + aid);
+ }
+
+ /**
+ * Utility method to convert a byte array to a hexadecimal string.
+ *
+ * @param bytes Bytes to convert
+ * @return String, containing hexadecimal representation.
+ */
+ public static String ByteArrayToHexString(byte[] bytes) {
+ final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ char[] hexChars = new char[bytes.length * 2]; // Each byte has two hex characters (nibbles)
+ int v;
+ for (int j = 0; j < bytes.length; j++) {
+ v = bytes[j] & 0xFF; // Cast bytes[j] to int, treating as unsigned value
+ hexChars[j * 2] = hexArray[v >>> 4]; // Select hex character from upper nibble
+ hexChars[j * 2 + 1] = hexArray[v & 0x0F]; // Select hex character from lower nibble
+ }
+ return new String(hexChars);
+ }
+
+ /**
+ * Utility method to convert a hexadecimal string to a byte string.
+ *
+ * <p>Behavior with input strings containing non-hexadecimal characters is undefined.
+ *
+ * @param s String containing hexadecimal characters to convert
+ * @return Byte array generated from input
+ * @throws java.lang.IllegalArgumentException if input length is incorrect
+ */
+ public static byte[] HexStringToByteArray(String s) throws IllegalArgumentException {
+ int len = s.length();
+ if (len % 2 == 1) {
+ throw new IllegalArgumentException("Hex string must have even number of characters");
+ }
+ byte[] data = new byte[len / 2]; // Allocate 1 byte per 2 hex characters
+ for (int i = 0; i < len; i += 2) {
+ // Convert each character into a integer (base-16), then bit-shift into place
+ data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ + Character.digit(s.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+ /**
+ * Utility method to concatenate two byte arrays.
+ * @param first First array
+ * @param rest Any remaining arrays
+ * @return Concatenated copy of input arrays
+ */
+ public static byte[] ConcatArrays(byte[] first, byte[]... rest) {
+ int totalLength = first.length;
+ for (byte[] array : rest) {
+ totalLength += array.length;
+ }
+ byte[] result = Arrays.copyOf(first, totalLength);
+ int offset = first.length;
+ for (byte[] array : rest) {
+ System.arraycopy(array, 0, result, offset, array.length);
+ offset += array.length;
+ }
+ return result;
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/MainActivity.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/MainActivity.java
new file mode 100644
index 0000000..0515609
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/cardemulation/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.cardemulation;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ CardEmulationFragment fragment = new CardEmulationFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..0be8f85
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..eb13405
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..8d1e6a6
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/card_background.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/card_background.png
new file mode 100644
index 0000000..86a7ba7
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/card_background.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..7ea109f
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/main_fragment.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/main_fragment.xml
new file mode 100644
index 0000000..2c69743
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/layout/main_fragment.xml
@@ -0,0 +1,65 @@
+<!--
+Copyright (C) 2013 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.
+-->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="380dp"
+ android:layout_height="242.25dp"
+ android:layout_gravity="center"
+ android:layout_margin="20dp">
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/card_background"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="20dp"
+ android:layout_gravity="center"
+ android:clickable="true">
+ <TextView
+ android:id="@+id/card_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/card_title"
+ android:fontFamily="sans-serif-condensed"
+ android:textStyle="bold"
+ android:textSize="32dp"
+ />
+ <TextView
+ android:id="@+id/card_account_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/account_number"
+ android:fontFamily="sans-serif"
+ android:textStyle="bold"
+ android:textSize="18dp"
+ android:layout_marginTop="40dp"
+ />
+ <EditText
+ android:id="@+id/card_account_field"
+ android:width="360dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:textStyle="bold"
+ android:textSize="42dp"
+ android:singleLine="true"
+ android:inputType="number" />
+ </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/menu/main.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..9062a23
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">CardEmulation</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to emulate an NFC card, using the "host card emulation"
+ feature added in Android 4.4. This sample makes the device appear as a loyalty card
+ whenever the screen is on and the user taps their device on an appropriately configured
+ NFC reader.
+
+ The "CardReader" sample can be used to read the loyalty card implemented in this sample.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/strings.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/xml/aid_list.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/xml/aid_list.xml
new file mode 100644
index 0000000..15ed754
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/src/main/res/xml/aid_list.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2013 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 file defines which AIDs this application should emulate cards for.
+
+ Vendor-specific AIDs should always start with an "F", according to the ISO 7816 spec. We
+ recommended vendor-specific AIDs be at least 6 characters long, to provide sufficient
+ uniqueness. Note, however, that longer AIDs may impose a burden on non-Android NFC terminals.
+ AIDs may not exceed 32 characters (16 bytes).
+
+ Additionally, AIDs must always contain an even number of characters, in hexadecimal format.
+
+ In order to avoid prompting the user to select which service they want to use when the device
+ is scanned, this app must be selected as the default handler for an AID group by the user, or
+ the terminal must select *all* AIDs defined in the category simultaneously ("exact match").
+-->
+<!-- BEGIN_INCLUDE(CardEmulationXML) -->
+<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
+ android:description="@string/service_name"
+ android:requireDeviceUnlock="false">
+ <!--
+ If category="payment" is used for any aid-groups, you must also add an android:apduServiceBanner
+ attribute above, like so:
+
+ android:apduServiceBanner="@drawable/settings_banner"
+
+ apduServiceBanner should be 260x96 dp. In pixels, that works out to...
+ - drawable-xxhdpi: 780x288 px
+ - drawable-xhdpi: 520x192 px
+ - drawable-hdpi: 390x144 px
+ - drawable-mdpi: 260x96 px
+
+ The apduServiceBanner is displayed in the "Tap & Pay" menu in the system Settings app, and
+ is only displayed for apps which implement the "payment" AID category.
+
+ Since this sample is implementing a non-standard card type (a loyalty card, specifically), we
+ do not need to define a banner.
+
+ Important: category="payment" should only be used for industry-standard payment cards. If you are
+ implementing a closed-loop payment system (e.g. stored value cards for a specific merchant
+ or transit system), use category="other". This is because only one "payment" card may be
+ active at a time, whereas all "other" cards are active simultaneously (subject to AID
+ dispatch).
+ -->
+
+ <aid-group android:description="@string/card_title" android:category="other">
+ <aid-filter android:name="F222222222"/>
+ </aid-group>
+<!-- END_INCLUDE(CardEmulationXML) -->
+</host-apdu-service>
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/AndroidManifest.xml b/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..447d041
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="${sample.package}.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.cardemulation"
+ android:label="Tests for com.example.android.cardemulation" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/src/com/example/android/cardemulation/tests/SampleTests.java b/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/src/com/example/android/cardemulation/tests/SampleTests.java
new file mode 100644
index 0000000..b9828c2
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/CardEmulationSample/tests/src/com/example/android/cardemulation/tests/SampleTests.java
@@ -0,0 +1,169 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+* Copyright (C) 2013 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.cardemulation.tests;
+
+import com.example.android.cardemulation.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for CardEmulation sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private CardEmulationFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (CardEmulationFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Test converting from a hex string to binary.
+ */
+ public void testHexToBinary() {
+ final byte[] testData = {(byte) 0xc0, (byte) 0xff, (byte) 0xee};
+ final byte[] output = CardService.HexStringToByteArray("C0FFEE");
+ for (int i = 0; i < testData.length; i++) {
+ assertEquals(testData[i], output[i]);
+ }
+ }
+
+ /**
+ * Test converting from binary to a hex string
+ */
+ public void testBinaryToHex() {
+ final byte[] input = {(byte) 0xc0, (byte) 0xff, (byte) 0xee};
+ final String output = CardService.ByteArrayToHexString(input);
+ assertEquals("C0FFEE", output);
+ }
+
+ /**
+ * Verify that account number is returned in response to APDU.
+ */
+ public void testRequestAccoutNumber() {
+ AccountStorage.SetAccount(this.getActivity(), "1234");
+ final byte[] command = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x05,
+ (byte) 0xF2, (byte) 0x22, (byte) 0x22, (byte) 0x22, (byte) 0x22};
+ final byte[] expectedResponse = {(byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34,
+ (byte) 0x90, (byte) 0x00};
+ final CardService cs = new CardService();
+ final byte[] output = cs.processCommandApdu(command, null);
+
+ assertEquals(expectedResponse.length, output.length);
+ for (int i = 0; i < expectedResponse.length; i++) {
+ assertEquals(expectedResponse[i], output[i]);
+ }
+
+ }
+
+
+ /**
+ * Verify that account number is returned in response to APDU.
+ */
+ public void testInvalidCommand() {
+ AccountStorage.SetAccount(this.getActivity(), "1234");
+ final byte[] command = {(byte) 0x01, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x05,
+ (byte) 0xF2, (byte) 0x22, (byte) 0x22, (byte) 0x22, (byte) 0x22};
+ final byte[] expectedResponse = {(byte) 0x00, (byte) 0x00};
+ final CardService cs = new CardService();
+ final byte[] output = cs.processCommandApdu(command, null);
+
+ assertEquals(expectedResponse.length, output.length);
+ for (int i = 0; i < expectedResponse.length; i++) {
+ assertEquals(expectedResponse[i], output[i]);
+ }
+ }
+
+ /**
+ * Test functionality fo ConcatArrays method.
+ */
+ public void testArrayConcat() {
+ final byte[] a = {(byte) 0x01, (byte) 0x02};
+ final byte[] b = {(byte) 0x03, (byte) 0x04};
+ final byte[] c = {(byte) 0x05, (byte) 0x06};
+ final byte[] expected = {(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, (byte) 0x05,
+ (byte) 0x06};
+ final byte[] result = CardService.ConcatArrays(a, b, c);
+
+ assertEquals(expected.length, result.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], result[i]);
+ }
+ }
+
+ /**
+ * Test setting and getting account number
+ */
+ public void testSetAccountNumber() {
+ final String account = "3456";
+ AccountStorage.SetAccount(getActivity(), account);
+ this.assertEquals(account, AccountStorage.GetAccount(getActivity()));
+ }
+
+ /**
+ * Test building SELECT APDU from AID string.
+ */
+ public void testBuildSelectApdu() {
+ final String aid = "1234";
+ final byte[] expectedResult = {(byte) 0x00, (byte) 0xA4, 04, (byte) 0x00, (byte) 0x02,
+ (byte) 0x12, (byte) 0x34};
+ final byte[] result = CardService.BuildSelectApdu(aid);
+
+ assertEquals(expectedResult.length, result.length);
+ for (int i = 0; i < expectedResult.length; i++) {
+ assertEquals(expectedResult[i], result[i]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/CardEmulation/README.txt b/prebuilts/gradle/CardEmulation/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/CardEmulation/build.gradle b/prebuilts/gradle/CardEmulation/build.gradle
new file mode 100644
index 0000000..12a6f48
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/build.gradle
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..56f685a
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/CardEmulation/gradlew b/prebuilts/gradle/CardEmulation/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/CardEmulation/gradlew.bat b/prebuilts/gradle/CardEmulation/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/CardEmulation/settings.gradle b/prebuilts/gradle/CardEmulation/settings.gradle
new file mode 100644
index 0000000..32b4942
--- /dev/null
+++ b/prebuilts/gradle/CardEmulation/settings.gradle
@@ -0,0 +1 @@
+include 'CardEmulationSample'
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/build.gradle b/prebuilts/gradle/CardReader/CardReaderSample/build.gradle
new file mode 100644
index 0000000..f73b206
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 19
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/AndroidManifest.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a8ebd13
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.cardreader"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- NFC Reader Mode was added in API 19. -->
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+ <uses-permission android:name="android.permission.NFC" />
+ <uses-feature android:name="android.hardware.nfc" android:required="true" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:launchMode="singleTop">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <!-- NFC-related intent filter. Allows application to handle messages from any
+ NFC-A devices discovered. Other Android devices are required to support NFC-A.
+ See: res/xml/nfc_tech_filter.xml -->
+ <intent-filter>
+ <action android:name="android.nfc.action.TECH_DISCOVERED" />
+ </intent-filter>
+ <meta-data
+ android:name="android.nfc.action.TECH_DISCOVERED"
+ android:resource="@xml/nfc_tech_filter" />
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/CardReaderFragment.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/CardReaderFragment.java
new file mode 100644
index 0000000..3f27e9b
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/CardReaderFragment.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 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.cardreader;
+
+import android.app.Activity;
+import android.nfc.NfcAdapter;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * Generic UI for sample discovery.
+ */
+public class CardReaderFragment extends Fragment implements LoyaltyCardReader.AccountCallback {
+
+ public static final String TAG = "CardReaderFragment";
+ // Recommend NfcAdapter flags for reading from other Android devices. Indicates that this
+ // activity is interested in NFC-A devices (including other Android devices), and that the
+ // system should not check for the presence of NDEF-formatted data (e.g. Android Beam).
+ public static int READER_FLAGS =
+ NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK;
+ public LoyaltyCardReader mLoyaltyCardReader;
+ private TextView mAccountField;
+
+ /** Called when sample is created. Displays generic UI with welcome text. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View v = inflater.inflate(R.layout.main_fragment, container, false);
+ if (v != null) {
+ mAccountField = (TextView) v.findViewById(R.id.card_account_field);
+ mAccountField.setText("Waiting...");
+
+ mLoyaltyCardReader = new LoyaltyCardReader(this);
+
+ // Disable Android Beam and register our card reader callback
+ enableReaderMode();
+ }
+
+ return v;
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ disableReaderMode();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ enableReaderMode();
+ }
+
+ private void enableReaderMode() {
+ Log.i(TAG, "Enabling reader mode");
+ Activity activity = getActivity();
+ NfcAdapter nfc = NfcAdapter.getDefaultAdapter(activity);
+ if (nfc != null) {
+ nfc.enableReaderMode(activity, mLoyaltyCardReader, READER_FLAGS, null);
+ }
+ }
+
+ private void disableReaderMode() {
+ Log.i(TAG, "Disabling reader mode");
+ Activity activity = getActivity();
+ NfcAdapter nfc = NfcAdapter.getDefaultAdapter(activity);
+ if (nfc != null) {
+ nfc.disableReaderMode(activity);
+ }
+ }
+
+ @Override
+ public void onAccountReceived(final String account) {
+ // This callback is run on a background thread, but updates to UI elements must be performed
+ // on the UI thread.
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mAccountField.setText(account);
+ }
+ });
+ }
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/LoyaltyCardReader.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/LoyaltyCardReader.java
new file mode 100644
index 0000000..c29bdfd
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/LoyaltyCardReader.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2013 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.cardreader;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.nfc.tech.IsoDep;
+
+import com.example.android.common.logger.Log;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+
+/**
+ * Callback class, invoked when an NFC card is scanned while the device is running in reader mode.
+ *
+ * Reader mode can be invoked by calling NfcAdapter
+ */
+public class LoyaltyCardReader implements NfcAdapter.ReaderCallback {
+ private static final String TAG = "LoyaltyCardReader";
+ // AID for our loyalty card service.
+ private static final String SAMPLE_LOYALTY_CARD_AID = "F222222222";
+ // ISO-DEP command HEADER for selecting an AID.
+ // Format: [Class | Instruction | Parameter 1 | Parameter 2]
+ private static final String SELECT_APDU_HEADER = "00A40400";
+ // "OK" status word sent in response to SELECT AID command (0x9000)
+ private static final byte[] SELECT_OK_SW = {(byte) 0x90, (byte) 0x00};
+
+ // Weak reference to prevent retain loop. mAccountCallback is responsible for exiting
+ // foreground mode before it becomes invalid (e.g. during onPause() or onStop()).
+ private WeakReference<AccountCallback> mAccountCallback;
+
+ public interface AccountCallback {
+ public void onAccountReceived(String account);
+ }
+
+ public LoyaltyCardReader(AccountCallback accountCallback) {
+ mAccountCallback = new WeakReference<AccountCallback>(accountCallback);
+ }
+
+ /**
+ * Callback when a new tag is discovered by the system.
+ *
+ * <p>Communication with the card should take place here.
+ *
+ * @param tag Discovered tag
+ */
+ @Override
+ public void onTagDiscovered(Tag tag) {
+ Log.i(TAG, "New tag discovered");
+ // Android's Host-based Card Emulation (HCE) feature implements the ISO-DEP (ISO 14443-4)
+ // protocol.
+ //
+ // In order to communicate with a device using HCE, the discovered tag should be processed
+ // using the IsoDep class.
+ IsoDep isoDep = IsoDep.get(tag);
+ if (isoDep != null) {
+ try {
+ // Connect to the remote NFC device
+ isoDep.connect();
+ // Build SELECT AID command for our loyalty card service.
+ // This command tells the remote device which service we wish to communicate with.
+ Log.i(TAG, "Requesting remote AID: " + SAMPLE_LOYALTY_CARD_AID);
+ byte[] command = BuildSelectApdu(SAMPLE_LOYALTY_CARD_AID);
+ // Send command to remote device
+ Log.i(TAG, "Sending: " + ByteArrayToHexString(command));
+ byte[] result = isoDep.transceive(command);
+ // If AID is successfully selected, 0x9000 is returned as the status word (last 2
+ // bytes of the result) by convention. Everything before the status word is
+ // optional payload, which is used here to hold the account number.
+ int resultLength = result.length;
+ byte[] statusWord = {result[resultLength-2], result[resultLength-1]};
+ byte[] payload = Arrays.copyOf(result, resultLength-2);
+ if (Arrays.equals(SELECT_OK_SW, statusWord)) {
+ // The remote NFC device will immediately respond with its stored account number
+ String accountNumber = new String(payload, "UTF-8");
+ Log.i(TAG, "Received: " + accountNumber);
+ // Inform CardReaderFragment of received account number
+ mAccountCallback.get().onAccountReceived(accountNumber);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Error communicating with card: " + e.toString());
+ }
+ }
+ }
+
+ /**
+ * Build APDU for SELECT AID command. This command indicates which service a reader is
+ * interested in communicating with. See ISO 7816-4.
+ *
+ * @param aid Application ID (AID) to select
+ * @return APDU for SELECT AID command
+ */
+ public static byte[] BuildSelectApdu(String aid) {
+ // Format: [CLASS | INSTRUCTION | PARAMETER 1 | PARAMETER 2 | LENGTH | DATA]
+ return HexStringToByteArray(SELECT_APDU_HEADER + String.format("%02X", aid.length() / 2) + aid);
+ }
+
+ /**
+ * Utility class to convert a byte array to a hexadecimal string.
+ *
+ * @param bytes Bytes to convert
+ * @return String, containing hexadecimal representation.
+ */
+ public static String ByteArrayToHexString(byte[] bytes) {
+ final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ char[] hexChars = new char[bytes.length * 2];
+ int v;
+ for ( int j = 0; j < bytes.length; j++ ) {
+ v = bytes[j] & 0xFF;
+ hexChars[j * 2] = hexArray[v >>> 4];
+ hexChars[j * 2 + 1] = hexArray[v & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
+ /**
+ * Utility class to convert a hexadecimal string to a byte string.
+ *
+ * <p>Behavior with input strings containing non-hexadecimal characters is undefined.
+ *
+ * @param s String containing hexadecimal characters to convert
+ * @return Byte array generated from input
+ */
+ public static byte[] HexStringToByteArray(String s) {
+ int len = s.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ + Character.digit(s.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/MainActivity.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/MainActivity.java
new file mode 100644
index 0000000..e0280e9
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/cardreader/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.cardreader;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ CardReaderFragment fragment = new CardReaderFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..9114e44
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..604fbd8
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..9e58d22
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/card_background.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/card_background.png
new file mode 100644
index 0000000..86a7ba7
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/card_background.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..c550c04
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/main_fragment.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/main_fragment.xml
new file mode 100644
index 0000000..1e3886c
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/layout/main_fragment.xml
@@ -0,0 +1,64 @@
+<!--
+Copyright (C) 2013 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.
+-->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="380dp"
+ android:layout_height="242.25dp"
+ android:layout_gravity="center"
+ android:layout_margin="20dp">
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/card_background"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="20dp"
+ android:layout_gravity="center"
+ android:clickable="true">
+ <TextView
+ android:id="@+id/card_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/card_title"
+ android:fontFamily="sans-serif-condensed"
+ android:textStyle="bold"
+ android:textSize="32dp"
+ />
+ <TextView
+ android:id="@+id/card_account_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/account_number"
+ android:fontFamily="sans-serif"
+ android:textStyle="bold"
+ android:textSize="18dp"
+ android:layout_marginTop="40dp"
+ />
+ <TextView
+ android:id="@+id/card_account_field"
+ android:width="360dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-condensed"
+ android:textStyle="bold"
+ android:textSize="42dp"
+ android:singleLine="true"
+ />
+ </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/menu/main.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..ac12480
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">CardReader</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to implement a low-level NFC card reader, for reading cards
+ that do not contain NDEF or Android Beam data. This sample is designed to read the virtual
+ loyalty card implemented in the "CardEmulation" sample.\n\n
+
+ In particular, this sample demonstrates how to disable Android Beam, select which AIDs the
+ reader is interested, and establish communication with the card
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/strings.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/xml/nfc_tech_filter.xml b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/xml/nfc_tech_filter.xml
new file mode 100644
index 0000000..dcfc979
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/src/main/res/xml/nfc_tech_filter.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This file is used as part of the filter for incoming NFC TECH_DISCOVERED intents. -->
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Android's host card emulation feature only supports the IsoDep protocol. -->
+ <tech-list>
+ <tech>android.nfc.tech.IsoDep</tech>
+ </tech-list>
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/tests/AndroidManifest.xml b/prebuilts/gradle/CardReader/CardReaderSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..1098859
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/tests/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.cardreader.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.cardreader"
+ android:label="Tests for com.example.android.cardreader" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/CardReader/CardReaderSample/tests/src/com/example/android/cardreader/tests/SampleTests.java b/prebuilts/gradle/CardReader/CardReaderSample/tests/src/com/example/android/cardreader/tests/SampleTests.java
new file mode 100644
index 0000000..d9d2cc5
--- /dev/null
+++ b/prebuilts/gradle/CardReader/CardReaderSample/tests/src/com/example/android/cardreader/tests/SampleTests.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.cardreader.tests;
+
+import com.example.android.cardreader.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for CardReader sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private CardReaderFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (CardReaderFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Test building SELECT APDU from AID string.
+ */
+ public void testBuildSelectApdu() {
+ final String aid = "1234";
+ final byte[] expectedResult = {(byte) 0x00, (byte) 0xA4, 04, (byte) 0x00, (byte) 0x02,
+ (byte) 0x12, (byte) 0x34};
+ final byte[] result = LoyaltyCardReader.BuildSelectApdu(aid);
+
+ assertEquals(expectedResult.length, result.length);
+ for (int i = 0; i < expectedResult.length; i++) {
+ assertEquals(expectedResult[i], result[i]);
+ }
+ }
+
+ /**
+ * Test converting from a hex string to binary.
+ */
+ public void testHexToBinary() {
+ final byte[] testData = {(byte) 0xc0, (byte) 0xff, (byte) 0xee};
+ final byte[] output = LoyaltyCardReader.HexStringToByteArray("C0FFEE");
+ for (int i = 0; i < testData.length; i++) {
+ assertEquals(testData[i], output[i]);
+ }
+ }
+
+ /**
+ * Test converting from binary to a hex string
+ */
+ public void testBinaryToHex() {
+ final byte[] input = {(byte) 0xc0, (byte) 0xff, (byte) 0xee};
+ final String output = LoyaltyCardReader.ByteArrayToHexString(input);
+ assertEquals("C0FFEE", output);
+ }
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/CardReader/README.txt b/prebuilts/gradle/CardReader/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/CardReader/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/CardReader/build.gradle b/prebuilts/gradle/CardReader/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/CardReader/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..1cfd865
--- /dev/null
+++ b/prebuilts/gradle/CardReader/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 02 15:37:05 PST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-all.zip
diff --git a/prebuilts/gradle/CardReader/gradlew b/prebuilts/gradle/CardReader/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/CardReader/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/CardReader/gradlew.bat b/prebuilts/gradle/CardReader/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/CardReader/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/CardReader/settings.gradle b/prebuilts/gradle/CardReader/settings.gradle
new file mode 100644
index 0000000..d1d7333
--- /dev/null
+++ b/prebuilts/gradle/CardReader/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'CardReaderSample'
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/build.gradle b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/build.gradle
new file mode 100644
index 0000000..1d9eedf
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 3
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/AndroidManifest.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8c194f5
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.customchoicelist"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="17" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.Sample"
+ android:allowBackup="true">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/CheckableLinearLayout.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/CheckableLinearLayout.java
new file mode 100644
index 0000000..a30eb2a
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/CheckableLinearLayout.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2013 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.customchoicelist;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.Checkable;
+import android.widget.LinearLayout;
+
+/**
+ * This is a simple wrapper for {@link android.widget.LinearLayout} that implements the {@link android.widget.Checkable}
+ * interface by keeping an internal 'checked' state flag.
+ * <p>
+ * This can be used as the root view for a custom list item layout for
+ * {@link android.widget.AbsListView} elements with a
+ * {@link android.widget.AbsListView#setChoiceMode(int) choiceMode} set.
+ */
+public class CheckableLinearLayout extends LinearLayout implements Checkable {
+ private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
+
+ private boolean mChecked = false;
+
+ public CheckableLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public boolean isChecked() {
+ return mChecked;
+ }
+
+ public void setChecked(boolean b) {
+ if (b != mChecked) {
+ mChecked = b;
+ refreshDrawableState();
+ }
+ }
+
+ public void toggle() {
+ setChecked(!mChecked);
+ }
+
+ @Override
+ public int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ if (isChecked()) {
+ mergeDrawableStates(drawableState, CHECKED_STATE_SET);
+ }
+ return drawableState;
+ }
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/Cheeses.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/Cheeses.java
new file mode 100644
index 0000000..871ae29
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/Cheeses.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2013 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.customchoicelist;
+
+/**
+ * Dummy data.
+ */
+public class Cheeses {
+ public static final String[] CHEESES = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+ "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+ "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+ "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+ "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+ "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+ "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+ "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+ "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+ "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+ "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+ "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+ "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+ "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+ "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+ "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+ "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+ "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+ "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+ "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+ "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+ "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+ "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+ "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+ "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+ "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+ "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+ "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+ "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+ "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+ "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+ "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+ "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+ "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+ "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+ "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+ "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+ "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+ "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+ "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+ "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+ "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+ "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+ "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+ "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+ "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+ "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+ "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+ "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+ "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+ "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+ "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+ "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+ "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+ "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+ "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+ "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+ "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+ "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+ "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+ "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+ "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+ "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+ "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+ "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+ "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+ "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+ "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+ "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+ "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+ "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+ "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+ "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+ "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+ "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+ "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+ "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+ "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+ "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+ "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+ "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+ "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+ "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+ "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+ "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+ "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+ "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+ "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+ "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+ "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+ "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+ "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+ "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+ "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+ "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+ "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+ "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+ "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+ "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+ "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+ "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+ "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+ "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+ "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+ "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+ "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+ "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+ "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+ "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+ "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+ "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+ "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+ "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+ "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+ "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+ "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+ "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+ "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+ "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+ "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+ "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+ "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+ "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+ "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+ "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+ "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+ "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+ "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+ "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+ "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"
+ };
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/MainActivity.java b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/MainActivity.java
new file mode 100755
index 0000000..e4e89f2
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/java/com/example/android/customchoicelist/MainActivity.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013 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.customchoicelist;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+/**
+ * This sample demonstrates how to create custom single- or multi-choice
+ * {@link android.widget.ListView} UIs. The most interesting bits are in
+ * the <code>res/layout/</code> directory of this sample.
+ */
+public class MainActivity extends ListActivity {
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+ setListAdapter(new MyAdapter());
+ }
+
+ /**
+ * A simple array adapter that creates a list of cheeses.
+ */
+ private class MyAdapter extends BaseAdapter {
+ @Override
+ public int getCount() {
+ return Cheeses.CHEESES.length;
+ }
+
+ @Override
+ public String getItem(int position) {
+ return Cheeses.CHEESES[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return Cheeses.CHEESES[position].hashCode();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(R.layout.list_item, container, false);
+ }
+
+ ((TextView) convertView.findViewById(android.R.id.text1))
+ .setText(getItem(position));
+ return convertView;
+ }
+ }
+}
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/color/hideable_text_color.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/color/hideable_text_color.xml
new file mode 100644
index 0000000..c48bb38
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/color/hideable_text_color.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 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 color state list changes from gray to blue depending on its state (checked or not checked).
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_checked="false" android:color="#6000" />
+ <item android:color="#09c" />
+</selector>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..230b1c3
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..dc56d26
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_checked.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_checked.png
new file mode 100644
index 0000000..9346d8a
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_checked.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_unchecked.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_unchecked.png
new file mode 100644
index 0000000..d45b374
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_hideable_item_unchecked.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..a71e6ca
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..051f1e3
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable/ic_hideable_item.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable/ic_hideable_item.xml
new file mode 100644
index 0000000..bc5ea54
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/drawable/ic_hideable_item.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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 state list drawable changes from an outline of an eye (ic_hideable_item_unchecked) to a
+ blue eye with iris (ic_hideable_item_checked) depending on its state (checked or not checked).
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_checked="false" android:drawable="@drawable/ic_hideable_item_unchecked" />
+ <item android:drawable="@drawable/ic_hideable_item_checked" />
+</selector>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/list_item.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/list_item.xml
new file mode 100644
index 0000000..09a17ed
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/list_item.xml
@@ -0,0 +1,62 @@
+<!--
+ Copyright 2013 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 ListView from sample_main.xml has a choiceMode set, meaning that when a user
+ selects a list item, the ListView will set the state for that item's root view
+ (this CheckableLinearLayout) to "checked". Note that this requires that the root view
+ implements the Checkable interface. Once the root view is checked, any children that
+ have the duplicateParentState attribute set will inherit this "checked" state.
+-->
+<com.example.android.customchoicelist.CheckableLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="8dp"
+ android:paddingRight="8dp"
+ android:minHeight="?android:listPreferredItemHeight"
+ android:gravity="center_vertical">
+
+ <!--
+ The duplicateParentState attribute on this TextView, along with the color state list
+ used in the textColor attribute causes its text color to change when its parent
+ is checked or unchecked.
+ -->
+ <TextView android:id="@android:id/text1"
+ android:duplicateParentState="true"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:textAppearanceMedium"
+ android:textColor="@color/hideable_text_color" />
+
+ <!--
+ The duplicateParentState attribute on this ImageView, along with the state list
+ drawable in the src attribute causes its image to change when its parent
+ is checked or unchecked.
+
+ To use the standard radio or checkmark image, set the src to
+ ?android:listChoiceIndicatorMultiple or ?android:listChoiceIndicatorSingle. These
+ are system theme attributes that reference a state list drawable.
+ -->
+ <ImageView android:src="@drawable/ic_hideable_item"
+ android:duplicateParentState="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="16dp" />
+
+</com.example.android.customchoicelist.CheckableLinearLayout>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/sample_main.xml
new file mode 100755
index 0000000..17a69e4
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,54 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:showDividers="middle"
+ android:divider="?android:dividerHorizontal">
+
+ <TextView style="@style/Widget.DescriptionBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_message" />
+
+ <!--
+ When a ListView has a choiceMode set, it will allow users to "choose"
+ one or more items. The framework provides default list item layouts
+ that show standard radio buttons or check boxes next to a
+ single line of text:
+
+ android.R.layout.simple_list_item_single_choice and
+ android.R.layout.simple_list_item_multiple_choice.
+
+ In some cases, you may want to customize this layout. When doing so,
+ the root view must implement the Checkable interface.
+
+ Lastly, remember to use padding on your ListViews to adhere to the standard
+ metrics described in the Android Design guidelines. When doing so,
+ you should set the android:scrollbarStyle such that the scrollbar
+ doesn'isn't inset.
+ -->
+ <ListView android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/page_margin"
+ android:paddingRight="@dimen/page_margin"
+ android:scrollbarStyle="outsideOverlay"
+ android:choiceMode="multipleChoice" />
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..e2890c4
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">CustomChoiceList</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to create custom checkable layouts, for use with ListView\'s choiceMode
+ attribute.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/dimens.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..c22027e
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Meta-dimension that switches on screen size -->
+
+ <dimen name="page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/styles.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..0851a81
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/styles.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <style name="Widget.DescriptionBar">
+ <item name="android:background">#fb3</item>
+ <item name="android:paddingTop">@dimen/margin_medium</item>
+ <item name="android:paddingBottom">@dimen/margin_medium</item>
+ <item name="android:paddingLeft">@dimen/page_margin</item>
+ <item name="android:paddingRight">@dimen/page_margin</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/CustomChoiceListSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomChoiceList/README.txt b/prebuilts/gradle/CustomChoiceList/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/CustomChoiceList/build.gradle b/prebuilts/gradle/CustomChoiceList/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/CustomChoiceList/gradlew b/prebuilts/gradle/CustomChoiceList/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/CustomChoiceList/gradlew.bat b/prebuilts/gradle/CustomChoiceList/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/CustomChoiceList/settings.gradle b/prebuilts/gradle/CustomChoiceList/settings.gradle
new file mode 100644
index 0000000..6d876cf
--- /dev/null
+++ b/prebuilts/gradle/CustomChoiceList/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'CustomChoiceListSample'
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/build.gradle b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/AndroidManifest.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b20a411
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.customnotifications"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="4"
+ android:targetSdkVersion="18" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name="com.example.android.customnotifications.MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/java/com/example/android/customnotifications/MainActivity.java b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/java/com/example/android/customnotifications/MainActivity.java
new file mode 100644
index 0000000..57a4315
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/java/com/example/android/customnotifications/MainActivity.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2013 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.customnotifications;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+public class MainActivity extends Activity {
+ /**
+ * This sample demonstrates notifications with custom content views.
+ *
+ * <p>On API level 16 and above a big content view is also defined that is used for the
+ * 'expanded' notification. The notification is created by the NotificationCompat.Builder.
+ * The expanded content view is set directly on the {@link android.app.Notification} once it has been build.
+ * (See {@link android.app.Notification#bigContentView}.) </p>
+ *
+ * <p>The content views are inflated as {@link android.widget.RemoteViews} directly from their XML layout
+ * definitions using {@link android.widget.RemoteViews#RemoteViews(String, int)}.</p>
+ */
+ private void createNotification() {
+ // BEGIN_INCLUDE(notificationCompat)
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+ // END_INCLUDE(notificationCompat)
+
+ // BEGIN_INCLUDE(intent)
+ //Create Intent to launch this Activity again if the notification is clicked.
+ Intent i = new Intent(this, MainActivity.class);
+ i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ PendingIntent intent = PendingIntent.getActivity(this, 0, i,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ builder.setContentIntent(intent);
+ // END_INCLUDE(intent)
+
+ // BEGIN_INCLUDE(ticker)
+ // Sets the ticker text
+ builder.setTicker(getResources().getString(R.string.custom_notification));
+
+ // Sets the small icon for the ticker
+ builder.setSmallIcon(R.drawable.ic_stat_custom);
+ // END_INCLUDE(ticker)
+
+ // BEGIN_INCLUDE(buildNotification)
+ // Cancel the notification when clicked
+ builder.setAutoCancel(true);
+
+ // Build the notification
+ Notification notification = builder.build();
+ // END_INCLUDE(buildNotification)
+
+ // BEGIN_INCLUDE(customLayout)
+ // Inflate the notification layout as RemoteViews
+ RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
+
+ // Set text on a TextView in the RemoteViews programmatically.
+ final String time = DateFormat.getTimeInstance().format(new Date()).toString();
+ final String text = getResources().getString(R.string.collapsed, time);
+ contentView.setTextViewText(R.id.textView, text);
+
+ /* Workaround: Need to set the content view here directly on the notification.
+ * NotificationCompatBuilder contains a bug that prevents this from working on platform
+ * versions HoneyComb.
+ * See https://code.google.com/p/android/issues/detail?id=30495
+ */
+ notification.contentView = contentView;
+
+ // Add a big content view to the notification if supported.
+ // Support for expanded notifications was added in API level 16.
+ // (The normal contentView is shown when the notification is collapsed, when expanded the
+ // big content view set here is displayed.)
+ if (Build.VERSION.SDK_INT >= 16) {
+ // Inflate and set the layout for the expanded notification view
+ RemoteViews expandedView =
+ new RemoteViews(getPackageName(), R.layout.notification_expanded);
+ notification.bigContentView = expandedView;
+ }
+ // END_INCLUDE(customLayout)
+
+ // START_INCLUDE(notify)
+ // Use the NotificationManager to show the notification
+ NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ nm.notify(0, notification);
+ // END_INCLUDE(notify)
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+ }
+
+ /**
+ * Create and show a notification with a custom layout.
+ * This callback is defined through the 'onClick' attribute of the
+ * 'Show Notification' button in the XML layout.
+ *
+ * @param v
+ */
+ public void showNotificationClicked(View v) {
+ createNotification();
+ }
+}
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_custom.png
new file mode 100644
index 0000000..db182ce
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v11/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_custom.png
new file mode 100644
index 0000000..c35f570
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi-v9/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..155ac98
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_stat_custom.png
new file mode 100644
index 0000000..b0434fd
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_custom.png
new file mode 100644
index 0000000..50e1b32
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v11/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_custom.png
new file mode 100644
index 0000000..d4de32a
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-ldpi-v9/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_custom.png
new file mode 100644
index 0000000..a46f47f
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v11/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_custom.png
new file mode 100644
index 0000000..2896b63
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi-v9/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6e38dc6
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_stat_custom.png
new file mode 100644
index 0000000..304f7e9
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-mdpi/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_custom.png
new file mode 100644
index 0000000..52f7df8
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v11/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_custom.png
new file mode 100644
index 0000000..5d2617e
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi-v9/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..638fc67
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_custom.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_custom.png
new file mode 100644
index 0000000..79c30a8
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/ic_stat_custom.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot.png
new file mode 100644
index 0000000..e21ee75
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot_expanded.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot_expanded.png
new file mode 100644
index 0000000..f9469d4
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xhdpi/robot_expanded.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..9a9a60c
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification.xml
new file mode 100644
index 0000000..9d977d3
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+* Copyright (C) 2013 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.
+-->
+
+<!-- Layout for the collapsed notification. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center_horizontal">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/NotificationContent"
+ android:id="@+id/textView"
+ android:gravity="center" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/imageView"
+ android:src="@drawable/robot"
+ android:contentDescription="@string/collapsed_image" />
+
+
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification_expanded.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification_expanded.xml
new file mode 100644
index 0000000..9d5a784
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/notification_expanded.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+* Copyright (C) 2013 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.
+-->
+
+<!-- Layout for the expanded notification. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="right|top">
+
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@style/NotificationContent"
+ android:text="@string/expanded"
+ android:layout_gravity="center_vertical"
+ android:layout_alignParentTop="false"
+ android:layout_alignParentLeft="true"
+ android:layout_toLeftOf="@+id/imageView"
+ android:gravity="center"
+ android:layout_centerVertical="true" />
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/robot_expanded"
+ android:layout_gravity="right|top"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:id="@+id/imageView"
+ android:contentDescription="@string/expanded_image" />
+ </RelativeLayout>
+
+
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..d67477d
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,43 @@
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<!-- Layout for MainActivity.
+ Includes an introductory text and a button to show the notification. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:orientation="vertical"
+ tools:context=".MainActivity"
+ android:gravity="center_horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/intro_text" />
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/show_notification"
+ android:id="@+id/button"
+ android:onClick="showNotificationClicked" />
+
+</LinearLayout>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..901314a
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,20 @@
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-v9/styles.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-v9/styles.xml
new file mode 100644
index 0000000..85010a5
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values-v9/styles.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <style name="NotificationContent" parent="@android:style/TextAppearance.StatusBar.EventContent">
+ </style>
+
+</resources>
\ No newline at end of file
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..7ddbc2d
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">CustomNotifications</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates notifications with custom content views.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/dimens.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..ca1b9e6
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/dimens.xml
@@ -0,0 +1,20 @@
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/strings.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a766441
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/strings.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<resources>
+
+ <string name="expanded">I\'m the expanded notification.\nCollapse me!</string>
+ <string name="collapsed">I\'m the collapsed notification.\nCreated at: %s</string>
+ <string name="show_notification">Show Notification</string>
+ <string name="custom_notification">I\'m a custom notification.</string>
+
+ <string name="intro_text">This sample demonstrates how a notification is created using the
+ <b>NotificationCompatBuilder</b>
+ with a custom content view. The layout of the notification is defined as a
+ layout resource and inflated as a <b>RemoteViews</b> object.
+ \n\nOn API level 16 and above, a different layout is inflated and set as
+ the <i>big content view</i>, which is used when the notification is expanded.
+ \n\n<b>Use the button below to create the notification.
+ \n\nIf your device is running Jelly Bean or above, try expanding or collapsing
+ the notification to see the different layouts.</b>
+ </string>
+ <string name="collapsed_image">A single Android robot waving. Symbolises a collapsed
+ notification.
+ </string>
+ <string name="expanded_image">Two Androids on top of each other. Symbolises an expanded
+ notification.
+ </string>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/styles.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..1d3d45b
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/styles.xml
@@ -0,0 +1,22 @@
+<!--
+ * Copyright (C) 2013 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.
+ -->
+
+<resources>
+
+ <style name="NotificationContent" parent="@android:style/TextAppearance.Small">
+ <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/CustomNotificationsSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/CustomNotifications/README.txt b/prebuilts/gradle/CustomNotifications/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/CustomNotifications/build.gradle b/prebuilts/gradle/CustomNotifications/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/CustomNotifications/gradlew b/prebuilts/gradle/CustomNotifications/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/CustomNotifications/gradlew.bat b/prebuilts/gradle/CustomNotifications/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/CustomNotifications/settings.gradle b/prebuilts/gradle/CustomNotifications/settings.gradle
new file mode 100644
index 0000000..71d4992
--- /dev/null
+++ b/prebuilts/gradle/CustomNotifications/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'CustomNotificationsSample'
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/build.gradle b/prebuilts/gradle/DoneBar/DoneBarSample/build.gradle
new file mode 100644
index 0000000..506795f
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 14
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/AndroidManifest.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4731114
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.donebar"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />
+
+ <application android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.Sample"
+ android:allowBackup="true">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".DoneBarActivity"
+ android:parentActivityName=".MainActivity" />
+
+ <activity android:name=".DoneButtonActivity"
+ android:parentActivityName=".MainActivity" />
+
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneBarActivity.java b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneBarActivity.java
new file mode 100755
index 0000000..f2a2b00
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneBarActivity.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 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.donebar;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A sample activity demonstrating the "done bar" alternative action bar presentation. For a more
+ * detailed description see {@link R.string.done_bar_description}.
+ */
+public class DoneBarActivity extends Activity {
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // BEGIN_INCLUDE (inflate_set_custom_view)
+ // Inflate a "Done/Cancel" custom action bar view.
+ final LayoutInflater inflater = (LayoutInflater) getActionBar().getThemedContext()
+ .getSystemService(LAYOUT_INFLATER_SERVICE);
+ final View customActionBarView = inflater.inflate(
+ R.layout.actionbar_custom_view_done_cancel, null);
+ customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // "Done"
+ finish();
+ }
+ });
+ customActionBarView.findViewById(R.id.actionbar_cancel).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // "Cancel"
+ finish();
+ }
+ });
+
+ // Show the custom action bar view and hide the normal Home icon and title.
+ final ActionBar actionBar = getActionBar();
+ actionBar.setDisplayOptions(
+ ActionBar.DISPLAY_SHOW_CUSTOM,
+ ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME
+ | ActionBar.DISPLAY_SHOW_TITLE);
+ actionBar.setCustomView(customActionBarView,
+ new ActionBar.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ // END_INCLUDE (inflate_set_custom_view)
+
+ setContentView(R.layout.activity_done_bar);
+ }
+}
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneButtonActivity.java b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneButtonActivity.java
new file mode 100755
index 0000000..3b1e37d
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/DoneButtonActivity.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 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.donebar;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * A sample activity demonstrating the "done button" alternative action bar presentation. For a more
+ * detailed description see {@link R.string.done_button_description}.
+ */
+public class DoneButtonActivity extends Activity {
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // BEGIN_INCLUDE (inflate_set_custom_view)
+ // Inflate a "Done" custom action bar view to serve as the "Up" affordance.
+ final LayoutInflater inflater = (LayoutInflater) getActionBar().getThemedContext()
+ .getSystemService(LAYOUT_INFLATER_SERVICE);
+ final View customActionBarView = inflater.inflate(
+ R.layout.actionbar_custom_view_done, null);
+ customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // "Done"
+ finish();
+ }
+ });
+
+ // Show the custom action bar view and hide the normal Home icon and title.
+ final ActionBar actionBar = getActionBar();
+ actionBar.setDisplayOptions(
+ ActionBar.DISPLAY_SHOW_CUSTOM,
+ ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME
+ | ActionBar.DISPLAY_SHOW_TITLE);
+ actionBar.setCustomView(customActionBarView);
+ // END_INCLUDE (inflate_set_custom_view)
+
+ setContentView(R.layout.activity_done_button);
+ }
+
+ // BEGIN_INCLUDE (handle_cancel)
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.cancel, menu);
+ return true;
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.cancel:
+ // "Cancel"
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+ // END_INCLUDE (handle_cancel)
+}
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/MainActivity.java b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/MainActivity.java
new file mode 100644
index 0000000..8b1e8a4
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/java/com/example/android/donebar/MainActivity.java
@@ -0,0 +1,112 @@
+/*
+* Copyright 2013 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.donebar;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+/**
+ * A simple launcher activity offering access to the individual samples in this project.
+ */
+public class MainActivity extends Activity implements AdapterView.OnItemClickListener {
+ private Sample[] mSamples;
+ private GridView mGridView;
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // Prepare list of samples in this dashboard.
+ mSamples = new Sample[]{
+ new Sample(R.string.donebaractivity_title, R.string.donebaractivity_description,
+ DoneBarActivity.class),
+ new Sample(R.string.donebuttonactivity_title, R.string.donebuttonactivity_description,
+ DoneButtonActivity.class),
+ };
+
+ // Prepare the GridView
+ mGridView = (GridView) findViewById(android.R.id.list);
+ mGridView.setAdapter(new SampleAdapter());
+ mGridView.setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> container, View view, int position, long id) {
+ startActivity(mSamples[position].intent);
+ }
+
+ private class SampleAdapter extends BaseAdapter {
+ @Override
+ public int getCount() {
+ return mSamples.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mSamples[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return mSamples[position].hashCode();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup container) {
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(R.layout.sample_dashboard_item,
+ container, false);
+ }
+
+ ((TextView) convertView.findViewById(android.R.id.text1)).setText(
+ mSamples[position].titleResId);
+ ((TextView) convertView.findViewById(android.R.id.text2)).setText(
+ mSamples[position].descriptionResId);
+ return convertView;
+ }
+ }
+
+ private class Sample {
+ int titleResId;
+ int descriptionResId;
+ Intent intent;
+
+ private Sample(int titleResId, int descriptionResId, Intent intent) {
+ this.intent = intent;
+ this.titleResId = titleResId;
+ this.descriptionResId = descriptionResId;
+ }
+
+ private Sample(int titleResId, int descriptionResId,
+ Class<? extends Activity> activityClass) {
+ this(titleResId, descriptionResId,
+ new Intent(MainActivity.this, activityClass));
+ }
+ }
+}
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_cancel.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_cancel.png
new file mode 100644
index 0000000..cde36e1
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_done.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_done.png
new file mode 100644
index 0000000..58bf972
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_action_done.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_cancel.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_cancel.png
new file mode 100644
index 0000000..9f4c3d6
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_done.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_done.png
new file mode 100644
index 0000000..cf5fab3
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_action_done.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_cancel.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_cancel.png
new file mode 100644
index 0000000..ca7d159
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_cancel.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_done.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_done.png
new file mode 100644
index 0000000..b891571
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_action_done.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/sample_dashboard_item_background.9.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/sample_dashboard_item_background.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xhdpi/sample_dashboard_item_background.9.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done.xml
new file mode 100644
index 0000000..44c1d61
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:divider="?android:attr/dividerVertical"
+ android:showDividers="end"
+ android:dividerPadding="12dp">
+
+ <include layout="@layout/include_done_button" />
+</LinearLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done_cancel.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done_cancel.xml
new file mode 100644
index 0000000..5cecdf0
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/actionbar_custom_view_done_cancel.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:divider="?android:attr/dividerVertical"
+ android:showDividers="middle"
+ android:dividerPadding="12dp">
+
+ <include layout="@layout/include_cancel_button" />
+ <include layout="@layout/include_done_button" />
+</LinearLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_bar.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_bar.xml
new file mode 100755
index 0000000..0d0272d
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_bar.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout style="@style/Widget.SampleContentContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/donebaractivity_description" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_button.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_button.xml
new file mode 100755
index 0000000..7fc2274
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_done_button.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout style="@style/Widget.SampleContentContainer"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/donebuttonactivity_description" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..88cdb80
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,41 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+
+ <GridView android:id="@android:id/list"
+ style="@style/Widget.SampleDashboard.Grid"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:scrollbarStyle="outsideOverlay" />
+
+</LinearLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_sample_dashboard.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_sample_dashboard.xml
new file mode 100755
index 0000000..88cdb80
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/activity_sample_dashboard.xml
@@ -0,0 +1,41 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+
+ <GridView android:id="@android:id/list"
+ style="@style/Widget.SampleDashboard.Grid"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:scrollbarStyle="outsideOverlay" />
+
+</LinearLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_cancel_button.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_cancel_button.xml
new file mode 100644
index 0000000..bffffa6
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_cancel_button.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:actionButtonStyle"
+ android:id="@+id/actionbar_cancel"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1">
+
+ <TextView style="?android:actionBarTabTextStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:paddingRight="20dp"
+ android:drawableLeft="@drawable/ic_action_cancel"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:text="@string/cancel" />
+</FrameLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_done_button.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_done_button.xml
new file mode 100644
index 0000000..9207733
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/include_done_button.xml
@@ -0,0 +1,33 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="?android:actionButtonStyle"
+ android:id="@+id/actionbar_done"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1">
+
+ <TextView style="?android:actionBarTabTextStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:paddingRight="20dp"
+ android:drawableLeft="@drawable/ic_action_done"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical"
+ android:text="@string/done" />
+</FrameLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/sample_dashboard_item.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/sample_dashboard_item.xml
new file mode 100644
index 0000000..38987ee
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/layout/sample_dashboard_item.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/Widget.SampleDashboard.Item"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView android:id="@android:id/text1"
+ style="@style/Widget.SampleDashboard.Item.Title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView android:id="@android:id/text2"
+ style="@style/Widget.SampleDashboard.Item.Description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/menu/cancel.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/menu/cancel.xml
new file mode 100644
index 0000000..18e3eed
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/menu/cancel.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/cancel"
+ android:title="@string/cancel"
+ android:icon="@drawable/ic_action_cancel"
+ android:showAsAction="never" />
+</menu>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/activitycards-strings.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/activitycards-strings.xml
new file mode 100644
index 0000000..5c2557c
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/activitycards-strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+
+<resources>
+ <string name="donebaractivity_title">Done Bar</string>
+ <string name="donebaractivity_description">In this presentation, a done bar replaces the action bar entirely, providing
+ two direct actions to persist or dismiss changes. This is suitable for cases where no
+ additional view details or actions are needed in the action bar.</string>
+ <string name="donebuttonactivity_title">Done Button</string>
+ <string name="donebuttonactivity_description">In this presentation, a done button replaces the action bar\'s "Up" affordance
+ and app icon, while the cancel action is made available in the action overflow. This is
+ well-suited to scenarios where additional view details or
+ actions may be needed in the action bar.</string>
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..22a4fae
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">DoneBar</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates two alternative presentations of the
+ action bar that are well-suited for simple data entry scenarios.
+
+ In this presentation, a done bar replaces the action
+ bar entirely, providing two direct actions to persist or dismiss changes. This is
+ suitable for cases where no additional view details or actions are needed in the
+ action bar.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/strings.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..df66a95
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <!-- Done bar strings -->
+ <string name="done">Done</string>
+ <string name="cancel">Cancel</string>
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..cafe531
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,71 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleContentContainer">
+ <item name="android:paddingTop">@dimen/vertical_page_margin</item>
+ <item name="android:paddingBottom">@dimen/vertical_page_margin</item>
+ <item name="android:paddingLeft">@dimen/horizontal_page_margin</item>
+ <item name="android:paddingRight">@dimen/horizontal_page_margin</item>
+ </style>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleDashboard.Grid" parent="Widget">
+ <item name="android:stretchMode">columnWidth</item>
+ <item name="android:columnWidth">200dp</item>
+ <item name="android:numColumns">auto_fit</item>
+ <item name="android:drawSelectorOnTop">true</item>
+ <item name="android:horizontalSpacing">@dimen/margin_medium</item>
+ <item name="android:verticalSpacing">@dimen/margin_medium</item>
+ </style>
+
+ <style name="Widget.SampleDashboard.Item" parent="Widget">
+ <item name="android:background">@drawable/sample_dashboard_item_background</item>
+ <item name="android:paddingTop">@dimen/margin_small</item>
+ <item name="android:paddingLeft">@dimen/margin_medium</item>
+ <item name="android:paddingRight">@dimen/margin_medium</item>
+ <item name="android:paddingBottom">@dimen/margin_medium</item>
+ </style>
+
+ <style name="Widget.SampleDashboard.Item.Title" parent="Widget">
+ <item name="android:layout_marginBottom">@dimen/margin_tiny</item>
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:textColor">#09c</item>
+ <item name="android:textStyle">bold</item>
+ <item name="android:textSize">24sp</item>
+ </style>
+
+ <style name="Widget.SampleDashboard.Item.Description" parent="Widget">
+ <item name="android:textAppearance">?android:textAppearanceSmall</item>
+ <item name="android:fontFamily">sans-serif-light</item>
+ </style>
+</resources>
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/tests/AndroidManifest.xml b/prebuilts/gradle/DoneBar/DoneBarSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..40eb5e1
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.donebar.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.donebar"
+ android:label="Tests for com.example.android.donebar" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/DoneBar/DoneBarSample/tests/src/com/example/android/donebar/tests/SampleTests.java b/prebuilts/gradle/DoneBar/DoneBarSample/tests/src/com/example/android/donebar/tests/SampleTests.java
new file mode 100644
index 0000000..c019ef8
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/DoneBarSample/tests/src/com/example/android/donebar/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.donebar.tests;
+
+import com.example.android.donebar.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for DoneBar sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private DoneBarFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (DoneBarFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/DoneBar/README.txt b/prebuilts/gradle/DoneBar/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/DoneBar/build.gradle b/prebuilts/gradle/DoneBar/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/DoneBar/gradlew b/prebuilts/gradle/DoneBar/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/DoneBar/gradlew.bat b/prebuilts/gradle/DoneBar/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/DoneBar/settings.gradle b/prebuilts/gradle/DoneBar/settings.gradle
new file mode 100644
index 0000000..d060dc7
--- /dev/null
+++ b/prebuilts/gradle/DoneBar/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'DoneBarSample'
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/build.gradle b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/build.gradle
new file mode 100644
index 0000000..6bbb9ea
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 11
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/AndroidManifest.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..33b9e15
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.horizontalpaging"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <!-- While ViewPager will work on API 4 or above, tabs require an ActionBar. ActionBar is only
+ available in API 11 or above. -->
+ <uses-sdk
+ android:minSdkVersion="11"
+ android:targetSdkVersion="16" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <!-- This is a standard Activity invocation for MainActivity. -->
+ <activity
+ android:name="com.example.android.horizontalpaging.MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/java/com/example/android/horizontalpaging/MainActivity.java b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/java/com/example/android/horizontalpaging/MainActivity.java
new file mode 100644
index 0000000..fdd4495
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/java/com/example/android/horizontalpaging/MainActivity.java
@@ -0,0 +1,219 @@
+package com.example.android.horizontalpaging;
+
+import android.app.ActionBar;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.Locale;
+
+public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
+
+ /**
+ * The {@link android.support.v4.view.PagerAdapter} that will provide
+ * fragments for each of the sections. We use a
+ * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
+ * will keep every loaded fragment in memory. If this becomes too memory
+ * intensive, it may be best to switch to a
+ * {@link android.support.v4.app.FragmentStatePagerAdapter}.
+ */
+ SectionsPagerAdapter mSectionsPagerAdapter;
+
+ /**
+ * The {@link ViewPager} that will host the section contents.
+ */
+ ViewPager mViewPager;
+
+ /**
+ * Create the activity. Sets up an {@link android.app.ActionBar} with tabs, and then configures the
+ * {@link ViewPager} contained inside R.layout.activity_main.
+ *
+ * <p>A {@link SectionsPagerAdapter} will be instantiated to hold the different pages of
+ * fragments that are to be displayed. A
+ * {@link android.support.v4.view.ViewPager.SimpleOnPageChangeListener} will also be configured
+ * to receive callbacks when the user swipes between pages in the ViewPager.
+ *
+ * @param savedInstanceState
+ */
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Load the UI from res/layout/activity_main.xml
+ setContentView(R.layout.sample_main);
+
+ // Set up the action bar. The navigation mode is set to NAVIGATION_MODE_TABS, which will
+ // cause the ActionBar to render a set of tabs. Note that these tabs are *not* rendered
+ // by the ViewPager; additional logic is lower in this file to synchronize the ViewPager
+ // state with the tab state. (See mViewPager.setOnPageChangeListener() and onTabSelected().)
+ // BEGIN_INCLUDE (set_navigation_mode)
+ final ActionBar actionBar = getActionBar();
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
+ // END_INCLUDE (set_navigation_mode)
+
+ // BEGIN_INCLUDE (setup_view_pager)
+ // Create the adapter that will return a fragment for each of the three primary sections
+ // of the app.
+ mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
+
+ // Set up the ViewPager with the sections adapter.
+ mViewPager = (ViewPager) findViewById(R.id.pager);
+ mViewPager.setAdapter(mSectionsPagerAdapter);
+ // END_INCLUDE (setup_view_pager)
+
+ // When swiping between different sections, select the corresponding tab. We can also use
+ // ActionBar.Tab#select() to do this if we have a reference to the Tab.
+ // BEGIN_INCLUDE (page_change_listener)
+ mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ actionBar.setSelectedNavigationItem(position);
+ }
+ });
+ // END_INCLUDE (page_change_listener)
+
+ // BEGIN_INCLUDE (add_tabs)
+ // For each of the sections in the app, add a tab to the action bar.
+ for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
+ // Create a tab with text corresponding to the page title defined by the adapter. Also
+ // specify this Activity object, which implements the TabListener interface, as the
+ // callback (listener) for when this tab is selected.
+ actionBar.addTab(
+ actionBar.newTab()
+ .setText(mSectionsPagerAdapter.getPageTitle(i))
+ .setTabListener(this));
+ }
+ // END_INCLUDE (add_tabs)
+ }
+
+ /**
+ * Update {@link ViewPager} after a tab has been selected in the ActionBar.
+ *
+ * @param tab Tab that was selected.
+ * @param fragmentTransaction A {@link android.app.FragmentTransaction} for queuing fragment operations to
+ * execute once this method returns. This FragmentTransaction does
+ * not support being added to the back stack.
+ */
+ // BEGIN_INCLUDE (on_tab_selected)
+ @Override
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ // When the given tab is selected, tell the ViewPager to switch to the corresponding page.
+ mViewPager.setCurrentItem(tab.getPosition());
+ }
+ // END_INCLUDE (on_tab_selected)
+
+ /**
+ * Unused. Required for {@link android.app.ActionBar.TabListener}.
+ */
+ @Override
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ /**
+ * Unused. Required for {@link android.app.ActionBar.TabListener}.
+ */
+ @Override
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
+ }
+
+ // BEGIN_INCLUDE (fragment_pager_adapter)
+ /**
+ * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
+ * one of the sections/tabs/pages. This provides the data for the {@link ViewPager}.
+ */
+ public class SectionsPagerAdapter extends FragmentPagerAdapter {
+ // END_INCLUDE (fragment_pager_adapter)
+
+ public SectionsPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ // BEGIN_INCLUDE (fragment_pager_adapter_getitem)
+ /**
+ * Get fragment corresponding to a specific position. This will be used to populate the
+ * contents of the {@link ViewPager}.
+ *
+ * @param position Position to fetch fragment for.
+ * @return Fragment for specified position.
+ */
+ @Override
+ public Fragment getItem(int position) {
+ // getItem is called to instantiate the fragment for the given page.
+ // Return a DummySectionFragment (defined as a static inner class
+ // below) with the page number as its lone argument.
+ Fragment fragment = new DummySectionFragment();
+ Bundle args = new Bundle();
+ args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
+ fragment.setArguments(args);
+ return fragment;
+ }
+ // END_INCLUDE (fragment_pager_adapter_getitem)
+
+ // BEGIN_INCLUDE (fragment_pager_adapter_getcount)
+ /**
+ * Get number of pages the {@link ViewPager} should render.
+ *
+ * @return Number of fragments to be rendered as pages.
+ */
+ @Override
+ public int getCount() {
+ // Show 3 total pages.
+ return 3;
+ }
+ // END_INCLUDE (fragment_pager_adapter_getcount)
+
+ // BEGIN_INCLUDE (fragment_pager_adapter_getpagetitle)
+ /**
+ * Get title for each of the pages. This will be displayed on each of the tabs.
+ *
+ * @param position Page to fetch title for.
+ * @return Title for specified page.
+ */
+ @Override
+ public CharSequence getPageTitle(int position) {
+ Locale l = Locale.getDefault();
+ switch (position) {
+ case 0:
+ return getString(R.string.title_section1).toUpperCase(l);
+ case 1:
+ return getString(R.string.title_section2).toUpperCase(l);
+ case 2:
+ return getString(R.string.title_section3).toUpperCase(l);
+ }
+ return null;
+ }
+ // END_INCLUDE (fragment_pager_adapter_getpagetitle)
+ }
+
+ /**
+ * A dummy fragment representing a section of the app, but that simply displays dummy text.
+ * This would be replaced with your application's content.
+ */
+ public static class DummySectionFragment extends Fragment {
+ /**
+ * The fragment argument representing the section number for this
+ * fragment.
+ */
+ public static final String ARG_SECTION_NUMBER = "section_number";
+
+ public DummySectionFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
+ TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
+ dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
+ return rootView;
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..96a442e
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..359047d
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..71c6d76
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/fragment_main_dummy.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/fragment_main_dummy.xml
new file mode 100644
index 0000000..6197494
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/fragment_main_dummy.xml
@@ -0,0 +1,16 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity$DummySectionFragment">
+
+ <TextView
+ android:id="@+id/section_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</RelativeLayout>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..237372c
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,8 @@
+<!-- BEGIN_INCLUDE (view_pager_layout) -->
+<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/pager"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".MainActivity" />
+<!-- END_INCLUDE (view_pager_layout) -->
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..70484bc
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">HorizontalPaging</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to implement horizontal paging between fragments in
+ applications that use ActionBar, using a ViewPager widget.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/dimens.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..47c8224
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/strings.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f9b4212
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/strings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="action_settings">Settings</string>
+ <string name="title_section1">Section 1</string>
+ <string name="title_section2">Section 2</string>
+ <string name="title_section3">Section 3</string>
+
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/values-sw720dp-land/dimens.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..00059fc
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/src/main/res/values/values-sw720dp-land/dimens.xml
@@ -0,0 +1,5 @@
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/AndroidManifest.xml b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..3f35ede
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.horizontalpaging.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.horizontalpaging"
+ android:label="Tests for com.example.android.horizontalpaging" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/src/com/example/android/horizontalpaging/tests/SampleTests.java b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/src/com/example/android/horizontalpaging/tests/SampleTests.java
new file mode 100644
index 0000000..206eea9
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/HorizontalPagingSample/tests/src/com/example/android/horizontalpaging/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.horizontalpaging.tests;
+
+import com.example.android.horizontalpaging.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for HorizontalPaging sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private HorizontalPagingFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (HorizontalPagingFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/HorizontalPaging/README.txt b/prebuilts/gradle/HorizontalPaging/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/HorizontalPaging/build.gradle b/prebuilts/gradle/HorizontalPaging/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/HorizontalPaging/gradlew b/prebuilts/gradle/HorizontalPaging/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/HorizontalPaging/gradlew.bat b/prebuilts/gradle/HorizontalPaging/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/HorizontalPaging/settings.gradle b/prebuilts/gradle/HorizontalPaging/settings.gradle
new file mode 100644
index 0000000..f70f0f1
--- /dev/null
+++ b/prebuilts/gradle/HorizontalPaging/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'HorizontalPagingSample'
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/build.gradle b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/AndroidManifest.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..72a60ce
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.immersivemode"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/ImmersiveModeFragment.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/ImmersiveModeFragment.java
new file mode 100644
index 0000000..8a7255c
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/ImmersiveModeFragment.java
@@ -0,0 +1,103 @@
+/*
+* Copyright (C) 2012 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.immersivemode;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.MenuItem;
+import android.view.View;
+
+import com.example.android.common.logger.Log;
+
+public class ImmersiveModeFragment extends Fragment {
+
+ public static final String TAG = "ImmersiveModeFragment";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final View decorView = getActivity().getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int i) {
+ int height = decorView.getHeight();
+ Log.i(TAG, "Current height: " + height);
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ toggleHideyBar();
+ }
+ return true;
+ }
+
+ /**
+ * Detects and toggles immersive mode (also known as "hidey bar" mode).
+ */
+ public void toggleHideyBar() {
+
+ // BEGIN_INCLUDE (get_current_ui_flags)
+ // The UI options currently enabled are represented by a bitfield.
+ // getSystemUiVisibility() gives us that bitfield.
+ int uiOptions = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ int newUiOptions = uiOptions;
+ // END_INCLUDE (get_current_ui_flags)
+ // BEGIN_INCLUDE (toggle_ui_flags)
+ boolean isImmersiveModeEnabled =
+ ((uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == uiOptions);
+ if (isImmersiveModeEnabled) {
+ Log.i(TAG, "Turning immersive mode mode off. ");
+ } else {
+ Log.i(TAG, "Turning immersive mode mode on.");
+ }
+
+ // Navigation bar hiding: Backwards compatible to ICS.
+ if (Build.VERSION.SDK_INT >= 14) {
+ newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ }
+
+ // Status bar hiding: Backwards compatible to Jellybean
+ if (Build.VERSION.SDK_INT >= 16) {
+ newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
+ }
+
+ // Immersive mode: Backward compatible to KitKat.
+ // Note that this flag doesn't do anything by itself, it only augments the behavior
+ // of HIDE_NAVIGATION and FLAG_FULLSCREEN. For the purposes of this sample
+ // all three flags are being toggled together.
+ // Note that there are two immersive mode UI flags, one of which is referred to as "sticky".
+ // Sticky immersive mode differs in that it makes the navigation and status bars
+ // semi-transparent, and the UI flag does not get cleared when the user interacts with
+ // the screen.
+ if (Build.VERSION.SDK_INT >= 18) {
+ newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ }
+
+ getActivity().getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
+ //END_INCLUDE (set_ui_flags)
+ }
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/MainActivity.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/MainActivity.java
new file mode 100644
index 0000000..fd02112
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/java/com/example/android/immersivemode/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.immersivemode;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "ImmersiveModeFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ ImmersiveModeFragment fragment = new ImmersiveModeFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/menu/main.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..2092f63
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">ImmersiveMode</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ One of the features introduced in KitKat is "immersive mode". Immersive mode gives the
+ user the ability to show/hide the status bar and navigation bar with a swipe. To try,
+ click the "Toggle immersive mode" button, then try swiping the bar in and out!
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/strings.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8a1e9e1
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Toggle immersive mode!</string>
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/AndroidManifest.xml b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..b090189
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.immersivemode.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.immersivemode"
+ android:label="Tests for com.example.android.immersivemode" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/ImmersiveModeSampleTests.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/ImmersiveModeSampleTests.java
new file mode 100644
index 0000000..eb80375
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/ImmersiveModeSampleTests.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013 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.immersivemode.tests;
+
+import com.example.android.immersivemode.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+/**
+ * Tests for immersive mode sample.
+ */
+public class ImmersiveModeSampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private ImmersiveModeFragment mTestFragment;
+
+ public ImmersiveModeSampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (ImmersiveModeFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Verify that the UI flags actually changed when the toggle method is called.
+ */
+ @UiThreadTest
+ public void testFlagsChanged() {
+ int uiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ mTestFragment.toggleHideyBar();
+ int newUiFlags = getActivity().getWindow().getDecorView().getSystemUiVisibility();
+ assertTrue("UI Flags didn't toggle.", uiFlags != newUiFlags);
+ }
+
+ /**
+ * Verify that the view's height actually changed when the toggle method is called.
+ * This should result in a change in height for the DecorView.
+ */
+ public void testDecorHeightExpanded() {
+ // Grab the initial height of the DecorWindow.
+ int startingHeight = getActivity().getWindow().getDecorView().getHeight();
+
+ // In order to test that this worked: Need to toggle the immersive mode on the UI thread,
+ // wait a suitable amount of time (this test goes with 200 ms), then check to see if the
+ // height changed.
+ try {
+ Runnable testRunnable = (new Runnable() {
+ public void run() {
+ // Toggle immersive mode
+ mTestFragment.toggleHideyBar();
+ synchronized(this) {
+ // Notify any thread waiting on this runnable that it can continue
+ this.notify();
+ }
+ }
+ });
+ synchronized(testRunnable) {
+ // Since toggling immersive mode makes changes to the view heirarchy, it needs to run
+ // on the UI thread, or crashing will occur.
+ mTestActivity.runOnUiThread(testRunnable);
+ testRunnable.wait();
+
+ }
+ synchronized(this) {
+ //Wait about 200ms for the change to take place
+ wait(200L);
+ }
+ } catch (Throwable throwable) {
+ fail(throwable.getMessage());
+ }
+
+ int expandedHeight = getActivity().getWindow().getDecorView().getHeight();
+ assertTrue("Bars aren't hidden.", expandedHeight != startingHeight);
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/SampleTests.java b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/SampleTests.java
new file mode 100644
index 0000000..162b3bd
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/ImmersiveModeSample/tests/src/com/example/android/immersivemode/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.immersivemode.tests;
+
+import com.example.android.immersivemode.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for ImmersiveMode sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private ImmersiveModeFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (ImmersiveModeFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/ImmersiveMode/README.txt b/prebuilts/gradle/ImmersiveMode/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/ImmersiveMode/build.gradle b/prebuilts/gradle/ImmersiveMode/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/ImmersiveMode/gradlew b/prebuilts/gradle/ImmersiveMode/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/ImmersiveMode/gradlew.bat b/prebuilts/gradle/ImmersiveMode/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/ImmersiveMode/settings.gradle b/prebuilts/gradle/ImmersiveMode/settings.gradle
new file mode 100644
index 0000000..d13a7a1
--- /dev/null
+++ b/prebuilts/gradle/ImmersiveMode/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'ImmersiveModeSample'
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/build.gradle b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/build.gradle
new file mode 100644
index 0000000..506795f
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 14
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/AndroidManifest.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..32f88f6
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.mediarecorder"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="14"
+ android:targetSdkVersion="17" />
+
+ <!-- This app records A/V content from camera and stores it to disk -->
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.RECORD_VIDEO" />
+ <uses-permission android:name="android.permission.RECORD_AUDIO"/>
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-feature android:name="android.hardware.camera" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme">
+ <!-- Since this sample records video from camera preview, locking the orientation to
+ landscape. Landscape mode offers us more preview space with standard video aspect
+ ratios (width > height) -->
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="landscape">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/CameraHelper.java b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/CameraHelper.java
new file mode 100644
index 0000000..1fa8416
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/CameraHelper.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.annotation.TargetApi;
+import android.hardware.Camera;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Camera related utilities.
+ */
+public class CameraHelper {
+
+ public static final int MEDIA_TYPE_IMAGE = 1;
+ public static final int MEDIA_TYPE_VIDEO = 2;
+
+ /**
+ * Iterate over supported camera preview sizes to see which one best fits the
+ * dimensions of the given view while maintaining the aspect ratio. If none can,
+ * be lenient with the aspect ratio.
+ *
+ * @param sizes Supported camera preview sizes.
+ * @param w The width of the view.
+ * @param h The height of the view.
+ * @return Best match camera preview size to fit in the view.
+ */
+ public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
+ // Use a very small tolerance because we want an exact match.
+ final double ASPECT_TOLERANCE = 0.1;
+ double targetRatio = (double) w / h;
+ if (sizes == null)
+ return null;
+
+ Camera.Size optimalSize = null;
+
+ // Start with max value and refine as we iterate over available preview sizes. This is the
+ // minimum difference between view and camera height.
+ double minDiff = Double.MAX_VALUE;
+
+ // Target view height
+ int targetHeight = h;
+
+ // Try to find a preview size that matches aspect ratio and the target view size.
+ // Iterate over all available sizes and pick the largest size that can fit in the view and
+ // still maintain the aspect ratio.
+ for (Camera.Size size : sizes) {
+ double ratio = (double) size.width / size.height;
+ if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
+ continue;
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+
+ // Cannot find preview size that matches the aspect ratio, ignore the requirement
+ if (optimalSize == null) {
+ minDiff = Double.MAX_VALUE;
+ for (Camera.Size size : sizes) {
+ if (Math.abs(size.height - targetHeight) < minDiff) {
+ optimalSize = size;
+ minDiff = Math.abs(size.height - targetHeight);
+ }
+ }
+ }
+ return optimalSize;
+ }
+
+ /**
+ * @return the default camera on the device. Return null if there is no camera on the device.
+ */
+ public static Camera getDefaultCameraInstance() {
+ return Camera.open();
+ }
+
+
+ /**
+ * @return the default rear/back facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultBackFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
+ }
+
+ /**
+ * @return the default front facing camera on the device. Returns null if camera is not
+ * available.
+ */
+ public static Camera getDefaultFrontFacingCameraInstance() {
+ return getDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
+ }
+
+
+ /**
+ *
+ * @param position Physical position of the camera i.e Camera.CameraInfo.CAMERA_FACING_FRONT
+ * or Camera.CameraInfo.CAMERA_FACING_BACK.
+ * @return the default camera on the device. Returns null if camera is not available.
+ */
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ private static Camera getDefaultCamera(int position) {
+ // Find the total number of cameras available
+ int mNumberOfCameras = Camera.getNumberOfCameras();
+
+ // Find the ID of the back-facing ("default") camera
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ for (int i = 0; i < mNumberOfCameras; i++) {
+ Camera.getCameraInfo(i, cameraInfo);
+ if (cameraInfo.facing == position) {
+ return Camera.open(i);
+
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a media file in the {@code Environment.DIRECTORY_PICTURES} directory. The directory
+ * is persistent and available to other applications like gallery.
+ *
+ * @param type Media type. Can be video or image.
+ * @return A file object pointing to the newly created file.
+ */
+ public static File getOutputMediaFile(int type){
+ // To be safe, you should check that the SDCard is mounted
+ // using Environment.getExternalStorageState() before doing this.
+ if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
+ return null;
+ }
+
+ File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_PICTURES), "CameraSample");
+ // This location works best if you want the created images to be shared
+ // between applications and persist after your app has been uninstalled.
+
+ // Create the storage directory if it does not exist
+ if (! mediaStorageDir.exists()){
+ if (! mediaStorageDir.mkdirs()) {
+ Log.d("CameraSample", "failed to create directory");
+ return null;
+ }
+ }
+
+ // Create a media file name
+ String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
+ File mediaFile;
+ if (type == MEDIA_TYPE_IMAGE){
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "IMG_"+ timeStamp + ".jpg");
+ } else if(type == MEDIA_TYPE_VIDEO) {
+ mediaFile = new File(mediaStorageDir.getPath() + File.separator +
+ "VID_"+ timeStamp + ".mp4");
+ } else {
+ return null;
+ }
+
+ return mediaFile;
+ }
+
+}
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
new file mode 100644
index 0000000..a511221
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/common/media/MediaCodecWrapper.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013 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.common.media;
+
+import android.media.*;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+/**
+ * Simplifies the MediaCodec interface by wrapping around the buffer processing operations.
+ */
+public class MediaCodecWrapper {
+
+ // Handler to use for {@code OutputSampleListener} and {code OutputFormatChangedListener}
+ // callbacks
+ private Handler mHandler;
+
+
+ // Callback when media output format changes.
+ public interface OutputFormatChangedListener {
+ void outputFormatChanged(MediaCodecWrapper sender, MediaFormat newFormat);
+ }
+
+ private OutputFormatChangedListener mOutputFormatChangedListener = null;
+
+ /**
+ * Callback for decodes frames. Observers can register a listener for optional stream
+ * of decoded data
+ */
+ public interface OutputSampleListener {
+ void outputSample(MediaCodecWrapper sender, MediaCodec.BufferInfo info, ByteBuffer buffer);
+ }
+
+ /**
+ * The {@link MediaCodec} that is managed by this class.
+ */
+ private MediaCodec mDecoder;
+
+ // References to the internal buffers managed by the codec. The codec
+ // refers to these buffers by index, never by reference so it's up to us
+ // to keep track of which buffer is which.
+ private ByteBuffer[] mInputBuffers;
+ private ByteBuffer[] mOutputBuffers;
+
+ // Indices of the input buffers that are currently available for writing. We'll
+ // consume these in the order they were dequeued from the codec.
+ private Queue<Integer> mAvailableInputBuffers;
+
+ // Indices of the output buffers that currently hold valid data, in the order
+ // they were produced by the codec.
+ private Queue<Integer> mAvailableOutputBuffers;
+
+ // Information about each output buffer, by index. Each entry in this array
+ // is valid if and only if its index is currently contained in mAvailableOutputBuffers.
+ private MediaCodec.BufferInfo[] mOutputBufferInfo;
+
+ // An (optional) stream that will receive decoded data.
+ private OutputSampleListener mOutputSampleListener;
+
+ private MediaCodecWrapper(MediaCodec codec) {
+ mDecoder = codec;
+ codec.start();
+ mInputBuffers = codec.getInputBuffers();
+ mOutputBuffers = codec.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableInputBuffers = new ArrayDeque<Integer>(mOutputBuffers.length);
+ mAvailableOutputBuffers = new ArrayDeque<Integer>(mInputBuffers.length);
+ }
+
+ /**
+ * Releases resources and ends the encoding/decoding session.
+ */
+ public void stopAndRelease() {
+ mDecoder.stop();
+ mDecoder.release();
+ mDecoder = null;
+ mHandler = null;
+ }
+
+ /**
+ * Getter for the registered {@link OutputFormatChangedListener}
+ */
+ public OutputFormatChangedListener getOutputFormatChangedListener() {
+ return mOutputFormatChangedListener;
+ }
+
+ /**
+ *
+ * @param outputFormatChangedListener the listener for callback.
+ * @param handler message handler for posting the callback.
+ */
+ public void setOutputFormatChangedListener(final OutputFormatChangedListener
+ outputFormatChangedListener, Handler handler) {
+ mOutputFormatChangedListener = outputFormatChangedListener;
+
+ // Making sure we don't block ourselves due to a bad implementation of the callback by
+ // using a handler provided by client.
+ Looper looper;
+ mHandler = handler;
+ if (outputFormatChangedListener != null && mHandler == null) {
+ if ((looper = Looper.myLooper()) != null) {
+ mHandler = new Handler();
+ } else {
+ throw new IllegalArgumentException(
+ "Looper doesn't exist in the calling thread");
+ }
+ }
+ }
+
+ /**
+ * Constructs the {@link MediaCodecWrapper} wrapper object around the video codec.
+ * The codec is created using the encapsulated information in the
+ * {@link MediaFormat} object.
+ *
+ * @param trackFormat The format of the media object to be decoded.
+ * @param surface Surface to render the decoded frames.
+ * @return
+ */
+ public static MediaCodecWrapper fromVideoFormat(final MediaFormat trackFormat,
+ Surface surface) {
+ MediaCodecWrapper result = null;
+ MediaCodec videoCodec = null;
+
+ // BEGIN_INCLUDE(create_codec)
+ final String mimeType = trackFormat.getString(MediaFormat.KEY_MIME);
+
+ // Check to see if this is actually a video mime type. If it is, then create
+ // a codec that can decode this mime type.
+ if (mimeType.contains("video/")) {
+ videoCodec = MediaCodec.createDecoderByType(mimeType);
+ videoCodec.configure(trackFormat, surface, null, 0);
+
+ }
+
+ // If codec creation was successful, then create a wrapper object around the
+ // newly created codec.
+ if (videoCodec != null) {
+ result = new MediaCodecWrapper(videoCodec);
+ }
+ // END_INCLUDE(create_codec)
+
+ return result;
+ }
+
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param input A ByteBuffer containing the input data for one sample. The buffer must be set
+ * up for reading, with its position set to the beginning of the sample data and its limit
+ * set to the end of the sample data.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final ByteBuffer input,
+ final MediaCodec.CryptoInfo crypto,
+ final long presentationTimeUs,
+ final int flags) throws MediaCodec.CryptoException, WriteException {
+ boolean result = false;
+ int size = input.remaining();
+
+ // check if we have dequed input buffers available from the codec
+ if (size > 0 && !mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // we can't write our sample to a lesser capacity input buffer.
+ if (size > buffer.capacity()) {
+ throw new MediaCodecWrapper.WriteException(String.format(
+ "Insufficient capacity in MediaCodec buffer: "
+ + "tried to write %d, buffer capacity is %d.",
+ input.remaining(),
+ buffer.capacity()));
+ }
+
+ buffer.clear();
+ buffer.put(input);
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (crypto == null) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ mDecoder.queueSecureInputBuffer(index, 0, crypto, presentationTimeUs, flags);
+ }
+ result = true;
+ }
+ return result;
+ }
+
+ static MediaCodec.CryptoInfo cryptoInfo= new MediaCodec.CryptoInfo();
+
+ /**
+ * Write a media sample to the decoder.
+ *
+ * A "sample" here refers to a single atomic access unit in the media stream. The definition
+ * of "access unit" is dependent on the type of encoding used, but it typically refers to
+ * a single frame of video or a few seconds of audio. {@link android.media.MediaExtractor}
+ * extracts data from a stream one sample at a time.
+ *
+ * @param extractor Instance of {@link android.media.MediaExtractor} wrapping the media.
+ *
+ * @param presentationTimeUs The time, relative to the beginning of the media stream,
+ * at which this buffer should be rendered.
+ *
+ * @param flags Flags to pass to the decoder. See {@link MediaCodec#queueInputBuffer(int,
+ * int, int, long, int)}
+ *
+ * @throws MediaCodec.CryptoException
+ */
+ public boolean writeSample(final MediaExtractor extractor,
+ final boolean isSecure,
+ final long presentationTimeUs,
+ int flags) {
+ boolean result = false;
+ boolean isEos = false;
+
+ if (!mAvailableInputBuffers.isEmpty()) {
+ int index = mAvailableInputBuffers.remove();
+ ByteBuffer buffer = mInputBuffers[index];
+
+ // reads the sample from the file using extractor into the buffer
+ int size = extractor.readSampleData(buffer, 0);
+ if (size <= 0) {
+ flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ }
+
+ // Submit the buffer to the codec for decoding. The presentationTimeUs
+ // indicates the position (play time) for the current sample.
+ if (!isSecure) {
+ mDecoder.queueInputBuffer(index, 0, size, presentationTimeUs, flags);
+ } else {
+ extractor.getSampleCryptoInfo(cryptoInfo);
+ mDecoder.queueSecureInputBuffer(index, 0, cryptoInfo, presentationTimeUs, flags);
+ }
+
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Performs a peek() operation in the queue to extract media info for the buffer ready to be
+ * released i.e. the head element of the queue.
+ *
+ * @param out_bufferInfo An output var to hold the buffer info.
+ *
+ * @return True, if the peek was successful.
+ */
+ public boolean peekSample(MediaCodec.BufferInfo out_bufferInfo) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ boolean result = false;
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.peek();
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ // metadata of the sample
+ out_bufferInfo.set(
+ info.offset,
+ info.size,
+ info.presentationTimeUs,
+ info.flags);
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Processes, releases and optionally renders the output buffer available at the head of the
+ * queue. All observers are notified with a callback. See {@link
+ * OutputSampleListener#outputSample(MediaCodecWrapper, android.media.MediaCodec.BufferInfo,
+ * java.nio.ByteBuffer)}
+ *
+ * @param render True, if the buffer is to be rendered on the {@link Surface} configured
+ *
+ */
+ public void popSample(boolean render) {
+ // dequeue available buffers and synchronize our data structures with the codec.
+ update();
+ if (!mAvailableOutputBuffers.isEmpty()) {
+ int index = mAvailableOutputBuffers.remove();
+
+ if (render && mOutputSampleListener != null) {
+ ByteBuffer buffer = mOutputBuffers[index];
+ MediaCodec.BufferInfo info = mOutputBufferInfo[index];
+ mOutputSampleListener.outputSample(this, info, buffer);
+ }
+
+ // releases the buffer back to the codec
+ mDecoder.releaseOutputBuffer(index, render);
+ }
+ }
+
+ /**
+ * Synchronize this object's state with the internal state of the wrapped
+ * MediaCodec.
+ */
+ private void update() {
+ // BEGIN_INCLUDE(update_codec_state)
+ int index;
+
+ // Get valid input buffers from the codec to fill later in the same order they were
+ // made available by the codec.
+ while ((index = mDecoder.dequeueInputBuffer(0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ mAvailableInputBuffers.add(index);
+ }
+
+
+ // Likewise with output buffers. If the output buffers have changed, start using the
+ // new set of output buffers. If the output format has changed, notify listeners.
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ while ((index = mDecoder.dequeueOutputBuffer(info, 0)) != MediaCodec.INFO_TRY_AGAIN_LATER) {
+ switch (index) {
+ case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
+ mOutputBuffers = mDecoder.getOutputBuffers();
+ mOutputBufferInfo = new MediaCodec.BufferInfo[mOutputBuffers.length];
+ mAvailableOutputBuffers.clear();
+ break;
+ case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
+ if (mOutputFormatChangedListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mOutputFormatChangedListener
+ .outputFormatChanged(MediaCodecWrapper.this,
+ mDecoder.getOutputFormat());
+
+ }
+ });
+ }
+ break;
+ default:
+ // Making sure the index is valid before adding to output buffers. We've already
+ // handled INFO_TRY_AGAIN_LATER, INFO_OUTPUT_FORMAT_CHANGED &
+ // INFO_OUTPUT_BUFFERS_CHANGED i.e all the other possible return codes but
+ // asserting index value anyways for future-proofing the code.
+ if(index >= 0) {
+ mOutputBufferInfo[index] = info;
+ mAvailableOutputBuffers.add(index);
+ } else {
+ throw new IllegalStateException("Unknown status from dequeueOutputBuffer");
+ }
+ break;
+ }
+
+ }
+ // END_INCLUDE(update_codec_state)
+
+ }
+
+ private class WriteException extends Throwable {
+ private WriteException(final String detailMessage) {
+ super(detailMessage);
+ }
+ }
+}
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/mediarecorder/MainActivity.java b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/mediarecorder/MainActivity.java
new file mode 100644
index 0000000..8587636
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/java/com/example/android/mediarecorder/MainActivity.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2013 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.mediarecorder;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.hardware.Camera;
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.TextureView;
+import android.view.View;
+import android.widget.Button;
+
+import com.example.android.common.media.CameraHelper;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * This activity uses the camera/camcorder as the A/V source for the {@link android.media.MediaRecorder} API.
+ * A {@link android.view.TextureView} is used as the camera preview which limits the code to API 14+. This
+ * can be easily replaced with a {@link android.view.SurfaceView} to run on older devices.
+ */
+public class MainActivity extends Activity {
+
+ private Camera mCamera;
+ private TextureView mPreview;
+ private MediaRecorder mMediaRecorder;
+
+ private boolean isRecording = false;
+ private static final String TAG = "Recorder";
+ private Button captureButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ mPreview = (TextureView) findViewById(R.id.surface_view);
+ captureButton = (Button) findViewById(R.id.button_capture);
+ }
+
+ /**
+ * The capture button controls all user interaction. When recording, the button click
+ * stops recording, releases {@link android.media.MediaRecorder} and {@link android.hardware.Camera}. When not recording,
+ * it prepares the {@link android.media.MediaRecorder} and starts recording.
+ *
+ * @param view the view generating the event.
+ */
+ public void onCaptureClick(View view) {
+ if (isRecording) {
+ // BEGIN_INCLUDE(stop_release_media_recorder)
+
+ // stop recording and release camera
+ mMediaRecorder.stop(); // stop the recording
+ releaseMediaRecorder(); // release the MediaRecorder object
+ mCamera.lock(); // take camera access back from MediaRecorder
+
+ // inform the user that recording has stopped
+ setCaptureButtonText("Capture");
+ isRecording = false;
+ releaseCamera();
+ // END_INCLUDE(stop_release_media_recorder)
+
+ } else {
+
+ // BEGIN_INCLUDE(prepare_start_media_recorder)
+
+ new MediaPrepareTask().execute(null, null, null);
+
+ // END_INCLUDE(prepare_start_media_recorder)
+
+ }
+ }
+
+ private void setCaptureButtonText(String title) {
+ captureButton.setText(title);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ // if we are using MediaRecorder, release it first
+ releaseMediaRecorder();
+ // release the camera immediately on pause event
+ releaseCamera();
+ }
+
+ private void releaseMediaRecorder(){
+ if (mMediaRecorder != null) {
+ // clear recorder configuration
+ mMediaRecorder.reset();
+ // release the recorder object
+ mMediaRecorder.release();
+ mMediaRecorder = null;
+ // Lock camera for later use i.e taking it back from MediaRecorder.
+ // MediaRecorder doesn't need it anymore and we will release it if the activity pauses.
+ mCamera.lock();
+ }
+ }
+
+ private void releaseCamera(){
+ if (mCamera != null){
+ // release the camera for other applications
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ private boolean prepareVideoRecorder(){
+
+ // BEGIN_INCLUDE (configure_preview)
+ mCamera = CameraHelper.getDefaultCameraInstance();
+
+ // We need to make sure that our preview and recording video size are supported by the
+ // camera. Query camera to find all the sizes and choose the optimal size given the
+ // dimensions of our preview surface.
+ Camera.Parameters parameters = mCamera.getParameters();
+ List<Camera.Size> mSupportedPreviewSizes = parameters.getSupportedPreviewSizes();
+ Camera.Size optimalSize = CameraHelper.getOptimalPreviewSize(mSupportedPreviewSizes,
+ mPreview.getWidth(), mPreview.getHeight());
+
+ // Use the same size for recording profile.
+ CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
+ profile.videoFrameWidth = optimalSize.width;
+ profile.videoFrameHeight = optimalSize.height;
+
+ // likewise for the camera object itself.
+ parameters.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
+ mCamera.setParameters(parameters);
+ try {
+ // Requires API level 11+, For backward compatibility use {@link setPreviewDisplay}
+ // with {@link SurfaceView}
+ mCamera.setPreviewTexture(mPreview.getSurfaceTexture());
+ } catch (IOException e) {
+ Log.e(TAG, "Surface texture is unavailable or unsuitable" + e.getMessage());
+ return false;
+ }
+ // END_INCLUDE (configure_preview)
+
+
+ // BEGIN_INCLUDE (configure_media_recorder)
+ mMediaRecorder = new MediaRecorder();
+
+ // Step 1: Unlock and set camera to MediaRecorder
+ mCamera.unlock();
+ mMediaRecorder.setCamera(mCamera);
+
+ // Step 2: Set sources
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT );
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+ // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
+ mMediaRecorder.setProfile(profile);
+
+ // Step 4: Set output file
+ mMediaRecorder.setOutputFile(CameraHelper.getOutputMediaFile(
+ CameraHelper.MEDIA_TYPE_VIDEO).toString());
+ // END_INCLUDE (configure_media_recorder)
+
+ // Step 5: Prepare configured MediaRecorder
+ try {
+ mMediaRecorder.prepare();
+ } catch (IllegalStateException e) {
+ Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
+ releaseMediaRecorder();
+ return false;
+ } catch (IOException e) {
+ Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
+ releaseMediaRecorder();
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Asynchronous task for preparing the {@link android.media.MediaRecorder} since it's a long blocking
+ * operation.
+ */
+ class MediaPrepareTask extends AsyncTask<Void, Void, Boolean> {
+
+ @Override
+ protected Boolean doInBackground(Void... voids) {
+ // initialize video camera
+ if (prepareVideoRecorder()) {
+ // Camera is available and unlocked, MediaRecorder is prepared,
+ // now you can start recording
+ mMediaRecorder.start();
+
+ isRecording = true;
+ } else {
+ // prepare didn't work, release the camera
+ releaseMediaRecorder();
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ if (!result) {
+ MainActivity.this.finish();
+ }
+ // inform the user that recording has started
+ setCaptureButtonText("Stop");
+
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..13cd1e8
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..00b2bd9
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..953f1cc
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f2ccb10
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..d53b376
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,24 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:orientation="vertical"
+ tools:context=".MainActivity">
+
+ <TextureView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/surface_view" />
+
+ <Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_capture"
+ android:layout_gravity="bottom"
+ android:onClick="onCaptureClick"
+ android:text="@string/btnCapture"/>
+</FrameLayout>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..c4aad9b
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2013 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.
+-->
+
+<resources>
+ <!-- Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..f9ade8c
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">MediaRecorder</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample uses the camera/camcorder as the A/V source for the MediaRecorder API.
+ A TextureView is used as the camera preview which limits the code to API 14+. This
+ can be easily replaced with a SurfaceView to run on older devices.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/dimens.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..0353ed6
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright (C) 2013 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.
+-->
+
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/strings.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b6a2cd2
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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.
+-->
+
+<resources>
+
+ <string name="action_settings">Settings</string>
+ <string name="hello_world">Hello world!</string>
+ <string name="btnCapture">capture</string>
+
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/MediaRecorderSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/MediaRecorder/README.txt b/prebuilts/gradle/MediaRecorder/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/MediaRecorder/build.gradle b/prebuilts/gradle/MediaRecorder/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/MediaRecorder/gradlew b/prebuilts/gradle/MediaRecorder/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/MediaRecorder/gradlew.bat b/prebuilts/gradle/MediaRecorder/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/MediaRecorder/settings.gradle b/prebuilts/gradle/MediaRecorder/settings.gradle
new file mode 100644
index 0000000..61e4032
--- /dev/null
+++ b/prebuilts/gradle/MediaRecorder/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'MediaRecorderSample'
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/build.gradle b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/build.gradle
new file mode 100644
index 0000000..e88b9ff
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 8
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/AndroidManifest.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1ae29df
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.networkconnect"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/Theme.Sample"
+ android:allowBackup="true">
+
+ <activity
+ android:name="com.example.android.networkconnect.MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/MainActivity.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/MainActivity.java
new file mode 100755
index 0000000..3ad4646
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/MainActivity.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2013 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.networkconnect;
+
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.util.TypedValue;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * Sample application demonstrating how to connect to the network and fetch raw
+ * HTML. It uses AsyncTask to do the fetch on a background thread. To establish
+ * the network connection, it uses HttpURLConnection.
+ *
+ * This sample uses the logging framework to display log output in the log
+ * fragment (LogFragment).
+ */
+public class MainActivity extends FragmentActivity {
+
+ public static final String TAG = "Network Connect";
+
+ // Reference to the fragment showing events, so we can clear it with a button
+ // as necessary.
+ private LogFragment mLogFragment;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ // Initialize text fragment that displays intro text.
+ SimpleTextFragment introFragment = (SimpleTextFragment)
+ getSupportFragmentManager().findFragmentById(R.id.intro_fragment);
+ introFragment.setText(R.string.welcome_message);
+ introFragment.getTextView().setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16.0f);
+
+ // Initialize the logging framework.
+ initializeLogging();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ // When the user clicks FETCH, fetch the first 500 characters of
+ // raw HTML from www.google.com.
+ case R.id.fetch_action:
+ new DownloadTask().execute("http://www.google.com");
+ return true;
+ // Clear the log view fragment.
+ case R.id.clear_action:
+ mLogFragment.getLogView().setText("");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Implementation of AsyncTask, to fetch the data in the background away from
+ * the UI thread.
+ */
+ private class DownloadTask extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... urls) {
+ try {
+ return loadFromNetwork(urls[0]);
+ } catch (IOException e) {
+ return getString(R.string.connection_error);
+ }
+ }
+
+ /**
+ * Uses the logging framework to display the output of the fetch
+ * operation in the log fragment.
+ */
+ @Override
+ protected void onPostExecute(String result) {
+ Log.i(TAG, result);
+ }
+ }
+
+ /** Initiates the fetch operation. */
+ private String loadFromNetwork(String urlString) throws IOException {
+ InputStream stream = null;
+ String str ="";
+
+ try {
+ stream = downloadUrl(urlString);
+ str = readIt(stream, 500);
+ } finally {
+ if (stream != null) {
+ stream.close();
+ }
+ }
+ return str;
+ }
+
+ /**
+ * Given a string representation of a URL, sets up a connection and gets
+ * an input stream.
+ * @param urlString A string representation of a URL.
+ * @return An InputStream retrieved from a successful HttpURLConnection.
+ * @throws java.io.IOException
+ */
+ private InputStream downloadUrl(String urlString) throws IOException {
+ // BEGIN_INCLUDE(get_inputstream)
+ URL url = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setReadTimeout(10000 /* milliseconds */);
+ conn.setConnectTimeout(15000 /* milliseconds */);
+ conn.setRequestMethod("GET");
+ conn.setDoInput(true);
+ // Start the query
+ conn.connect();
+ InputStream stream = conn.getInputStream();
+ return stream;
+ // END_INCLUDE(get_inputstream)
+ }
+
+ /** Reads an InputStream and converts it to a String.
+ * @param stream InputStream containing HTML from targeted site.
+ * @param len Length of string that this method returns.
+ * @return String concatenated according to len parameter.
+ * @throws java.io.IOException
+ * @throws java.io.UnsupportedEncodingException
+ */
+ private String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
+ Reader reader = null;
+ reader = new InputStreamReader(stream, "UTF-8");
+ char[] buffer = new char[len];
+ reader.read(buffer);
+ return new String(buffer);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ public void initializeLogging() {
+
+ // Using Log, front-end to the logging chain, emulates
+ // android.util.log method signatures.
+
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ // A filter that strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ mLogFragment =
+ (LogFragment) getSupportFragmentManager().findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(mLogFragment.getLogView());
+ }
+}
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/SimpleTextFragment.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/SimpleTextFragment.java
new file mode 100644
index 0000000..3202937
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/java/com/example/android/networkconnect/SimpleTextFragment.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2013 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.networkconnect;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Simple fragment containing only a TextView. Used by TextPagerAdapter to create
+ * tutorial-style pages for apps.
+ */
+public class SimpleTextFragment extends Fragment {
+
+ // Contains the text that will be displayed by this Fragment
+ String mText;
+
+ // Contains a resource ID for the text that will be displayed by this fragment.
+ int mTextId = -1;
+
+ // Keys which will be used to store/retrieve text passed in via setArguments.
+ public static final String TEXT_KEY = "text";
+ public static final String TEXT_ID_KEY = "text_id";
+
+ // For situations where the app wants to modify text at Runtime, exposing the TextView.
+ private TextView mTextView;
+
+ public SimpleTextFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Before initializing the textView, check if any arguments were provided via setArguments.
+ processArguments();
+
+ // Create a new TextView and set its text to whatever was provided.
+ mTextView = new TextView(getActivity());
+ mTextView.setGravity(Gravity.CENTER);
+
+ if (mText != null) {
+ mTextView.setText(mText);
+ Log.i("SimpleTextFragment", mText);
+ }
+ return mTextView;
+ }
+
+ public TextView getTextView() {
+ return mTextView;
+ }
+
+ /**
+ * Changes the text for this TextView, according to the resource ID provided.
+ * @param stringId A resource ID representing the text content for this Fragment's TextView.
+ */
+ public void setText(int stringId) {
+ getTextView().setText(getActivity().getString(stringId));
+ }
+
+ /**
+ * Processes the arguments passed into this Fragment via setArguments method.
+ * Currently the method only looks for text or a textID, nothing else.
+ */
+ public void processArguments() {
+ // For most objects we'd handle the multiple possibilities for initialization variables
+ // as multiple constructors. For Fragments, however, it's customary to use
+ // setArguments / getArguments.
+ if (getArguments() != null) {
+ Bundle args = getArguments();
+ if (args.containsKey(TEXT_KEY)) {
+ mText = args.getString(TEXT_KEY);
+ Log.d("Constructor", "Added Text.");
+ } else if (args.containsKey(TEXT_ID_KEY)) {
+ mTextId = args.getInt(TEXT_ID_KEY);
+ mText = getString(mTextId);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..22ce606
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..f21e17b
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..64b8059
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..6b4434a
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/sample_main.xml
new file mode 100755
index 0000000..76fa7d7
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <fragment
+ android:name="com.example.android.networkconnect.SimpleTextFragment"
+ android:id="@+id/intro_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/menu/main.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..ef1568f
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/menu/main.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/fetch_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/fetch_text" />
+ <item android:id="@+id/clear_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/clear_text" />
+</menu>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..0248814
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">NetworkConnect</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample demonstrates how to connect to the network and fetch raw HTML using
+ HttpURLConnection. AsyncTask is used to perform the fetch on a background thread.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/strings.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..1e7915a
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+ <string name="welcome_message">Welcome to Network Connect!
+ Click FETCH to fetch the first 500 characters of raw HTML from www.google.com.
+ </string>
+
+ <string name="fetch_text">Fetch</string>
+ <string name="clear_text">Clear</string>
+ <string name="connection_error">Connection error.</string>
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/AndroidManifest.xml b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..80fec80
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.networkconnect.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.networkconnect"
+ android:label="Tests for com.example.android.networkconnect" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/src/com/example/android/networkconnect/tests/SampleTests.java b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/src/com/example/android/networkconnect/tests/SampleTests.java
new file mode 100644
index 0000000..a554964
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/NetworkConnectSample/tests/src/com/example/android/networkconnect/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.networkconnect.tests;
+
+import com.example.android.networkconnect.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for NetworkConnect sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private NetworkConnectFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (NetworkConnectFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/NetworkConnect/README.txt b/prebuilts/gradle/NetworkConnect/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/NetworkConnect/build.gradle b/prebuilts/gradle/NetworkConnect/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/NetworkConnect/gradlew b/prebuilts/gradle/NetworkConnect/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/NetworkConnect/gradlew.bat b/prebuilts/gradle/NetworkConnect/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/NetworkConnect/settings.gradle b/prebuilts/gradle/NetworkConnect/settings.gradle
new file mode 100644
index 0000000..ebae091
--- /dev/null
+++ b/prebuilts/gradle/NetworkConnect/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'NetworkConnectSample'
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/README.txt b/prebuilts/gradle/RenderScriptIntrinsic/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/build.gradle b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/build.gradle
new file mode 100644
index 0000000..4240bc2
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/build.gradle
@@ -0,0 +1,67 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 8
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
+ compile files('renderscript-v8.jar')
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+
+ defaultConfig {
+
+ renderscriptTargetApi 18
+ renderscriptSupportMode true
+
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/AndroidManifest.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..566ef8a
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?><!--
+ Copyright 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.renderscriptintrinsic"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <application
+ android:allowBackup="true"
+ android:label="RenderScriptIntrinsic"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity
+ android:name=".MainActivity"
+ android:label="RenderScriptIntrinsic"
+ android:theme="@style/FullscreenTheme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/MainActivity.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/MainActivity.java
new file mode 100644
index 0000000..4b6f5ce
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/MainActivity.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.renderscriptintrinsic;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageView;
+import android.widget.RadioButton;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.support.v8.renderscript.*;
+
+public class MainActivity extends Activity {
+ /* Number of bitmaps that is used for renderScript thread and UI thread synchronization.
+ Ideally, this can be reduced to 2, however in some devices, 2 buffers still showing tierings on UI.
+ Investigating a root cause.
+ */
+ private final int NUM_BITMAPS = 3;
+ private int mCurrentBitmap = 0;
+ private Bitmap mBitmapIn;
+ private Bitmap[] mBitmapsOut;
+ private ImageView mImageView;
+
+ private RenderScript mRS;
+ private Allocation mInAllocation;
+ private Allocation[] mOutAllocations;
+
+ private ScriptIntrinsicBlur mScriptBlur;
+ private ScriptIntrinsicConvolve5x5 mScriptConvolve;
+ private ScriptIntrinsicColorMatrix mScriptMatrix;
+
+ private final int MODE_BLUR = 0;
+ private final int MODE_CONVOLVE = 1;
+ private final int MODE_COLORMATRIX = 2;
+
+ private int mFilterMode = MODE_BLUR;
+
+ private RenderScriptTask mLatestTask = null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.main_layout);
+
+ /*
+ * Initialize UI
+ */
+
+ //Set up main image view
+ mBitmapIn = loadBitmap(R.drawable.data);
+ mBitmapsOut = new Bitmap[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mBitmapsOut[i] = Bitmap.createBitmap(mBitmapIn.getWidth(),
+ mBitmapIn.getHeight(), mBitmapIn.getConfig());
+ }
+
+ mImageView = (ImageView) findViewById(R.id.imageView);
+ mImageView.setImageBitmap(mBitmapsOut[mCurrentBitmap]);
+ mCurrentBitmap += (mCurrentBitmap + 1) % NUM_BITMAPS;
+
+ //Set up seekbar
+ final SeekBar seekbar = (SeekBar) findViewById(R.id.seekBar1);
+ seekbar.setProgress(50);
+ seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
+ public void onProgressChanged(SeekBar seekBar, int progress,
+ boolean fromUser) {
+ updateImage(progress);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+ });
+
+ //Setup effect selector
+ RadioButton radio0 = (RadioButton) findViewById(R.id.radio0);
+ radio0.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ mFilterMode = MODE_BLUR;
+ updateImage(seekbar.getProgress());
+ }
+ }
+ });
+ RadioButton radio1 = (RadioButton) findViewById(R.id.radio1);
+ radio1.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ mFilterMode = MODE_CONVOLVE;
+ updateImage(seekbar.getProgress());
+ }
+ }
+ });
+ RadioButton radio2 = (RadioButton) findViewById(R.id.radio2);
+ radio2.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ mFilterMode = MODE_COLORMATRIX;
+ updateImage(seekbar.getProgress());
+ }
+ }
+ });
+
+ /*
+ * Create renderScript
+ */
+ createScript();
+
+ /*
+ * Create thumbnails
+ */
+ createThumbnail();
+
+
+ /*
+ * Invoke renderScript kernel and update imageView
+ */
+ mFilterMode = MODE_BLUR;
+ updateImage(50);
+ }
+
+ private void createScript() {
+ mRS = RenderScript.create(this);
+
+ mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn);
+
+ mOutAllocations = new Allocation[NUM_BITMAPS];
+ for (int i = 0; i < NUM_BITMAPS; ++i) {
+ mOutAllocations[i] = Allocation.createFromBitmap(mRS, mBitmapsOut[i]);
+ }
+
+ /*
+ Create intrinsics.
+ RenderScript has built-in features such as blur, convolve filter etc.
+ These intrinsics are handy for specific operations without writing RenderScript kernel.
+ In the sample, it's creating blur, convolve and matrix intrinsics.
+ */
+
+ mScriptBlur = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
+ mScriptConvolve = ScriptIntrinsicConvolve5x5.create(mRS,
+ Element.U8_4(mRS));
+ mScriptMatrix = ScriptIntrinsicColorMatrix.create(mRS,
+ Element.U8_4(mRS));
+ }
+
+ private void performFilter(Allocation inAllocation,
+ Allocation outAllocation, Bitmap bitmapOut, float value) {
+ switch (mFilterMode) {
+ case MODE_BLUR:
+ /*
+ * Set blur kernel size
+ */
+ mScriptBlur.setRadius(value);
+
+ /*
+ * Invoke filter kernel
+ */
+ mScriptBlur.setInput(inAllocation);
+ mScriptBlur.forEach(outAllocation);
+ break;
+ case MODE_CONVOLVE: {
+ float f1 = value;
+ float f2 = 1.0f - f1;
+
+ // Emboss filter kernel
+ float coefficients[] = {-f1 * 2, 0, -f1, 0, 0, 0, -f2 * 2, -f2, 0,
+ 0, -f1, -f2, 1, f2, f1, 0, 0, f2, f2 * 2, 0, 0, 0, f1, 0,
+ f1 * 2,};
+ /*
+ * Set kernel parameter
+ */
+ mScriptConvolve.setCoefficients(coefficients);
+
+ /*
+ * Invoke filter kernel
+ */
+ mScriptConvolve.setInput(inAllocation);
+ mScriptConvolve.forEach(outAllocation);
+ break;
+ }
+ case MODE_COLORMATRIX: {
+ /*
+ * Set HUE rotation matrix
+ * The matrix below performs a combined operation of,
+ * RGB->HSV transform * HUE rotation * HSV->RGB transform
+ */
+ float cos = (float) Math.cos((double) value);
+ float sin = (float) Math.sin((double) value);
+ Matrix3f mat = new Matrix3f();
+ mat.set(0, 0, (float) (.299 + .701 * cos + .168 * sin));
+ mat.set(1, 0, (float) (.587 - .587 * cos + .330 * sin));
+ mat.set(2, 0, (float) (.114 - .114 * cos - .497 * sin));
+ mat.set(0, 1, (float) (.299 - .299 * cos - .328 * sin));
+ mat.set(1, 1, (float) (.587 + .413 * cos + .035 * sin));
+ mat.set(2, 1, (float) (.114 - .114 * cos + .292 * sin));
+ mat.set(0, 2, (float) (.299 - .3 * cos + 1.25 * sin));
+ mat.set(1, 2, (float) (.587 - .588 * cos - 1.05 * sin));
+ mat.set(2, 2, (float) (.114 + .886 * cos - .203 * sin));
+ mScriptMatrix.setColorMatrix(mat);
+
+ /*
+ * Invoke filter kernel
+ */
+ mScriptMatrix.forEach(inAllocation, outAllocation);
+ }
+ break;
+ }
+
+ /*
+ * Copy to bitmap and invalidate image view
+ */
+ outAllocation.copyTo(bitmapOut);
+ }
+
+ /*
+ Convert seekBar progress parameter (0-100 in range) to parameter for each intrinsic filter.
+ (e.g. 1.0-25.0 in Blur filter)
+ */
+ private float getFilterParameter(int i) {
+ float f = 0.f;
+ switch (mFilterMode) {
+ case MODE_BLUR: {
+ final float max = 25.0f;
+ final float min = 1.f;
+ f = (float) ((max - min) * (i / 100.0) + min);
+ }
+ break;
+ case MODE_CONVOLVE: {
+ final float max = 2.f;
+ final float min = 0.f;
+ f = (float) ((max - min) * (i / 100.0) + min);
+ }
+ break;
+ case MODE_COLORMATRIX: {
+ final float max = (float) Math.PI;
+ final float min = (float) -Math.PI;
+ f = (float) ((max - min) * (i / 100.0) + min);
+ }
+ break;
+ }
+ return f;
+
+ }
+
+ /*
+ * In the AsyncTask, it invokes RenderScript intrinsics to do a filtering.
+ * After the filtering is done, an operation blocks at Allication.copyTo() in AsyncTask thread.
+ * Once all operation is finished at onPostExecute() in UI thread, it can invalidate and update ImageView UI.
+ */
+ private class RenderScriptTask extends AsyncTask<Float, Integer, Integer> {
+ Boolean issued = false;
+
+ protected Integer doInBackground(Float... values) {
+ int index = -1;
+ if (isCancelled() == false) {
+ issued = true;
+ index = mCurrentBitmap;
+
+ performFilter(mInAllocation, mOutAllocations[index], mBitmapsOut[index], values[0]);
+ mCurrentBitmap = (mCurrentBitmap + 1) % NUM_BITMAPS;
+ }
+ return index;
+ }
+
+ void updateView(Integer result) {
+ if (result != -1) {
+ // Request UI update
+ mImageView.setImageBitmap(mBitmapsOut[result]);
+ mImageView.invalidate();
+ }
+ }
+
+ protected void onPostExecute(Integer result) {
+ updateView(result);
+ }
+
+ protected void onCancelled(Integer result) {
+ if (issued) {
+ updateView(result);
+ }
+ }
+ }
+
+ /*
+ Invoke AsynchTask and cancel previous task.
+ When AsyncTasks are piled up (typically in slow device with heavy kernel),
+ Only the latest (and already started) task invokes RenderScript operation.
+ */
+ private void updateImage(int progress) {
+ float f = getFilterParameter(progress);
+
+ if (mLatestTask != null)
+ mLatestTask.cancel(false);
+ mLatestTask = new RenderScriptTask();
+
+ mLatestTask.execute(f);
+ }
+
+ /*
+ Helper to load Bitmap from resource
+ */
+ private Bitmap loadBitmap(int resource) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ return BitmapFactory.decodeResource(getResources(), resource, options);
+ }
+
+ /*
+ Create thumbNail for UI. It invokes RenderScript kernel synchronously in UI-thread,
+ which is OK for small thumbnail (but not ideal).
+ */
+ private void createThumbnail() {
+ int width = 72;
+ int height = 96;
+ float scale = getResources().getDisplayMetrics().density;
+ int pixelsWidth = (int) (width * scale + 0.5f);
+ int pixelsHeight = (int) (height * scale + 0.5f);
+
+ //Temporary image
+ Bitmap tempBitmap = Bitmap.createScaledBitmap(mBitmapIn, pixelsWidth, pixelsHeight, false);
+ Allocation inAllocation = Allocation.createFromBitmap(mRS, tempBitmap);
+
+ //Create thumbnail with each RS intrinsic and set it to radio buttons
+ int[] modes = {MODE_BLUR, MODE_CONVOLVE, MODE_COLORMATRIX};
+ int[] ids = {R.id.radio0, R.id.radio1, R.id.radio2};
+ int[] parameter = {50, 100, 25};
+ for (int mode : modes) {
+ mFilterMode = mode;
+ float f = getFilterParameter(parameter[mode]);
+
+ Bitmap destBitpmap = Bitmap.createBitmap(tempBitmap.getWidth(),
+ tempBitmap.getHeight(), tempBitmap.getConfig());
+ Allocation outAllocation = Allocation.createFromBitmap(mRS, destBitpmap);
+ performFilter(inAllocation, outAllocation, destBitpmap, f);
+
+ ThumbnailRadioButton button = (ThumbnailRadioButton) findViewById(ids[mode]);
+ button.setThumbnail(destBitpmap);
+ }
+ }
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/ThumbnailRadioButton.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/ThumbnailRadioButton.java
new file mode 100644
index 0000000..160e970
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/java/com/example/android/renderscriptintrinsic/ThumbnailRadioButton.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.renderscriptintrinsic;
+
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.StateListDrawable;
+import android.graphics.drawable.shapes.RectShape;
+import android.os.Build;
+import android.view.Gravity;
+import android.widget.RadioButton;
+import android.content.Context;
+import android.util.AttributeSet;
+
+/*
+ A button with Thumbnail which extends Radio Button.
+ The widget override a background drawable of Radio Button with a StateList Drawable.
+ Each state has a LayerDrawable with a Thumbnail image and a Focus rectangle.
+ It's using original Radio Buttons text as a label, because LayerDrawable showed some issues with Canvas.drawText().
+ */
+public class ThumbnailRadioButton extends RadioButton {
+ public ThumbnailRadioButton(Context context) {
+ super(context);
+ init();
+ }
+
+ public ThumbnailRadioButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public ThumbnailRadioButton(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ private void init() {
+ setButtonDrawable(android.R.color.transparent);
+ }
+
+ public void setThumbnail(Bitmap bitmap) {
+ //Bitmap drawable
+ BitmapDrawable bmp = new BitmapDrawable(getResources(), bitmap);
+ bmp.setGravity(Gravity.CENTER);
+
+ int strokeWidth = 24;
+ //Checked state
+ ShapeDrawable rectChecked = new ShapeDrawable(new RectShape());
+ rectChecked.getPaint().setColor(0xFFFFFFFF);
+ rectChecked.getPaint().setStyle(Paint.Style.STROKE);
+ rectChecked.getPaint().setStrokeWidth(strokeWidth);
+ rectChecked.setIntrinsicWidth(bitmap.getWidth() + strokeWidth);
+ rectChecked.setIntrinsicHeight(bitmap.getHeight() + strokeWidth);
+ Drawable drawableArray[] = new Drawable[]{bmp, rectChecked};
+ LayerDrawable layerChecked = new LayerDrawable(drawableArray);
+
+ //Unchecked state
+ ShapeDrawable rectUnchecked = new ShapeDrawable(new RectShape());
+ rectUnchecked.getPaint().setColor(0x0);
+ rectUnchecked.getPaint().setStyle(Paint.Style.STROKE);
+ rectUnchecked.getPaint().setStrokeWidth(strokeWidth);
+ rectUnchecked.setIntrinsicWidth(bitmap.getWidth() + strokeWidth);
+ rectUnchecked.setIntrinsicHeight(bitmap.getHeight() + strokeWidth);
+ Drawable drawableArray2[] = new Drawable[]{bmp, rectUnchecked};
+ LayerDrawable layerUnchecked = new LayerDrawable(drawableArray2);
+
+ //Statelist drawable
+ StateListDrawable states = new StateListDrawable();
+ states.addState(new int[]{android.R.attr.state_checked},
+ layerChecked);
+ states.addState(new int[]{},
+ layerUnchecked);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
+ setBackground(states);
+ else
+ setBackgroundDrawable(states);
+
+ //Offset text to center/bottom of the checkbox
+ Paint paint = new Paint();
+ paint.setAntiAlias(true);
+ paint.setTextSize(getTextSize());
+ paint.setTypeface(getTypeface());
+ float w = paint.measureText(getText(), 0, getText().length());
+ setPadding(getPaddingLeft() + (int) ((bitmap.getWidth() - w) / 2.f + .5f),
+ getPaddingTop() + (int) (bitmap.getHeight() * 0.70),
+ getPaddingRight(),
+ getPaddingBottom());
+
+ setShadowLayer(5, 0, 0, Color.BLACK);
+ }
+}
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..75b3c97
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..4ccd98e
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-nodpi/data.jpg b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-nodpi/data.jpg
new file mode 100644
index 0000000..48e48e6
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-nodpi/data.jpg
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..7c5aeed
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..3c45f51
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/main_layout.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/main_layout.xml
new file mode 100644
index 0000000..13516d8
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/layout/main_layout.xml
@@ -0,0 +1,51 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#0099cc"
+ tools:context=".MainActivity">
+
+ <ImageView
+ android:id="@+id/imageView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerCrop"
+ android:src="@drawable/data" />
+
+ <RadioGroup
+ android:id="@+id/radioGroup1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:orientation="horizontal"
+ android:layout_above="@+id/seekBar1"
+ android:layout_marginBottom="8dp">
+
+ <com.example.android.renderscriptintrinsic.ThumbnailRadioButton
+ android:id="@+id/radio0"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:checked="true"
+ android:text="Blur" />
+
+ <com.example.android.renderscriptintrinsic.ThumbnailRadioButton
+ android:id="@+id/radio1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Emboss" />
+
+ <com.example.android.renderscriptintrinsic.ThumbnailRadioButton
+ android:id="@+id/radio2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hue" />
+ </RadioGroup>
+
+ <SeekBar
+ android:id="@+id/seekBar1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="16dp" />
+
+</RelativeLayout>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v11/styles.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..f3a90c6
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v11/styles.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+ <style name="FullscreenTheme" parent="android:Theme.Holo">
+ <item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
+ <item name="android:windowActionBarOverlay">true</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
+ <item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
+ </style>
+
+ <style name="FullscreenActionBarStyle" parent="android:Widget.Holo.ActionBar">
+ <item name="android:background">@color/black_overlay</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..a91fd03
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/attrs.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..e67df0a
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/attrs.xml
@@ -0,0 +1,14 @@
+<resources>
+
+ <!--
+ Declare custom theme attributes that allow changing which styles are
+ used for button bars depending on the API level.
+ ?android:attr/buttonBarStyle is new as of API 11 so this is
+ necessary to support previous API levels.
+ -->
+ <declare-styleable name="ButtonBarContainerTheme">
+ <attr name="buttonBarStyle" format="reference" />
+ <attr name="buttonBarButtonStyle" format="reference" />
+ </declare-styleable>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..c8488be
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">RenderScriptIntrinsic</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ RenderScriptIntrinsic sample that demonstrates how to use RenderScript intrinsics.
+ Creates several RenderScript intrinsics and shows a filtering result with various parameters.
+ Also shows how to extends RedioButton with StateListDrawable.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/colors.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/colors.xml
new file mode 100644
index 0000000..327c060
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+<resources>
+
+ <color name="black_overlay">#66000000</color>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/styles.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..12eb930
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/styles.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Light">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <style name="FullscreenTheme" parent="android:Theme.NoTitleBar">
+ <item name="android:windowContentOverlay">@null</item>
+ <item name="android:windowBackground">@null</item>
+ <item name="buttonBarStyle">@style/ButtonBar</item>
+ <item name="buttonBarButtonStyle">@style/ButtonBarButton</item>
+ </style>
+
+ <style name="ButtonBar">
+ <item name="android:paddingLeft">2dp</item>
+ <item name="android:paddingTop">5dp</item>
+ <item name="android:paddingRight">2dp</item>
+ <item name="android:paddingBottom">0dp</item>
+ <item name="android:background">@android:drawable/bottom_bar</item>
+ </style>
+
+ <style name="ButtonBarButton" />
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/AndroidManifest.xml b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..96fa207
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.renderscriptintrinsic.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.renderscriptintrinsic"
+ android:label="Tests for com.example.android.renderscriptintrinsic" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/src/com/example/android/renderscriptintrinsic/tests/SampleTests.java b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/src/com/example/android/renderscriptintrinsic/tests/SampleTests.java
new file mode 100644
index 0000000..c1864f0
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/RenderScriptIntrinsicSample/tests/src/com/example/android/renderscriptintrinsic/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.renderscriptintrinsic.tests;
+
+import com.example.android.renderscriptintrinsic.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for RenderScriptIntrinsic sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private RenderScriptIntrinsicFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (RenderScriptIntrinsicFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/build.gradle b/prebuilts/gradle/RenderScriptIntrinsic/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..5838598
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..0f9e485
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Jan 30 18:12:33 PST 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/gradlew b/prebuilts/gradle/RenderScriptIntrinsic/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/gradlew.bat b/prebuilts/gradle/RenderScriptIntrinsic/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/RenderScriptIntrinsic/settings.gradle b/prebuilts/gradle/RenderScriptIntrinsic/settings.gradle
new file mode 100644
index 0000000..702ca57
--- /dev/null
+++ b/prebuilts/gradle/RenderScriptIntrinsic/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'RenderScriptIntrinsicSample'
diff --git a/prebuilts/gradle/RepeatingAlarm/README.txt b/prebuilts/gradle/RepeatingAlarm/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/build.gradle b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/AndroidManifest.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b7d02e5
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.repeatingalarm"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/MainActivity.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/MainActivity.java
new file mode 100644
index 0000000..2d2a6aa
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.repeatingalarm;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "RepeatingAlarmFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ RepeatingAlarmFragment fragment = new RepeatingAlarmFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/RepeatingAlarmFragment.java b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/RepeatingAlarmFragment.java
new file mode 100644
index 0000000..81b1e44
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/java/com/example/android/repeatingalarm/RepeatingAlarmFragment.java
@@ -0,0 +1,96 @@
+/*
+* Copyright 2013 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.repeatingalarm;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.support.v4.app.Fragment;
+import android.view.MenuItem;
+import com.example.android.common.logger.*;
+
+
+public class RepeatingAlarmFragment extends Fragment {
+
+ // This value is defined and consumed by app code, so any value will work.
+ // There's no significance to this sample using 0.
+ public static final int REQUEST_CODE = 0;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if(item.getItemId() == R.id.sample_action) {
+
+ // BEGIN_INCLUDE (intent_fired_by_alarm)
+ // First create an intent for the alarm to activate.
+ // This code simply starts an Activity, or brings it to the front if it has already
+ // been created.
+ Intent intent = new Intent(getActivity(), MainActivity.class);
+ intent.setAction(Intent.ACTION_MAIN);
+ intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ // END_INCLUDE (intent_fired_by_alarm)
+
+ // BEGIN_INCLUDE (pending_intent_for_alarm)
+ // Because the intent must be fired by a system service from outside the application,
+ // it's necessary to wrap it in a PendingIntent. Providing a different process with
+ // a PendingIntent gives that other process permission to fire the intent that this
+ // application has created.
+ // Also, this code creates a PendingIntent to start an Activity. To create a
+ // BroadcastIntent instead, simply call getBroadcast instead of getIntent.
+ PendingIntent pendingIntent = PendingIntent.getActivity(getActivity(), REQUEST_CODE,
+ intent, 0);
+
+ // END_INCLUDE (pending_intent_for_alarm)
+
+ // BEGIN_INCLUDE (configure_alarm_manager)
+ // There are two clock types for alarms, ELAPSED_REALTIME and RTC.
+ // ELAPSED_REALTIME uses time since system boot as a reference, and RTC uses UTC (wall
+ // clock) time. This means ELAPSED_REALTIME is suited to setting an alarm according to
+ // passage of time (every 15 seconds, 15 minutes, etc), since it isn't affected by
+ // timezone/locale. RTC is better suited for alarms that should be dependant on current
+ // locale.
+
+ // Both types have a WAKEUP version, which says to wake up the device if the screen is
+ // off. This is useful for situations such as alarm clocks. Abuse of this flag is an
+ // efficient way to skyrocket the uninstall rate of an application, so use with care.
+ // For most situations, ELAPSED_REALTIME will suffice.
+ int alarmType = AlarmManager.ELAPSED_REALTIME;
+ final int FIFTEEN_SEC_MILLIS = 15000;
+
+ // The AlarmManager, like most system services, isn't created by application code, but
+ // requested from the system.
+ AlarmManager alarmManager = (AlarmManager)
+ getActivity().getSystemService(getActivity().ALARM_SERVICE);
+
+ // setRepeating takes a start delay and period between alarms as arguments.
+ // The below code fires after 15 seconds, and repeats every 15 seconds. This is very
+ // useful for demonstration purposes, but horrendous for production. Don't be that dev.
+ alarmManager.setRepeating(alarmType, SystemClock.elapsedRealtime() + FIFTEEN_SEC_MILLIS,
+ FIFTEEN_SEC_MILLIS, pendingIntent);
+ // END_INCLUDE (configure_alarm_manager);
+ Log.i("RepeatingAlarmFragment", "Alarm set.");
+ }
+ return true;
+ }
+}
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/menu/main.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..6b89192
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">RepeatingAlarm</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ Introductory text that explains what the sample is intended to demonstrate. Edit
+ in template-params.xml.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/strings.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..2013d95
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Set Alarm</string>
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/RepeatingAlarmSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/RepeatingAlarm/build.gradle b/prebuilts/gradle/RepeatingAlarm/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..56f685a
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/prebuilts/gradle/RepeatingAlarm/gradlew b/prebuilts/gradle/RepeatingAlarm/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/RepeatingAlarm/gradlew.bat b/prebuilts/gradle/RepeatingAlarm/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/RepeatingAlarm/settings.gradle b/prebuilts/gradle/RepeatingAlarm/settings.gradle
new file mode 100644
index 0000000..0f14173
--- /dev/null
+++ b/prebuilts/gradle/RepeatingAlarm/settings.gradle
@@ -0,0 +1 @@
+include 'RepeatingAlarmSample'
diff --git a/prebuilts/gradle/SlidingTabsBasic/README.txt b/prebuilts/gradle/SlidingTabsBasic/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/build.gradle b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/AndroidManifest.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..31cbfb8
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.slidingtabsbasic"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 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.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+ /**
+ * Allows complete control over the colors drawn in the tab layout. Set with
+ * {@link #setCustomTabColorizer(TabColorizer)}.
+ */
+ public interface TabColorizer {
+
+ /**
+ * @return return the color of the indicator used when {@code position} is selected.
+ */
+ int getIndicatorColor(int position);
+
+ /**
+ * @return return the color of the divider drawn to the right of {@code position}.
+ */
+ int getDividerColor(int position);
+
+ }
+
+ private static final int TITLE_OFFSET_DIPS = 24;
+ private static final int TAB_VIEW_PADDING_DIPS = 16;
+ private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+ private int mTitleOffset;
+
+ private int mTabViewLayoutId;
+ private int mTabViewTextViewId;
+
+ private ViewPager mViewPager;
+ private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+ private final SlidingTabStrip mTabStrip;
+
+ public SlidingTabLayout(Context context) {
+ this(context, null);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ // Disable the Scroll Bar
+ setHorizontalScrollBarEnabled(false);
+ // Make sure that the Tab Strips fills this View
+ setFillViewport(true);
+
+ mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+ mTabStrip = new SlidingTabStrip(context);
+ addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ /**
+ * Set the custom {@link TabColorizer} to be used.
+ *
+ * If you only require simple custmisation then you can use
+ * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+ * similar effects.
+ */
+ public void setCustomTabColorizer(TabColorizer tabColorizer) {
+ mTabStrip.setCustomTabColorizer(tabColorizer);
+ }
+
+ /**
+ * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+ * circular array. Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setSelectedIndicatorColors(int... colors) {
+ mTabStrip.setSelectedIndicatorColors(colors);
+ }
+
+ /**
+ * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+ * Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setDividerColors(int... colors) {
+ mTabStrip.setDividerColors(colors);
+ }
+
+ /**
+ * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+ * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+ * that the layout can update it's scroll position correctly.
+ *
+ * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+ */
+ public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ mViewPagerPageChangeListener = listener;
+ }
+
+ /**
+ * Set the custom layout to be inflated for the tab views.
+ *
+ * @param layoutResId Layout id to be inflated
+ * @param textViewId id of the {@link TextView} in the inflated view
+ */
+ public void setCustomTabView(int layoutResId, int textViewId) {
+ mTabViewLayoutId = layoutResId;
+ mTabViewTextViewId = textViewId;
+ }
+
+ /**
+ * Sets the associated view pager. Note that the assumption here is that the pager content
+ * (number of tabs and tab titles) does not change after this call has been made.
+ */
+ public void setViewPager(ViewPager viewPager) {
+ mTabStrip.removeAllViews();
+
+ mViewPager = viewPager;
+ if (viewPager != null) {
+ viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+ populateTabStrip();
+ }
+ }
+
+ /**
+ * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+ * {@link #setCustomTabView(int, int)}.
+ */
+ protected TextView createDefaultTabView(Context context) {
+ TextView textView = new TextView(context);
+ textView.setGravity(Gravity.CENTER);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+ textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // If we're running on Honeycomb or newer, then we can use the Theme's
+ // selectableItemBackground to ensure that the View has a pressed state
+ TypedValue outValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true);
+ textView.setBackgroundResource(outValue.resourceId);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+ textView.setAllCaps(true);
+ }
+
+ int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+ textView.setPadding(padding, padding, padding, padding);
+
+ return textView;
+ }
+
+ private void populateTabStrip() {
+ final PagerAdapter adapter = mViewPager.getAdapter();
+ final View.OnClickListener tabClickListener = new TabClickListener();
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View tabView = null;
+ TextView tabTitleView = null;
+
+ if (mTabViewLayoutId != 0) {
+ // If there is a custom tab view layout id set, try and inflate it
+ tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+ false);
+ tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+ }
+
+ if (tabView == null) {
+ tabView = createDefaultTabView(getContext());
+ }
+
+ if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+ tabTitleView = (TextView) tabView;
+ }
+
+ tabTitleView.setText(adapter.getPageTitle(i));
+ tabView.setOnClickListener(tabClickListener);
+
+ mTabStrip.addView(tabView);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mViewPager != null) {
+ scrollToTab(mViewPager.getCurrentItem(), 0);
+ }
+ }
+
+ private void scrollToTab(int tabIndex, int positionOffset) {
+ final int tabStripChildCount = mTabStrip.getChildCount();
+ if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+ return;
+ }
+
+ View selectedChild = mTabStrip.getChildAt(tabIndex);
+ if (selectedChild != null) {
+ int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+ if (tabIndex > 0 || positionOffset > 0) {
+ // If we're not at the first child and are mid-scroll, make sure we obey the offset
+ targetScrollX -= mTitleOffset;
+ }
+
+ scrollTo(targetScrollX, 0);
+ }
+ }
+
+ private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+ private int mScrollState;
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+ View selectedTitle = mTabStrip.getChildAt(position);
+ int extraOffset = (selectedTitle != null)
+ ? (int) (positionOffset * selectedTitle.getWidth())
+ : 0;
+ scrollToTab(position, extraOffset);
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+ positionOffsetPixels);
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ mScrollState = state;
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+ mTabStrip.onViewPagerPageChanged(position, 0f);
+ scrollToTab(position, 0);
+ }
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageSelected(position);
+ }
+ }
+
+ }
+
+ private class TabClickListener implements View.OnClickListener {
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+ if (v == mTabStrip.getChildAt(i)) {
+ mViewPager.setCurrentItem(i);
+ return;
+ }
+ }
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 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.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+ private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+ private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+ private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+ private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+ private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+ private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+ private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+ private final int mBottomBorderThickness;
+ private final Paint mBottomBorderPaint;
+
+ private final int mSelectedIndicatorThickness;
+ private final Paint mSelectedIndicatorPaint;
+
+ private final int mDefaultBottomBorderColor;
+
+ private final Paint mDividerPaint;
+ private final float mDividerHeight;
+
+ private int mSelectedPosition;
+ private float mSelectionOffset;
+
+ private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+ private final SimpleTabColorizer mDefaultTabColorizer;
+
+ SlidingTabStrip(Context context) {
+ this(context, null);
+ }
+
+ SlidingTabStrip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+
+ final float density = getResources().getDisplayMetrics().density;
+
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+ final int themeForegroundColor = outValue.data;
+
+ mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+ DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+ mDefaultTabColorizer = new SimpleTabColorizer();
+ mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+ mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+ DEFAULT_DIVIDER_COLOR_ALPHA));
+
+ mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+ mBottomBorderPaint = new Paint();
+ mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+ mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+ mSelectedIndicatorPaint = new Paint();
+
+ mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+ mDividerPaint = new Paint();
+ mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+ }
+
+ void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+ mCustomTabColorizer = customTabColorizer;
+ invalidate();
+ }
+
+ void setSelectedIndicatorColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setIndicatorColors(colors);
+ invalidate();
+ }
+
+ void setDividerColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setDividerColors(colors);
+ invalidate();
+ }
+
+ void onViewPagerPageChanged(int position, float positionOffset) {
+ mSelectedPosition = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ final int height = getHeight();
+ final int childCount = getChildCount();
+ final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+ final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+ ? mCustomTabColorizer
+ : mDefaultTabColorizer;
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mSelectedPosition);
+ int left = selectedTitle.getLeft();
+ int right = selectedTitle.getRight();
+ int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+ if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+ int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+ if (color != nextColor) {
+ color = blendColors(nextColor, color, mSelectionOffset);
+ }
+
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mSelectedPosition + 1);
+ left = (int) (mSelectionOffset * nextTitle.getLeft() +
+ (1.0f - mSelectionOffset) * left);
+ right = (int) (mSelectionOffset * nextTitle.getRight() +
+ (1.0f - mSelectionOffset) * right);
+ }
+
+ mSelectedIndicatorPaint.setColor(color);
+
+ canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+ height, mSelectedIndicatorPaint);
+ }
+
+ // Thin underline along the entire bottom edge
+ canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+ // Vertical separators between the titles
+ int separatorTop = (height - dividerHeightPx) / 2;
+ for (int i = 0; i < childCount - 1; i++) {
+ View child = getChildAt(i);
+ mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+ canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+ separatorTop + dividerHeightPx, mDividerPaint);
+ }
+ }
+
+ /**
+ * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+ */
+ private static int setColorAlpha(int color, byte alpha) {
+ return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+ }
+
+ /**
+ * Blend {@code color1} and {@code color2} using the given ratio.
+ *
+ * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+ * 0.0 will return {@code color2}.
+ */
+ private static int blendColors(int color1, int color2, float ratio) {
+ final float inverseRation = 1f - ratio;
+ float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+ float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+ float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+ return Color.rgb((int) r, (int) g, (int) b);
+ }
+
+ private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+ private int[] mIndicatorColors;
+ private int[] mDividerColors;
+
+ @Override
+ public final int getIndicatorColor(int position) {
+ return mIndicatorColors[position % mIndicatorColors.length];
+ }
+
+ @Override
+ public final int getDividerColor(int position) {
+ return mDividerColors[position % mDividerColors.length];
+ }
+
+ void setIndicatorColors(int... colors) {
+ mIndicatorColors = colors;
+ }
+
+ void setDividerColors(int... colors) {
+ mDividerColors = colors;
+ }
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/MainActivity.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/MainActivity.java
new file mode 100644
index 0000000..ac405d1
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.slidingtabsbasic;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ SlidingTabsBasicFragment fragment = new SlidingTabsBasicFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/SlidingTabsBasicFragment.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/SlidingTabsBasicFragment.java
new file mode 100644
index 0000000..80f7b10
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/java/com/example/android/slidingtabsbasic/SlidingTabsBasicFragment.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2013 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.slidingtabsbasic;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.view.SlidingTabLayout;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * A basic sample which shows how to use {@link com.example.android.common.view.SlidingTabLayout}
+ * to display a custom {@link ViewPager} title strip which gives continuous feedback to the user
+ * when scrolling.
+ */
+public class SlidingTabsBasicFragment extends Fragment {
+
+ static final String LOG_TAG = "SlidingTabsBasicFragment";
+
+ /**
+ * A custom {@link ViewPager} title strip which looks much like Tabs present in Android v4.0 and
+ * above, but is designed to give continuous feedback to the user when scrolling.
+ */
+ private SlidingTabLayout mSlidingTabLayout;
+
+ /**
+ * A {@link ViewPager} which will be used in conjunction with the {@link SlidingTabLayout} above.
+ */
+ private ViewPager mViewPager;
+
+ /**
+ * Inflates the {@link View} which will be displayed by this {@link Fragment}, from the app's
+ * resources.
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_sample, container, false);
+ }
+
+ // BEGIN_INCLUDE (fragment_onviewcreated)
+ /**
+ * This is called after the {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} has finished.
+ * Here we can pick out the {@link View}s we need to configure from the content view.
+ *
+ * We set the {@link ViewPager}'s adapter to be an instance of {@link SamplePagerAdapter}. The
+ * {@link SlidingTabLayout} is then given the {@link ViewPager} so that it can populate itself.
+ *
+ * @param view View created in {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ // BEGIN_INCLUDE (setup_viewpager)
+ // Get the ViewPager and set it's PagerAdapter so that it can display items
+ mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
+ mViewPager.setAdapter(new SamplePagerAdapter());
+ // END_INCLUDE (setup_viewpager)
+
+ // BEGIN_INCLUDE (setup_slidingtablayout)
+ // Give the SlidingTabLayout the ViewPager, this must be done AFTER the ViewPager has had
+ // it's PagerAdapter set.
+ mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
+ mSlidingTabLayout.setViewPager(mViewPager);
+ // END_INCLUDE (setup_slidingtablayout)
+ }
+ // END_INCLUDE (fragment_onviewcreated)
+
+ /**
+ * The {@link android.support.v4.view.PagerAdapter} used to display pages in this sample.
+ * The individual pages are simple and just display two lines of text. The important section of
+ * this class is the {@link #getPageTitle(int)} method which controls what is displayed in the
+ * {@link SlidingTabLayout}.
+ */
+ class SamplePagerAdapter extends PagerAdapter {
+
+ /**
+ * @return the number of pages to display
+ */
+ @Override
+ public int getCount() {
+ return 10;
+ }
+
+ /**
+ * @return true if the value returned from {@link #instantiateItem(ViewGroup, int)} is the
+ * same object as the {@link View} added to the {@link ViewPager}.
+ */
+ @Override
+ public boolean isViewFromObject(View view, Object o) {
+ return o == view;
+ }
+
+ // BEGIN_INCLUDE (pageradapter_getpagetitle)
+ /**
+ * Return the title of the item at {@code position}. This is important as what this method
+ * returns is what is displayed in the {@link SlidingTabLayout}.
+ * <p>
+ * Here we construct one using the position value, but for real application the title should
+ * refer to the item's contents.
+ */
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return "Item " + (position + 1);
+ }
+ // END_INCLUDE (pageradapter_getpagetitle)
+
+ /**
+ * Instantiate the {@link View} which should be displayed at {@code position}. Here we
+ * inflate a layout from the apps resources and then change the text view to signify the position.
+ */
+ @Override
+ public Object instantiateItem(ViewGroup container, int position) {
+ // Inflate a new layout from our resources
+ View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
+ container, false);
+ // Add the newly created View to the ViewPager
+ container.addView(view);
+
+ // Retrieve a TextView from the inflated View, and update it's text
+ TextView title = (TextView) view.findViewById(R.id.item_title);
+ title.setText(String.valueOf(position + 1));
+
+ Log.i(LOG_TAG, "instantiateItem() [position: " + position + "]");
+
+ // Return the View
+ return view;
+ }
+
+ /**
+ * Destroy the item from the {@link ViewPager}. In our case this is simply removing the
+ * {@link View}.
+ */
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ container.removeView((View) object);
+ Log.i(LOG_TAG, "destroyItem() [position: " + position + "]");
+ }
+
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..53ebb57
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..33aa87a
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6a4ba00
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..c3744cd
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/fragment_sample.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/fragment_sample.xml
new file mode 100644
index 0000000..6ac3690
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/fragment_sample.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.example.android.common.view.SlidingTabLayout
+ android:id="@+id/sliding_tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/viewpager"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:background="@android:color/white"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/pager_item.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/pager_item.xml
new file mode 100644
index 0000000..ce4413f
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/layout/pager_item.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <TextView
+ android:id="@+id/item_subtitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="Page:"/>
+
+ <TextView
+ android:id="@+id/item_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="80sp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/menu/main.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..c7f26bf
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">SlidingTabsBasic</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ A basic sample which shows how to use SlidingTabLayout to display a custom
+ ViewPager title strip which gives continuous feedback to the user when scrolling.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/strings.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/AndroidManifest.xml b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..8d8fa2b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.slidingtabsbasic.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="4"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.slidingtabsbasic"
+ android:label="Tests for com.example.android.slidingtabsbasic" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/src/com/example/android/slidingtabsbasic/tests/SampleTests.java b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/src/com/example/android/slidingtabsbasic/tests/SampleTests.java
new file mode 100644
index 0000000..6ab9c73
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/SlidingTabsBasicSample/tests/src/com/example/android/slidingtabsbasic/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.slidingtabsbasic.tests;
+
+import com.example.android.slidingtabsbasic.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for SlidingTabsBasic sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private SlidingTabsBasicFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (SlidingTabsBasicFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsBasic/build.gradle b/prebuilts/gradle/SlidingTabsBasic/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..42ae065
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Feb 06 10:46:09 GMT 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/prebuilts/gradle/SlidingTabsBasic/gradlew b/prebuilts/gradle/SlidingTabsBasic/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/SlidingTabsBasic/gradlew.bat b/prebuilts/gradle/SlidingTabsBasic/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/SlidingTabsBasic/settings.gradle b/prebuilts/gradle/SlidingTabsBasic/settings.gradle
new file mode 100644
index 0000000..4accfbd
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsBasic/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'SlidingTabsBasicSample'
diff --git a/prebuilts/gradle/SlidingTabsColors/README.txt b/prebuilts/gradle/SlidingTabsColors/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/build.gradle b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/build.gradle
new file mode 100644
index 0000000..c8567d6
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/build.gradle
@@ -0,0 +1,59 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/AndroidManifest.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..be4a43a
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.slidingtabscolors"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java
new file mode 100644
index 0000000..20049e3
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabLayout.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2013 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.common.view;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+/**
+ * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
+ * the user's scroll progress.
+ * <p>
+ * To use the component, simply add it to your view hierarchy. Then in your
+ * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
+ * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
+ * <p>
+ * The colors can be customized in two ways. The first and simplest is to provide an array of colors
+ * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
+ * alternative is via the {@link TabColorizer} interface which provides you complete control over
+ * which color is used for any individual position.
+ * <p>
+ * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
+ * providing the layout ID of your custom layout.
+ */
+public class SlidingTabLayout extends HorizontalScrollView {
+
+ /**
+ * Allows complete control over the colors drawn in the tab layout. Set with
+ * {@link #setCustomTabColorizer(TabColorizer)}.
+ */
+ public interface TabColorizer {
+
+ /**
+ * @return return the color of the indicator used when {@code position} is selected.
+ */
+ int getIndicatorColor(int position);
+
+ /**
+ * @return return the color of the divider drawn to the right of {@code position}.
+ */
+ int getDividerColor(int position);
+
+ }
+
+ private static final int TITLE_OFFSET_DIPS = 24;
+ private static final int TAB_VIEW_PADDING_DIPS = 16;
+ private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
+
+ private int mTitleOffset;
+
+ private int mTabViewLayoutId;
+ private int mTabViewTextViewId;
+
+ private ViewPager mViewPager;
+ private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
+
+ private final SlidingTabStrip mTabStrip;
+
+ public SlidingTabLayout(Context context) {
+ this(context, null);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ // Disable the Scroll Bar
+ setHorizontalScrollBarEnabled(false);
+ // Make sure that the Tab Strips fills this View
+ setFillViewport(true);
+
+ mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
+
+ mTabStrip = new SlidingTabStrip(context);
+ addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+ }
+
+ /**
+ * Set the custom {@link TabColorizer} to be used.
+ *
+ * If you only require simple custmisation then you can use
+ * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
+ * similar effects.
+ */
+ public void setCustomTabColorizer(TabColorizer tabColorizer) {
+ mTabStrip.setCustomTabColorizer(tabColorizer);
+ }
+
+ /**
+ * Sets the colors to be used for indicating the selected tab. These colors are treated as a
+ * circular array. Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setSelectedIndicatorColors(int... colors) {
+ mTabStrip.setSelectedIndicatorColors(colors);
+ }
+
+ /**
+ * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
+ * Providing one color will mean that all tabs are indicated with the same color.
+ */
+ public void setDividerColors(int... colors) {
+ mTabStrip.setDividerColors(colors);
+ }
+
+ /**
+ * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
+ * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
+ * that the layout can update it's scroll position correctly.
+ *
+ * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
+ */
+ public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
+ mViewPagerPageChangeListener = listener;
+ }
+
+ /**
+ * Set the custom layout to be inflated for the tab views.
+ *
+ * @param layoutResId Layout id to be inflated
+ * @param textViewId id of the {@link TextView} in the inflated view
+ */
+ public void setCustomTabView(int layoutResId, int textViewId) {
+ mTabViewLayoutId = layoutResId;
+ mTabViewTextViewId = textViewId;
+ }
+
+ /**
+ * Sets the associated view pager. Note that the assumption here is that the pager content
+ * (number of tabs and tab titles) does not change after this call has been made.
+ */
+ public void setViewPager(ViewPager viewPager) {
+ mTabStrip.removeAllViews();
+
+ mViewPager = viewPager;
+ if (viewPager != null) {
+ viewPager.setOnPageChangeListener(new InternalViewPagerListener());
+ populateTabStrip();
+ }
+ }
+
+ /**
+ * Create a default view to be used for tabs. This is called if a custom tab view is not set via
+ * {@link #setCustomTabView(int, int)}.
+ */
+ protected TextView createDefaultTabView(Context context) {
+ TextView textView = new TextView(context);
+ textView.setGravity(Gravity.CENTER);
+ textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
+ textView.setTypeface(Typeface.DEFAULT_BOLD);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ // If we're running on Honeycomb or newer, then we can use the Theme's
+ // selectableItemBackground to ensure that the View has a pressed state
+ TypedValue outValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
+ outValue, true);
+ textView.setBackgroundResource(outValue.resourceId);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
+ textView.setAllCaps(true);
+ }
+
+ int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
+ textView.setPadding(padding, padding, padding, padding);
+
+ return textView;
+ }
+
+ private void populateTabStrip() {
+ final PagerAdapter adapter = mViewPager.getAdapter();
+ final View.OnClickListener tabClickListener = new TabClickListener();
+
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View tabView = null;
+ TextView tabTitleView = null;
+
+ if (mTabViewLayoutId != 0) {
+ // If there is a custom tab view layout id set, try and inflate it
+ tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
+ false);
+ tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
+ }
+
+ if (tabView == null) {
+ tabView = createDefaultTabView(getContext());
+ }
+
+ if (tabTitleView == null && TextView.class.isInstance(tabView)) {
+ tabTitleView = (TextView) tabView;
+ }
+
+ tabTitleView.setText(adapter.getPageTitle(i));
+ tabView.setOnClickListener(tabClickListener);
+
+ mTabStrip.addView(tabView);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (mViewPager != null) {
+ scrollToTab(mViewPager.getCurrentItem(), 0);
+ }
+ }
+
+ private void scrollToTab(int tabIndex, int positionOffset) {
+ final int tabStripChildCount = mTabStrip.getChildCount();
+ if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
+ return;
+ }
+
+ View selectedChild = mTabStrip.getChildAt(tabIndex);
+ if (selectedChild != null) {
+ int targetScrollX = selectedChild.getLeft() + positionOffset;
+
+ if (tabIndex > 0 || positionOffset > 0) {
+ // If we're not at the first child and are mid-scroll, make sure we obey the offset
+ targetScrollX -= mTitleOffset;
+ }
+
+ scrollTo(targetScrollX, 0);
+ }
+ }
+
+ private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
+ private int mScrollState;
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ int tabStripChildCount = mTabStrip.getChildCount();
+ if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
+ return;
+ }
+
+ mTabStrip.onViewPagerPageChanged(position, positionOffset);
+
+ View selectedTitle = mTabStrip.getChildAt(position);
+ int extraOffset = (selectedTitle != null)
+ ? (int) (positionOffset * selectedTitle.getWidth())
+ : 0;
+ scrollToTab(position, extraOffset);
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
+ positionOffsetPixels);
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+ mScrollState = state;
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageScrollStateChanged(state);
+ }
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+ if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
+ mTabStrip.onViewPagerPageChanged(position, 0f);
+ scrollToTab(position, 0);
+ }
+
+ if (mViewPagerPageChangeListener != null) {
+ mViewPagerPageChangeListener.onPageSelected(position);
+ }
+ }
+
+ }
+
+ private class TabClickListener implements View.OnClickListener {
+ @Override
+ public void onClick(View v) {
+ for (int i = 0; i < mTabStrip.getChildCount(); i++) {
+ if (v == mTabStrip.getChildAt(i)) {
+ mViewPager.setCurrentItem(i);
+ return;
+ }
+ }
+ }
+ }
+
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java
new file mode 100644
index 0000000..d5bbbae
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/common/view/SlidingTabStrip.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 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.common.view;
+
+import android.R;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.View;
+import android.widget.LinearLayout;
+
+class SlidingTabStrip extends LinearLayout {
+
+ private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2;
+ private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26;
+ private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8;
+ private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5;
+
+ private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1;
+ private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20;
+ private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f;
+
+ private final int mBottomBorderThickness;
+ private final Paint mBottomBorderPaint;
+
+ private final int mSelectedIndicatorThickness;
+ private final Paint mSelectedIndicatorPaint;
+
+ private final int mDefaultBottomBorderColor;
+
+ private final Paint mDividerPaint;
+ private final float mDividerHeight;
+
+ private int mSelectedPosition;
+ private float mSelectionOffset;
+
+ private SlidingTabLayout.TabColorizer mCustomTabColorizer;
+ private final SimpleTabColorizer mDefaultTabColorizer;
+
+ SlidingTabStrip(Context context) {
+ this(context, null);
+ }
+
+ SlidingTabStrip(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+
+ final float density = getResources().getDisplayMetrics().density;
+
+ TypedValue outValue = new TypedValue();
+ context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, true);
+ final int themeForegroundColor = outValue.data;
+
+ mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor,
+ DEFAULT_BOTTOM_BORDER_COLOR_ALPHA);
+
+ mDefaultTabColorizer = new SimpleTabColorizer();
+ mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR);
+ mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor,
+ DEFAULT_DIVIDER_COLOR_ALPHA));
+
+ mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density);
+ mBottomBorderPaint = new Paint();
+ mBottomBorderPaint.setColor(mDefaultBottomBorderColor);
+
+ mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density);
+ mSelectedIndicatorPaint = new Paint();
+
+ mDividerHeight = DEFAULT_DIVIDER_HEIGHT;
+ mDividerPaint = new Paint();
+ mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density));
+ }
+
+ void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) {
+ mCustomTabColorizer = customTabColorizer;
+ invalidate();
+ }
+
+ void setSelectedIndicatorColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setIndicatorColors(colors);
+ invalidate();
+ }
+
+ void setDividerColors(int... colors) {
+ // Make sure that the custom colorizer is removed
+ mCustomTabColorizer = null;
+ mDefaultTabColorizer.setDividerColors(colors);
+ invalidate();
+ }
+
+ void onViewPagerPageChanged(int position, float positionOffset) {
+ mSelectedPosition = position;
+ mSelectionOffset = positionOffset;
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ final int height = getHeight();
+ final int childCount = getChildCount();
+ final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);
+ final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null
+ ? mCustomTabColorizer
+ : mDefaultTabColorizer;
+
+ // Thick colored underline below the current selection
+ if (childCount > 0) {
+ View selectedTitle = getChildAt(mSelectedPosition);
+ int left = selectedTitle.getLeft();
+ int right = selectedTitle.getRight();
+ int color = tabColorizer.getIndicatorColor(mSelectedPosition);
+
+ if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {
+ int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);
+ if (color != nextColor) {
+ color = blendColors(nextColor, color, mSelectionOffset);
+ }
+
+ // Draw the selection partway between the tabs
+ View nextTitle = getChildAt(mSelectedPosition + 1);
+ left = (int) (mSelectionOffset * nextTitle.getLeft() +
+ (1.0f - mSelectionOffset) * left);
+ right = (int) (mSelectionOffset * nextTitle.getRight() +
+ (1.0f - mSelectionOffset) * right);
+ }
+
+ mSelectedIndicatorPaint.setColor(color);
+
+ canvas.drawRect(left, height - mSelectedIndicatorThickness, right,
+ height, mSelectedIndicatorPaint);
+ }
+
+ // Thin underline along the entire bottom edge
+ canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);
+
+ // Vertical separators between the titles
+ int separatorTop = (height - dividerHeightPx) / 2;
+ for (int i = 0; i < childCount - 1; i++) {
+ View child = getChildAt(i);
+ mDividerPaint.setColor(tabColorizer.getDividerColor(i));
+ canvas.drawLine(child.getRight(), separatorTop, child.getRight(),
+ separatorTop + dividerHeightPx, mDividerPaint);
+ }
+ }
+
+ /**
+ * Set the alpha value of the {@code color} to be the given {@code alpha} value.
+ */
+ private static int setColorAlpha(int color, byte alpha) {
+ return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
+ }
+
+ /**
+ * Blend {@code color1} and {@code color2} using the given ratio.
+ *
+ * @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
+ * 0.0 will return {@code color2}.
+ */
+ private static int blendColors(int color1, int color2, float ratio) {
+ final float inverseRation = 1f - ratio;
+ float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
+ float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
+ float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
+ return Color.rgb((int) r, (int) g, (int) b);
+ }
+
+ private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {
+ private int[] mIndicatorColors;
+ private int[] mDividerColors;
+
+ @Override
+ public final int getIndicatorColor(int position) {
+ return mIndicatorColors[position % mIndicatorColors.length];
+ }
+
+ @Override
+ public final int getDividerColor(int position) {
+ return mDividerColors[position % mDividerColors.length];
+ }
+
+ void setIndicatorColors(int... colors) {
+ mIndicatorColors = colors;
+ }
+
+ void setDividerColors(int... colors) {
+ mDividerColors = colors;
+ }
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/ContentFragment.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/ContentFragment.java
new file mode 100644
index 0000000..4715fd7
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/ContentFragment.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013 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.slidingtabscolors;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+/**
+ * Simple Fragment used to display some meaningful content for each page in the sample's
+ * {@link android.support.v4.view.ViewPager}.
+ */
+public class ContentFragment extends Fragment {
+
+ private static final String KEY_TITLE = "title";
+ private static final String KEY_INDICATOR_COLOR = "indicator_color";
+ private static final String KEY_DIVIDER_COLOR = "divider_color";
+
+ /**
+ * @return a new instance of {@link ContentFragment}, adding the parameters into a bundle and
+ * setting them as arguments.
+ */
+ public static ContentFragment newInstance(CharSequence title, int indicatorColor,
+ int dividerColor) {
+ Bundle bundle = new Bundle();
+ bundle.putCharSequence(KEY_TITLE, title);
+ bundle.putInt(KEY_INDICATOR_COLOR, indicatorColor);
+ bundle.putInt(KEY_DIVIDER_COLOR, dividerColor);
+
+ ContentFragment fragment = new ContentFragment();
+ fragment.setArguments(bundle);
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.pager_item, container, false);
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ Bundle args = getArguments();
+
+ if (args != null) {
+ TextView title = (TextView) view.findViewById(R.id.item_title);
+ title.setText("Title: " + args.getCharSequence(KEY_TITLE));
+
+ int indicatorColor = args.getInt(KEY_INDICATOR_COLOR);
+ TextView indicatorColorView = (TextView) view.findViewById(R.id.item_indicator_color);
+ indicatorColorView.setText("Indicator: #" + Integer.toHexString(indicatorColor));
+ indicatorColorView.setTextColor(indicatorColor);
+
+ int dividerColor = args.getInt(KEY_DIVIDER_COLOR);
+ TextView dividerColorView = (TextView) view.findViewById(R.id.item_divider_color);
+ dividerColorView.setText("Divider: #" + Integer.toHexString(dividerColor));
+ dividerColorView.setTextColor(dividerColor);
+ }
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/MainActivity.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/MainActivity.java
new file mode 100644
index 0000000..d3d7567
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/MainActivity.java
@@ -0,0 +1,110 @@
+/*
+* Copyright 2013 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.slidingtabscolors;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.ViewAnimator;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description, sample log and a custom
+ * {@link android.support.v4.app.Fragment} which can display a view.
+ * <p>
+ * For devices with displays with a width of 720dp or greater, the sample log is always visible,
+ * on other devices it's visibility is controlled by an item on the Action Bar.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ // Whether the Log Fragment is currently shown
+ private boolean mLogShown;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ SlidingTabsColorsFragment fragment = new SlidingTabsColorsFragment();
+ transaction.replace(R.id.sample_content_fragment, fragment);
+ transaction.commit();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
+ logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
+ logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
+
+ return super.onPrepareOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case R.id.menu_toggle_log:
+ mLogShown = !mLogShown;
+ ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
+ if (mLogShown) {
+ output.setDisplayedChild(1);
+ } else {
+ output.setDisplayedChild(0);
+ }
+ supportInvalidateOptionsMenu();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/SlidingTabsColorsFragment.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/SlidingTabsColorsFragment.java
new file mode 100644
index 0000000..1e5c3e3
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/java/com/example/android/slidingtabscolors/SlidingTabsColorsFragment.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2013 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.slidingtabscolors;
+
+import com.example.android.common.view.SlidingTabLayout;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.view.ViewPager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A basic sample which shows how to use {@link com.example.android.common.view.SlidingTabLayout}
+ * to display a custom {@link ViewPager} title strip which gives continuous feedback to the user
+ * when scrolling.
+ */
+public class SlidingTabsColorsFragment extends Fragment {
+
+ /**
+ * This class represents a tab to be displayed by {@link ViewPager} and it's associated
+ * {@link SlidingTabLayout}.
+ */
+ static class SamplePagerItem {
+ private final CharSequence mTitle;
+ private final int mIndicatorColor;
+ private final int mDividerColor;
+
+ SamplePagerItem(CharSequence title, int indicatorColor, int dividerColor) {
+ mTitle = title;
+ mIndicatorColor = indicatorColor;
+ mDividerColor = dividerColor;
+ }
+
+ /**
+ * @return A new {@link Fragment} to be displayed by a {@link ViewPager}
+ */
+ Fragment createFragment() {
+ return ContentFragment.newInstance(mTitle, mIndicatorColor, mDividerColor);
+ }
+
+ /**
+ * @return the title which represents this tab. In this sample this is used directly by
+ * {@link android.support.v4.view.PagerAdapter#getPageTitle(int)}
+ */
+ CharSequence getTitle() {
+ return mTitle;
+ }
+
+ /**
+ * @return the color to be used for indicator on the {@link SlidingTabLayout}
+ */
+ int getIndicatorColor() {
+ return mIndicatorColor;
+ }
+
+ /**
+ * @return the color to be used for right divider on the {@link SlidingTabLayout}
+ */
+ int getDividerColor() {
+ return mDividerColor;
+ }
+ }
+
+ static final String LOG_TAG = "SlidingTabsColorsFragment";
+
+ /**
+ * A custom {@link ViewPager} title strip which looks much like Tabs present in Android v4.0 and
+ * above, but is designed to give continuous feedback to the user when scrolling.
+ */
+ private SlidingTabLayout mSlidingTabLayout;
+
+ /**
+ * A {@link ViewPager} which will be used in conjunction with the {@link SlidingTabLayout} above.
+ */
+ private ViewPager mViewPager;
+
+ /**
+ * List of {@link SamplePagerItem} which represent this sample's tabs.
+ */
+ private List<SamplePagerItem> mTabs = new ArrayList<SamplePagerItem>();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // BEGIN_INCLUDE (populate_tabs)
+ /**
+ * Populate our tab list with tabs. Each item contains a title, indicator color and divider
+ * color, which are used by {@link SlidingTabLayout}.
+ */
+ mTabs.add(new SamplePagerItem(
+ getString(R.string.tab_stream), // Title
+ Color.BLUE, // Indicator color
+ Color.GRAY // Divider color
+ ));
+
+ mTabs.add(new SamplePagerItem(
+ getString(R.string.tab_messages), // Title
+ Color.RED, // Indicator color
+ Color.GRAY // Divider color
+ ));
+
+ mTabs.add(new SamplePagerItem(
+ getString(R.string.tab_photos), // Title
+ Color.YELLOW, // Indicator color
+ Color.GRAY // Divider color
+ ));
+
+ mTabs.add(new SamplePagerItem(
+ getString(R.string.tab_notifications), // Title
+ Color.GREEN, // Indicator color
+ Color.GRAY // Divider color
+ ));
+ // END_INCLUDE (populate_tabs)
+ }
+
+ /**
+ * Inflates the {@link View} which will be displayed by this {@link Fragment}, from the app's
+ * resources.
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_sample, container, false);
+ }
+
+ // BEGIN_INCLUDE (fragment_onviewcreated)
+ /**
+ * This is called after the {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} has finished.
+ * Here we can pick out the {@link View}s we need to configure from the content view.
+ *
+ * We set the {@link ViewPager}'s adapter to be an instance of
+ * {@link SampleFragmentPagerAdapter}. The {@link SlidingTabLayout} is then given the
+ * {@link ViewPager} so that it can populate itself.
+ *
+ * @param view View created in {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ // BEGIN_INCLUDE (setup_viewpager)
+ // Get the ViewPager and set it's PagerAdapter so that it can display items
+ mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
+ mViewPager.setAdapter(new SampleFragmentPagerAdapter(getChildFragmentManager()));
+ // END_INCLUDE (setup_viewpager)
+
+ // BEGIN_INCLUDE (setup_slidingtablayout)
+ // Give the SlidingTabLayout the ViewPager, this must be done AFTER the ViewPager has had
+ // it's PagerAdapter set.
+ mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
+ mSlidingTabLayout.setViewPager(mViewPager);
+
+ // BEGIN_INCLUDE (tab_colorizer)
+ // Set a TabColorizer to customize the indicator and divider colors. Here we just retrieve
+ // the tab at the position, and return it's set color
+ mSlidingTabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
+
+ @Override
+ public int getIndicatorColor(int position) {
+ return mTabs.get(position).getIndicatorColor();
+ }
+
+ @Override
+ public int getDividerColor(int position) {
+ return mTabs.get(position).getDividerColor();
+ }
+
+ });
+ // END_INCLUDE (tab_colorizer)
+ // END_INCLUDE (setup_slidingtablayout)
+ }
+ // END_INCLUDE (fragment_onviewcreated)
+
+ /**
+ * The {@link FragmentPagerAdapter} used to display pages in this sample. The individual pages
+ * are instances of {@link ContentFragment} which just display three lines of text. Each page is
+ * created by the relevant {@link SamplePagerItem} for the requested position.
+ * <p>
+ * The important section of this class is the {@link #getPageTitle(int)} method which controls
+ * what is displayed in the {@link SlidingTabLayout}.
+ */
+ class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
+
+ SampleFragmentPagerAdapter(FragmentManager fm) {
+ super(fm);
+ }
+
+ /**
+ * Return the {@link android.support.v4.app.Fragment} to be displayed at {@code position}.
+ * <p>
+ * Here we return the value returned from {@link SamplePagerItem#createFragment()}.
+ */
+ @Override
+ public Fragment getItem(int i) {
+ return mTabs.get(i).createFragment();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ // BEGIN_INCLUDE (pageradapter_getpagetitle)
+ /**
+ * Return the title of the item at {@code position}. This is important as what this method
+ * returns is what is displayed in the {@link SlidingTabLayout}.
+ * <p>
+ * Here we return the value returned from {@link SamplePagerItem#getTitle()}.
+ */
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return mTabs.get(position).getTitle();
+ }
+ // END_INCLUDE (pageradapter_getpagetitle)
+
+ }
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..66542ee
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..56e4726
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..ba41664
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..c9a51f6
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout-w720dp/activity_main.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout-w720dp/activity_main.xml
new file mode 100755
index 0000000..c9a52f6
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout-w720dp/activity_main.xml
@@ -0,0 +1,73 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <LinearLayout
+ android:id="@+id/sample_output"
+ android:layout_width="0px"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <FrameLayout
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/margin_medium"
+ android:paddingRight="@dimen/margin_medium"
+ android:paddingTop="@dimen/margin_large"
+ android:paddingBottom="@dimen/margin_large"
+ android:text="@string/intro_message" />
+ </FrameLayout>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+ <View
+ android:layout_width="1dp"
+ android:layout_height="match_parent"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="0px"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
+
+
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..1ae4f98
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,65 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/sample_main_layout">
+
+ <ViewAnimator
+ android:id="@+id/sample_output"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1">
+
+ <ScrollView
+ style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/horizontal_page_margin"
+ android:paddingRight="@dimen/horizontal_page_margin"
+ android:paddingTop="@dimen/vertical_page_margin"
+ android:paddingBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </ScrollView>
+
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </ViewAnimator>
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray" />
+
+ <FrameLayout
+ android:id="@+id/sample_content_fragment"
+ android:layout_weight="2"
+ android:layout_width="match_parent"
+ android:layout_height="0px" />
+
+</LinearLayout>
+
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/fragment_sample.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/fragment_sample.xml
new file mode 100644
index 0000000..605cba7
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/fragment_sample.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <com.example.android.common.view.SlidingTabLayout
+ android:id="@+id/sliding_tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <android.support.v4.view.ViewPager
+ android:id="@+id/viewpager"
+ android:layout_width="match_parent"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:background="@android:color/white" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/pager_item.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/pager_item.xml
new file mode 100644
index 0000000..039ceb1
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/layout/pager_item.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <TextView
+ android:id="@+id/item_title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:id="@+id/item_indicator_color"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <TextView
+ android:id="@+id/item_divider_color"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/menu/main.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..b49c2c5
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/menu_toggle_log"
+ android:showAsAction="always"
+ android:title="@string/sample_show_log" />
+</menu>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..89cac2d
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">SlidingTabsColors</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ A more advanced sample which shows how to use SlidingTabLayout to display a custom
+ ViewPager title strip, with custom coloring for each tab.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/strings.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/strings.xml
new file mode 100755
index 0000000..7b9d9ec
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+ Copyright 2013 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.
+-->
+<resources>
+ <string name="sample_show_log">Show Log</string>
+ <string name="sample_hide_log">Hide Log</string>
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/AndroidManifest.xml b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..f9fcf3e
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.slidingtabscolors.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="4"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.slidingtabscolors"
+ android:label="Tests for com.example.android.slidingtabscolors" />
+
+</manifest>
diff --git a/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/src/com/example/android/slidingtabscolors/tests/SampleTests.java b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/src/com/example/android/slidingtabscolors/tests/SampleTests.java
new file mode 100644
index 0000000..caab5d8
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/SlidingTabsColorsSample/tests/src/com/example/android/slidingtabscolors/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.slidingtabscolors.tests;
+
+import com.example.android.slidingtabscolors.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for SlidingTabsColors sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private SlidingTabsColorsFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (SlidingTabsColorsFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/SlidingTabsColors/build.gradle b/prebuilts/gradle/SlidingTabsColors/build.gradle
new file mode 100644
index 0000000..5cf5d3d
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/build.gradle
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..2ea0b84
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Feb 06 11:07:10 GMT 2014
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip
diff --git a/prebuilts/gradle/SlidingTabsColors/gradlew b/prebuilts/gradle/SlidingTabsColors/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/SlidingTabsColors/gradlew.bat b/prebuilts/gradle/SlidingTabsColors/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/SlidingTabsColors/settings.gradle b/prebuilts/gradle/SlidingTabsColors/settings.gradle
new file mode 100644
index 0000000..3c5586a
--- /dev/null
+++ b/prebuilts/gradle/SlidingTabsColors/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'SlidingTabsColorsSample'
diff --git a/prebuilts/gradle/StorageClient/README.txt b/prebuilts/gradle/StorageClient/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/build.gradle b/prebuilts/gradle/StorageClient/StorageClientSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/AndroidManifest.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..d35a4ec
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.storageclient"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19" />
+
+ <application android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/AppTheme">
+
+ <activity android:name=".MainActivity"
+ android:label="@string/app_name"
+ android:uiOptions="splitActionBarWhenNarrow">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+
+</manifest>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/MainActivity.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/MainActivity.java
new file mode 100644
index 0000000..69c75eb
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.storageclient;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "StorageClientFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ StorageClientFragment fragment = new StorageClientFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/StorageClientFragment.java b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/StorageClientFragment.java
new file mode 100644
index 0000000..7f9f73e
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/java/com/example/android/storageclient/StorageClientFragment.java
@@ -0,0 +1,255 @@
+/*
+* Copyright (C) 2012 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.storageclient;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.OpenableColumns;
+import android.support.v4.app.DialogFragment;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.view.MenuItem;
+import android.view.Window;
+import android.widget.ImageView;
+
+import com.example.android.common.logger.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+public class StorageClientFragment extends Fragment {
+
+ // A request code's purpose is to match the result of a "startActivityForResult" with
+ // the type of the original request. Choose any value.
+ private static final int READ_REQUEST_CODE = 1337;
+
+ public static final String TAG = "StorageClientFragment";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ performFileSearch();
+ }
+ return true;
+ }
+
+ /**
+ * Fires an intent to spin up the "file chooser" UI and select an image.
+ */
+ public void performFileSearch() {
+
+ // BEGIN_INCLUDE (use_open_document_intent)
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file browser.
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+ // Filter to only show results that can be "opened", such as a file (as opposed to a list
+ // of contacts or timezones)
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Filter to show only images, using the image MIME data type.
+ // If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
+ // To search for all documents available via installed storage providers, it would be
+ // "*/*".
+ intent.setType("image/*");
+
+ startActivityForResult(intent, READ_REQUEST_CODE);
+ // END_INCLUDE (use_open_document_intent)
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
+ Log.i(TAG, "Received an \"Activity Result\"");
+ // BEGIN_INCLUDE (parse_open_document_response)
+ // The ACTION_OPEN_DOCUMENT intent was sent with the request code READ_REQUEST_CODE.
+ // If the request code seen here doesn't match, it's the response to some other intent,
+ // and the below code shouldn't run at all.
+
+ if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ // The document selected by the user won't be returned in the intent.
+ // Instead, a URI to that document will be contained in the return intent
+ // provided to this method as a parameter. Pull that uri using "resultData.getData()"
+ Uri uri = null;
+ if (resultData != null) {
+ uri = resultData.getData();
+ Log.i(TAG, "Uri: " + uri.toString());
+ showImage(uri);
+ }
+ // END_INCLUDE (parse_open_document_response)
+ }
+ }
+
+ /**
+ * Given the URI of an image, shows it on the screen using a DialogFragment.
+ *
+ * @param uri the Uri of the image to display.
+ */
+ public void showImage(Uri uri) {
+ // BEGIN_INCLUDE (create_show_image_dialog)
+ if (uri != null) {
+ // Since the URI is to an image, create and show a DialogFragment to display the
+ // image to the user.
+ FragmentManager fm = getActivity().getSupportFragmentManager();
+ ImageDialogFragment imageDialog = new ImageDialogFragment(uri);
+ imageDialog.show(fm, "image_dialog");
+ }
+ // END_INCLUDE (create_show_image_dialog)
+ }
+
+ /**
+ * Grabs metadata for a document specified by URI, logs it to the screen.
+ *
+ * @param uri The uri for the document whose metadata should be printed.
+ */
+ public void dumpImageMetaData(Uri uri) {
+ // BEGIN_INCLUDE (dump_metadata)
+
+ // The query, since it only applies to a single document, will only return one row.
+ // no need to filter, sort, or select fields, since we want all fields for one
+ // document.
+ Cursor cursor = getActivity().getContentResolver()
+ .query(uri, null, null, null, null, null);
+
+ try {
+ // moveToFirst() returns false if the cursor has 0 rows. Very handy for
+ // "if there's anything to look at, look at it" conditionals.
+ if (cursor != null && cursor.moveToFirst()) {
+
+ // Note it's called "Display Name". This is provider-specific, and
+ // might not necessarily be the file name.
+ String displayName = cursor.getString(
+ cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
+ Log.i(TAG, "Display Name: " + displayName);
+
+ int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
+ // If the size is unknown, the value stored is null. But since an int can't be
+ // null in java, the behavior is implementation-specific, which is just a fancy
+ // term for "unpredictable". So as a rule, check if it's null before assigning
+ // to an int. This will happen often: The storage API allows for remote
+ // files, whose size might not be locally known.
+ String size = null;
+ if (!cursor.isNull(sizeIndex)) {
+ // Technically the column stores an int, but cursor.getString will do the
+ // conversion automatically.
+ size = cursor.getString(sizeIndex);
+ } else {
+ size = "Unknown";
+ }
+ Log.i(TAG, "Size: " + size);
+ }
+ } finally {
+ cursor.close();
+ }
+ // END_INCLUDE (dump_metadata)
+ }
+
+ /**
+ * DialogFragment which displays an image, given a URI.
+ */
+ private class ImageDialogFragment extends DialogFragment {
+ private Dialog mDialog;
+ private Uri mUri;
+
+ public ImageDialogFragment(Uri uri) {
+ super();
+ mUri = uri;
+ }
+
+ /** Create a Bitmap from the URI for that image and return it.
+ *
+ * @param uri the Uri for the image to return.
+ */
+ private Bitmap getBitmapFromUri(Uri uri) {
+ ParcelFileDescriptor parcelFileDescriptor = null;
+ try {
+ parcelFileDescriptor =
+ getActivity().getContentResolver().openFileDescriptor(uri, "r");
+ FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
+ Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
+ parcelFileDescriptor.close();
+ return image;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to load image.", e);
+ return null;
+ } finally {
+ try {
+ if (parcelFileDescriptor != null) {
+ parcelFileDescriptor.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ Log.e(TAG, "Error closing ParcelFile Descriptor");
+ }
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mDialog = super.onCreateDialog(savedInstanceState);
+ // To optimize for the "lightbox" style layout. Since we're not actually displaying a
+ // title, remove the bar along the top of the fragment where a dialog title would
+ // normally go.
+ mDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
+ final ImageView imageView = new ImageView(getActivity());
+ mDialog.setContentView(imageView);
+
+ // BEGIN_INCLUDE (show_image)
+ // Loading the image is going to require some sort of I/O, which must occur off the UI
+ // thread. Changing the ImageView to display the image must occur ON the UI thread.
+ // The easiest way to divide up this labor is with an AsyncTask. The doInBackground
+ // method will run in a separate thread, but onPostExecute will run in the main
+ // UI thread.
+ AsyncTask<Uri, Void, Bitmap> imageLoadAsyncTask = new AsyncTask<Uri, Void, Bitmap>() {
+ @Override
+ protected Bitmap doInBackground(Uri... uris) {
+ dumpImageMetaData(uris[0]);
+ return getBitmapFromUri(uris[0]);
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ imageView.setImageBitmap(bitmap);
+ }
+ };
+ imageLoadAsyncTask.execute(mUri);
+ // END_INCLUDE (show_image)
+
+ return mDialog;
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (getDialog() != null) {
+ getDialog().dismiss();
+ }
+ }
+ }
+}
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..b1efaf4
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f5f9244
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..5d07b3f
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6ef21e1
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/menu/main.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..9498a2d
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">StorageClient</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ Using the OPEN_DOCUMENT intent, a client app can access a list of Document Providers
+ on the device, and choose a file from any of them.
+ \n\nTo demonstrate this, click the button below to open up the Storage Access Framework
+ interface, and choose an image on your device. It will be displayed in this app.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/strings.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..303776f
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Show Me The Image</string>
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/tests/AndroidManifest.xml b/prebuilts/gradle/StorageClient/StorageClientSample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..3f0a38f
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.storageclient.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.storageclient"
+ android:label="Tests for com.example.android.storageclient" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageClient/StorageClientSample/tests/src/com/example/android/storageclient/tests/SampleTests.java b/prebuilts/gradle/StorageClient/StorageClientSample/tests/src/com/example/android/storageclient/tests/SampleTests.java
new file mode 100644
index 0000000..5ed779a
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/StorageClientSample/tests/src/com/example/android/storageclient/tests/SampleTests.java
@@ -0,0 +1,81 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+* Copyright (C) 2013 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.storageclient.tests;
+
+import com.example.android.storageclient.*;
+
+import android.net.Uri;
+import android.support.v4.app.FragmentManager;
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for StorageClient sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private StorageClientFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (StorageClientFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Test if the metadata dump handles an invalid URI without blowing up.
+ */
+ public void testDumpMetadataInvalidUri() {
+ Uri uri = Uri.parse("content://HAHADOESNTEXIST");
+ mTestFragment.dumpImageMetaData(uri);
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageClient/build.gradle b/prebuilts/gradle/StorageClient/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/StorageClient/gradlew b/prebuilts/gradle/StorageClient/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/StorageClient/gradlew.bat b/prebuilts/gradle/StorageClient/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/StorageClient/settings.gradle b/prebuilts/gradle/StorageClient/settings.gradle
new file mode 100644
index 0000000..73cfad8
--- /dev/null
+++ b/prebuilts/gradle/StorageClient/settings.gradle
@@ -0,0 +1 @@
+include 'StorageClientSample'
diff --git a/prebuilts/gradle/StorageProvider/README.txt b/prebuilts/gradle/StorageProvider/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/build.gradle b/prebuilts/gradle/StorageProvider/StorageProviderSample/build.gradle
new file mode 100644
index 0000000..f73b206
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 19
+ compile "com.android.support:support-v13:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/AndroidManifest.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e4704dc
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/AndroidManifest.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.storageprovider"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19"/>
+
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+ <application
+ android:allowBackup="true"
+ android:label="@string/app_name"
+ android:icon="@drawable/ic_launcher"
+ android:theme="@style/MyAppTheme">
+
+ <activity
+ android:name=".MainActivity"
+ android:uiOptions="splitActionBarWhenNarrow"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <!--BEGIN_INCLUDE(provider_manifest)-->
+ <!--
+ Declare the document provider class MyCloudProvider to the system. The MANAGE_DOCUMENTS
+ permission belongs only to the Android system, ensuring this provider will never be used
+ directly by another app. The provider must grant URI permissions in order to expose the
+ specific documents(s) chosen, while not sharing all of its data by default. It must be
+ exported to be visible outside the application, and it must include a filter with the intent
+ "android.content.action.DOCUMENTS_PROVIDER" in order to be shown in the system document
+ picker UI.
+ -->
+ <provider
+ android:name="com.example.android.storageprovider.MyCloudProvider"
+ android:authorities="com.example.android.storageprovider.documents"
+ android:grantUriPermissions="true"
+ android:exported="true"
+ android:permission="android.permission.MANAGE_DOCUMENTS">
+ <intent-filter>
+ <action android:name="android.content.action.DOCUMENTS_PROVIDER"/>
+ </intent-filter>
+ </provider>
+ <!--END_INCLUDE(provider_manifest)-->
+
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
new file mode 100644
index 0000000..3228927
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/activities/SampleActivityBase.java
@@ -0,0 +1,52 @@
+/*
+* Copyright 2013 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.common.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogWrapper;
+
+/**
+ * Base launcher activity, to handle most of the common plumbing for samples.
+ */
+public class SampleActivityBase extends FragmentActivity {
+
+ public static final String TAG = "SampleActivityBase";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initializeLogging();
+ }
+
+ /** Set up targets to receive log data */
+ public void initializeLogging() {
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ // Wraps Android's native log framework
+ LogWrapper logWrapper = new LogWrapper();
+ Log.setLogNode(logWrapper);
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MainActivity.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MainActivity.java
new file mode 100644
index 0000000..5f04a62
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MainActivity.java
@@ -0,0 +1,80 @@
+/*
+* Copyright 2013 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.storageprovider;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.Menu;
+
+import com.example.android.common.activities.SampleActivityBase;
+import com.example.android.common.logger.Log;
+import com.example.android.common.logger.LogFragment;
+import com.example.android.common.logger.LogWrapper;
+import com.example.android.common.logger.MessageOnlyLogFilter;
+
+/**
+ * A simple launcher activity containing a summary sample description
+ * and a few action bar buttons.
+ */
+public class MainActivity extends SampleActivityBase {
+
+ public static final String TAG = "MainActivity";
+
+ public static final String FRAGTAG = "MyCloudFragment";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ if (getSupportFragmentManager().findFragmentByTag(FRAGTAG) == null ) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ MyCloudFragment fragment = new MyCloudFragment();
+ transaction.add(fragment, FRAGTAG);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ /** Create a chain of targets that will receive log data */
+ @Override
+ public void initializeLogging() {
+ // Wraps Android's native log framework.
+ LogWrapper logWrapper = new LogWrapper();
+ // Using Log, front-end to the logging chain, emulates android.util.log method signatures.
+ Log.setLogNode(logWrapper);
+
+ // Filter strips out everything except the message text.
+ MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
+ logWrapper.setNext(msgFilter);
+
+ // On screen logging via a fragment with a TextView.
+ LogFragment logFragment = (LogFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.log_fragment);
+ msgFilter.setNext(logFragment.getLogView());
+
+ Log.i(TAG, "Ready");
+ }
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudFragment.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudFragment.java
new file mode 100644
index 0000000..f624e90
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudFragment.java
@@ -0,0 +1,105 @@
+/*
+* Copyright 2013 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.storageprovider;
+
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.v4.app.Fragment;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.example.android.common.logger.Log;
+
+/**
+ * Toggles the user's login status via a login menu option, and enables/disables the cloud storage
+ * content provider.
+ */
+public class MyCloudFragment extends Fragment {
+
+ private static final String TAG = "MyCloudFragment";
+ private static final String AUTHORITY = "com.example.android.storageprovider.documents";
+ private boolean mLoggedIn = false;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mLoggedIn = readLoginValue();
+
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ MenuItem item = menu.findItem(R.id.sample_action);
+ item.setTitle(mLoggedIn ? R.string.log_out : R.string.log_in);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.sample_action) {
+ toggleLogin();
+ item.setTitle(mLoggedIn ? R.string.log_out : R.string.log_in);
+
+ // BEGIN_INCLUDE(notify_change)
+ // Notify the system that the status of our roots has changed. This will trigger
+ // a call to MyCloudProvider.queryRoots() and force a refresh of the system
+ // picker UI. It's important to call this or stale results may persist.
+ getActivity().getContentResolver().notifyChange(DocumentsContract.buildRootsUri
+ (AUTHORITY), null, false);
+ // END_INCLUDE(notify_change)
+ }
+ return true;
+ }
+
+ /**
+ * Dummy function to change the user's authorization status.
+ */
+ private void toggleLogin() {
+ // Replace this with your standard method of authentication to determine if your app
+ // should make the user's documents available.
+ mLoggedIn = !mLoggedIn;
+ writeLoginValue(mLoggedIn);
+ Log.i(TAG, getString(mLoggedIn ? R.string.logged_in_info : R.string.logged_out_info));
+ }
+
+ /**
+ * Dummy function to save whether the user is logged in.
+ */
+ private void writeLoginValue(boolean loggedIn) {
+ final SharedPreferences sharedPreferences =
+ getActivity().getSharedPreferences(getString(R.string.app_name),
+ getActivity().MODE_PRIVATE);
+ sharedPreferences.edit().putBoolean(getString(R.string.key_logged_in), loggedIn).commit();
+ }
+
+ /**
+ * Dummy function to determine whether the user is logged in.
+ */
+ private boolean readLoginValue() {
+ final SharedPreferences sharedPreferences =
+ getActivity().getSharedPreferences(getString(R.string.app_name),
+ getActivity().MODE_PRIVATE);
+ return sharedPreferences.getBoolean(getString(R.string.key_logged_in), false);
+ }
+
+}
+
+
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudProvider.java b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudProvider.java
new file mode 100644
index 0000000..d8be813
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/java/com/example/android/storageprovider/MyCloudProvider.java
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2013 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.storageprovider;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.TypedArray;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Point;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract.Root;
+import android.provider.DocumentsProvider;
+import android.webkit.MimeTypeMap;
+
+import com.example.android.common.logger.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.PriorityQueue;
+import java.util.Set;
+
+/**
+ * Manages documents and exposes them to the Android system for sharing.
+ */
+public class MyCloudProvider extends DocumentsProvider {
+ private static final String TAG = MyCloudProvider.class.getSimpleName();
+
+ // Use these as the default columns to return information about a root if no specific
+ // columns are requested in a query.
+ private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{
+ Root.COLUMN_ROOT_ID,
+ Root.COLUMN_MIME_TYPES,
+ Root.COLUMN_FLAGS,
+ Root.COLUMN_ICON,
+ Root.COLUMN_TITLE,
+ Root.COLUMN_SUMMARY,
+ Root.COLUMN_DOCUMENT_ID,
+ Root.COLUMN_AVAILABLE_BYTES
+ };
+
+ // Use these as the default columns to return information about a document if no specific
+ // columns are requested in a query.
+ private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[]{
+ Document.COLUMN_DOCUMENT_ID,
+ Document.COLUMN_MIME_TYPE,
+ Document.COLUMN_DISPLAY_NAME,
+ Document.COLUMN_LAST_MODIFIED,
+ Document.COLUMN_FLAGS,
+ Document.COLUMN_SIZE
+ };
+
+ // No official policy on how many to return, but make sure you do limit the number of recent
+ // and search results.
+ private static final int MAX_SEARCH_RESULTS = 20;
+ private static final int MAX_LAST_MODIFIED = 5;
+
+ private static final String ROOT = "root";
+
+ // A file object at the root of the file hierarchy. Depending on your implementation, the root
+ // does not need to be an existing file system directory. For example, a tag-based document
+ // provider might return a directory containing all tags, represented as child directories.
+ private File mBaseDir;
+
+ @Override
+ public boolean onCreate() {
+ Log.v(TAG, "onCreate");
+
+ mBaseDir = getContext().getFilesDir();
+
+ writeDummyFilesToStorage();
+
+ return true;
+ }
+
+ // BEGIN_INCLUDE(query_roots)
+ @Override
+ public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+ Log.v(TAG, "queryRoots");
+
+ // Create a cursor with either the requested fields, or the default projection. This
+ // cursor is returned to the Android system picker UI and used to display all roots from
+ // this provider.
+ final MatrixCursor result = new MatrixCursor(resolveRootProjection(projection));
+
+ // If user is not logged in, return an empty root cursor. This removes our provider from
+ // the list entirely.
+ if (!isUserLoggedIn()) {
+ return result;
+ }
+
+ // It's possible to have multiple roots (e.g. for multiple accounts in the same app) -
+ // just add multiple cursor rows.
+ // Construct one row for a root called "MyCloud".
+ final MatrixCursor.RowBuilder row = result.newRow();
+
+ row.add(Root.COLUMN_ROOT_ID, ROOT);
+ row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary));
+
+ // FLAG_SUPPORTS_CREATE means at least one directory under the root supports creating
+ // documents. FLAG_SUPPORTS_RECENTS means your application's most recently used
+ // documents will show up in the "Recents" category. FLAG_SUPPORTS_SEARCH allows users
+ // to search all documents the application shares.
+ row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE |
+ Root.FLAG_SUPPORTS_RECENTS |
+ Root.FLAG_SUPPORTS_SEARCH);
+
+ // COLUMN_TITLE is the root title (e.g. what will be displayed to identify your provider).
+ row.add(Root.COLUMN_TITLE, getContext().getString(R.string.app_name));
+
+ // This document id must be unique within this provider and consistent across time. The
+ // system picker UI may save it and refer to it later.
+ row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir));
+
+ // The child MIME types are used to filter the roots and only present to the user roots
+ // that contain the desired type somewhere in their file hierarchy.
+ row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir));
+ row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace());
+ row.add(Root.COLUMN_ICON, R.drawable.ic_launcher);
+
+ return result;
+ }
+ // END_INCLUDE(query_roots)
+
+ // BEGIN_INCLUDE(query_recent_documents)
+ @Override
+ public Cursor queryRecentDocuments(String rootId, String[] projection)
+ throws FileNotFoundException {
+ Log.v(TAG, "queryRecentDocuments");
+
+ // This example implementation walks a local file structure to find the most recently
+ // modified files. Other implementations might include making a network call to query a
+ // server.
+
+ // Create a cursor with the requested projection, or the default projection.
+ final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+
+ final File parent = getFileForDocId(rootId);
+
+ // Create a queue to store the most recent documents, which orders by last modified.
+ PriorityQueue<File> lastModifiedFiles = new PriorityQueue<File>(5, new Comparator<File>() {
+ public int compare(File i, File j) {
+ return Long.compare(i.lastModified(), j.lastModified());
+ }
+ });
+
+ // Iterate through all files and directories in the file structure under the root. If
+ // the file is more recent than the least recently modified, add it to the queue,
+ // limiting the number of results.
+ final LinkedList<File> pending = new LinkedList<File>();
+
+ // Start by adding the parent to the list of files to be processed
+ pending.add(parent);
+
+ // Do while we still have unexamined files
+ while (!pending.isEmpty()) {
+ // Take a file from the list of unprocessed files
+ final File file = pending.removeFirst();
+ if (file.isDirectory()) {
+ // If it's a directory, add all its children to the unprocessed list
+ Collections.addAll(pending, file.listFiles());
+ } else {
+ // If it's a file, add it to the ordered queue.
+ lastModifiedFiles.add(file);
+ }
+ }
+
+ // Add the most recent files to the cursor, not exceeding the max number of results.
+ for (int i = 0; i < Math.min(MAX_LAST_MODIFIED + 1, lastModifiedFiles.size()); i++) {
+ final File file = lastModifiedFiles.remove();
+ includeFile(result, null, file);
+ }
+ return result;
+ }
+ // END_INCLUDE(query_recent_documents)
+
+ // BEGIN_INCLUDE(query_search_documents)
+ @Override
+ public Cursor querySearchDocuments(String rootId, String query, String[] projection)
+ throws FileNotFoundException {
+ Log.v(TAG, "querySearchDocuments");
+
+ // Create a cursor with the requested projection, or the default projection.
+ final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+ final File parent = getFileForDocId(rootId);
+
+ // This example implementation searches file names for the query and doesn't rank search
+ // results, so we can stop as soon as we find a sufficient number of matches. Other
+ // implementations might use other data about files, rather than the file name, to
+ // produce a match; it might also require a network call to query a remote server.
+
+ // Iterate through all files in the file structure under the root until we reach the
+ // desired number of matches.
+ final LinkedList<File> pending = new LinkedList<File>();
+
+ // Start by adding the parent to the list of files to be processed
+ pending.add(parent);
+
+ // Do while we still have unexamined files, and fewer than the max search results
+ while (!pending.isEmpty() && result.getCount() < MAX_SEARCH_RESULTS) {
+ // Take a file from the list of unprocessed files
+ final File file = pending.removeFirst();
+ if (file.isDirectory()) {
+ // If it's a directory, add all its children to the unprocessed list
+ Collections.addAll(pending, file.listFiles());
+ } else {
+ // If it's a file and it matches, add it to the result cursor.
+ if (file.getName().toLowerCase().contains(query)) {
+ includeFile(result, null, file);
+ }
+ }
+ }
+ return result;
+ }
+ // END_INCLUDE(query_search_documents)
+
+ // BEGIN_INCLUDE(open_document_thumbnail)
+ @Override
+ public AssetFileDescriptor openDocumentThumbnail(String documentId, Point sizeHint,
+ CancellationSignal signal)
+ throws FileNotFoundException {
+ Log.v(TAG, "openDocumentThumbnail");
+
+ final File file = getFileForDocId(documentId);
+ final ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+ return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH);
+ }
+ // END_INCLUDE(open_document_thumbnail)
+
+ // BEGIN_INCLUDE(query_document)
+ @Override
+ public Cursor queryDocument(String documentId, String[] projection)
+ throws FileNotFoundException {
+ Log.v(TAG, "queryDocument");
+
+ // Create a cursor with the requested projection, or the default projection.
+ final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+ includeFile(result, documentId, null);
+ return result;
+ }
+ // END_INCLUDE(query_document)
+
+ // BEGIN_INCLUDE(query_child_documents)
+ @Override
+ public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
+ String sortOrder) throws FileNotFoundException {
+ Log.v(TAG, "queryChildDocuments, parentDocumentId: " +
+ parentDocumentId +
+ " sortOrder: " +
+ sortOrder);
+
+ final MatrixCursor result = new MatrixCursor(resolveDocumentProjection(projection));
+ final File parent = getFileForDocId(parentDocumentId);
+ for (File file : parent.listFiles()) {
+ includeFile(result, null, file);
+ }
+ return result;
+ }
+ // END_INCLUDE(query_child_documents)
+
+
+ // BEGIN_INCLUDE(open_document)
+ @Override
+ public ParcelFileDescriptor openDocument(final String documentId, final String mode,
+ CancellationSignal signal)
+ throws FileNotFoundException {
+ Log.v(TAG, "openDocument, mode: " + mode);
+ // It's OK to do network operations in this method to download the document, as long as you
+ // periodically check the CancellationSignal. If you have an extremely large file to
+ // transfer from the network, a better solution may be pipes or sockets
+ // (see ParcelFileDescriptor for helper methods).
+
+ final File file = getFileForDocId(documentId);
+ final int accessMode = ParcelFileDescriptor.parseMode(mode);
+
+ final boolean isWrite = (mode.indexOf('w') != -1);
+ if (isWrite) {
+ // Attach a close listener if the document is opened in write mode.
+ try {
+ Handler handler = new Handler(getContext().getMainLooper());
+ return ParcelFileDescriptor.open(file, accessMode, handler,
+ new ParcelFileDescriptor.OnCloseListener() {
+ @Override
+ public void onClose(IOException e) {
+
+ // Update the file with the cloud server. The client is done writing.
+ Log.i(TAG, "A file with id " + documentId + " has been closed! Time to " +
+ "update the server.");
+ }
+
+ });
+ } catch (IOException e) {
+ throw new FileNotFoundException("Failed to open document with id " + documentId +
+ " and mode " + mode);
+ }
+ } else {
+ return ParcelFileDescriptor.open(file, accessMode);
+ }
+ }
+ // END_INCLUDE(open_document)
+
+
+ // BEGIN_INCLUDE(create_document)
+ @Override
+ public String createDocument(String documentId, String mimeType, String displayName)
+ throws FileNotFoundException {
+ Log.v(TAG, "createDocument");
+
+ File parent = getFileForDocId(documentId);
+ File file = new File(parent.getPath(), displayName);
+ try {
+ file.createNewFile();
+ file.setWritable(true);
+ file.setReadable(true);
+ } catch (IOException e) {
+ throw new FileNotFoundException("Failed to create document with name " +
+ displayName +" and documentId " + documentId);
+ }
+ return getDocIdForFile(file);
+ }
+ // END_INCLUDE(create_document)
+
+ // BEGIN_INCLUDE(delete_document)
+ @Override
+ public void deleteDocument(String documentId) throws FileNotFoundException {
+ Log.v(TAG, "deleteDocument");
+ File file = getFileForDocId(documentId);
+ if (file.delete()) {
+ Log.i(TAG, "Deleted file with id " + documentId);
+ } else {
+ throw new FileNotFoundException("Failed to delete document with id " + documentId);
+ }
+ }
+ // END_INCLUDE(delete_document)
+
+
+ @Override
+ public String getDocumentType(String documentId) throws FileNotFoundException {
+ File file = getFileForDocId(documentId);
+ return getTypeForFile(file);
+ }
+
+ /**
+ * @param projection the requested root column projection
+ * @return either the requested root column projection, or the default projection if the
+ * requested projection is null.
+ */
+ private static String[] resolveRootProjection(String[] projection) {
+ return projection != null ? projection : DEFAULT_ROOT_PROJECTION;
+ }
+
+ private static String[] resolveDocumentProjection(String[] projection) {
+ return projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION;
+ }
+
+ /**
+ * Get a file's MIME type
+ *
+ * @param file the File object whose type we want
+ * @return the MIME type of the file
+ */
+ private static String getTypeForFile(File file) {
+ if (file.isDirectory()) {
+ return Document.MIME_TYPE_DIR;
+ } else {
+ return getTypeForName(file.getName());
+ }
+ }
+
+ /**
+ * Get the MIME data type of a document, given its filename.
+ *
+ * @param name the filename of the document
+ * @return the MIME data type of a document
+ */
+ private static String getTypeForName(String name) {
+ final int lastDot = name.lastIndexOf('.');
+ if (lastDot >= 0) {
+ final String extension = name.substring(lastDot + 1);
+ final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
+ if (mime != null) {
+ return mime;
+ }
+ }
+ return "application/octet-stream";
+ }
+
+ /**
+ * Gets a string of unique MIME data types a directory supports, separated by newlines. This
+ * should not change.
+ *
+ * @param parent the File for the parent directory
+ * @return a string of the unique MIME data types the parent directory supports
+ */
+ private String getChildMimeTypes(File parent) {
+ Set<String> mimeTypes = new HashSet<String>();
+ mimeTypes.add("image/*");
+ mimeTypes.add("text/*");
+ mimeTypes.add("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
+
+ // Flatten the list into a string and insert newlines between the MIME type strings.
+ StringBuilder mimeTypesString = new StringBuilder();
+ for (String mimeType : mimeTypes) {
+ mimeTypesString.append(mimeType).append("\n");
+ }
+
+ return mimeTypesString.toString();
+ }
+
+ /**
+ * Get the document ID given a File. The document id must be consistent across time. Other
+ * applications may save the ID and use it to reference documents later.
+ * <p/>
+ * This implementation is specific to this demo. It assumes only one root and is built
+ * directly from the file structure. However, it is possible for a document to be a child of
+ * multiple directories (for example "android" and "images"), in which case the file must have
+ * the same consistent, unique document ID in both cases.
+ *
+ * @param file the File whose document ID you want
+ * @return the corresponding document ID
+ */
+ private String getDocIdForFile(File file) {
+ String path = file.getAbsolutePath();
+
+ // Start at first char of path under root
+ final String rootPath = mBaseDir.getPath();
+ if (rootPath.equals(path)) {
+ path = "";
+ } else if (rootPath.endsWith("/")) {
+ path = path.substring(rootPath.length());
+ } else {
+ path = path.substring(rootPath.length() + 1);
+ }
+
+ return "root" + ':' + path;
+ }
+
+ /**
+ * Add a representation of a file to a cursor.
+ *
+ * @param result the cursor to modify
+ * @param docId the document ID representing the desired file (may be null if given file)
+ * @param file the File object representing the desired file (may be null if given docID)
+ * @throws java.io.FileNotFoundException
+ */
+ private void includeFile(MatrixCursor result, String docId, File file)
+ throws FileNotFoundException {
+ if (docId == null) {
+ docId = getDocIdForFile(file);
+ } else {
+ file = getFileForDocId(docId);
+ }
+
+ int flags = 0;
+
+ if (file.isDirectory()) {
+ // Request the folder to lay out as a grid rather than a list. This also allows a larger
+ // thumbnail to be displayed for each image.
+ // flags |= Document.FLAG_DIR_PREFERS_GRID;
+
+ // Add FLAG_DIR_SUPPORTS_CREATE if the file is a writable directory.
+ if (file.isDirectory() && file.canWrite()) {
+ flags |= Document.FLAG_DIR_SUPPORTS_CREATE;
+ }
+ } else if (file.canWrite()) {
+ // If the file is writable set FLAG_SUPPORTS_WRITE and
+ // FLAG_SUPPORTS_DELETE
+ flags |= Document.FLAG_SUPPORTS_WRITE;
+ flags |= Document.FLAG_SUPPORTS_DELETE;
+ }
+
+ final String displayName = file.getName();
+ final String mimeType = getTypeForFile(file);
+
+ if (mimeType.startsWith("image/")) {
+ // Allow the image to be represented by a thumbnail rather than an icon
+ flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
+ }
+
+ final MatrixCursor.RowBuilder row = result.newRow();
+ row.add(Document.COLUMN_DOCUMENT_ID, docId);
+ row.add(Document.COLUMN_DISPLAY_NAME, displayName);
+ row.add(Document.COLUMN_SIZE, file.length());
+ row.add(Document.COLUMN_MIME_TYPE, mimeType);
+ row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
+ row.add(Document.COLUMN_FLAGS, flags);
+
+ // Add a custom icon
+ row.add(Document.COLUMN_ICON, R.drawable.ic_launcher);
+ }
+
+ /**
+ * Translate your custom URI scheme into a File object.
+ *
+ * @param docId the document ID representing the desired file
+ * @return a File represented by the given document ID
+ * @throws java.io.FileNotFoundException
+ */
+ private File getFileForDocId(String docId) throws FileNotFoundException {
+ File target = mBaseDir;
+ if (docId.equals(ROOT)) {
+ return target;
+ }
+ final int splitIndex = docId.indexOf(':', 1);
+ if (splitIndex < 0) {
+ throw new FileNotFoundException("Missing root for " + docId);
+ } else {
+ final String path = docId.substring(splitIndex + 1);
+ target = new File(target, path);
+ if (!target.exists()) {
+ throw new FileNotFoundException("Missing file for " + docId + " at " + target);
+ }
+ return target;
+ }
+ }
+
+
+ /**
+ * Preload sample files packaged in the apk into the internal storage directory. This is a
+ * dummy function specific to this demo. The MyCloud mock cloud service doesn't actually
+ * have a backend, so it simulates by reading content from the device's internal storage.
+ */
+ private void writeDummyFilesToStorage() {
+ if (mBaseDir.list().length > 0) {
+ return;
+ }
+
+ int[] imageResIds = getResourceIdArray(R.array.image_res_ids);
+ for (int resId : imageResIds) {
+ writeFileToInternalStorage(resId, ".jpeg");
+ }
+
+ int[] textResIds = getResourceIdArray(R.array.text_res_ids);
+ for (int resId : textResIds) {
+ writeFileToInternalStorage(resId, ".txt");
+ }
+
+ int[] docxResIds = getResourceIdArray(R.array.docx_res_ids);
+ for (int resId : docxResIds) {
+ writeFileToInternalStorage(resId, ".docx");
+ }
+ }
+
+ /**
+ * Write a file to internal storage. Used to set up our dummy "cloud server".
+ *
+ * @param resId the resource ID of the file to write to internal storage
+ * @param extension the file extension (ex. .png, .mp3)
+ */
+ private void writeFileToInternalStorage(int resId, String extension) {
+ InputStream ins = getContext().getResources().openRawResource(resId);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ int size;
+ byte[] buffer = new byte[1024];
+ try {
+ while ((size = ins.read(buffer, 0, 1024)) >= 0) {
+ outputStream.write(buffer, 0, size);
+ }
+ ins.close();
+ buffer = outputStream.toByteArray();
+ String filename = getContext().getResources().getResourceEntryName(resId) + extension;
+ FileOutputStream fos = getContext().openFileOutput(filename, Context.MODE_PRIVATE);
+ fos.write(buffer);
+ fos.close();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private int[] getResourceIdArray(int arrayResId) {
+ TypedArray ar = getContext().getResources().obtainTypedArray(arrayResId);
+ int len = ar.length();
+ int[] resIds = new int[len];
+ for (int i = 0; i < len; i++) {
+ resIds[i] = ar.getResourceId(i, 0);
+ }
+ ar.recycle();
+ return resIds;
+ }
+
+ /**
+ * Dummy function to determine whether the user is logged in.
+ */
+ private boolean isUserLoggedIn() {
+ final SharedPreferences sharedPreferences =
+ getContext().getSharedPreferences(getContext().getString(R.string.app_name),
+ Context.MODE_PRIVATE);
+ return sharedPreferences.getBoolean(getContext().getString(R.string.key_logged_in), false);
+ }
+
+
+}
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..c5d6972
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..59e6bd9
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..5b8b7be
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..474bbd2
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/ic_launcher.png b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/ic_launcher.png
new file mode 100755
index 0000000..c5d6972
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..bc5a575
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,38 @@
+<!--
+ Copyright 2013 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.
+ -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:id="@+id/sample_main_layout">
+ <TextView android:id="@+id/sample_output"
+ style="@style/Widget.SampleMessage"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/intro_message" />
+ <View
+ android:layout_width="fill_parent"
+ android:layout_height="1dp"
+ android:background="@android:color/darker_gray"/>
+ <fragment
+ android:name="com.example.android.common.logger.LogFragment"
+ android:id="@+id/log_fragment"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/menu/main.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/menu/main.xml
new file mode 100644
index 0000000..2c3515d
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/menu/main.xml
@@ -0,0 +1,21 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/sample_action"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/sample_action" />
+</menu>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_android_studio.jpg b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_android_studio.jpg
new file mode 100755
index 0000000..b916136
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_android_studio.jpg
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_back.jpg b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_back.jpg
new file mode 100755
index 0000000..4ba4929
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_computer_back.jpg
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_dinner.jpg b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_dinner.jpg
new file mode 100755
index 0000000..6c5491f
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_dinner.jpg
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_pumpkins_fall.jpg b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_pumpkins_fall.jpg
new file mode 100755
index 0000000..6111f32
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_pumpkins_fall.jpg
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_rose.jpg b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_rose.jpg
new file mode 100755
index 0000000..396eb90
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/android_rose.jpg
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/cat_names.txt b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/cat_names.txt
new file mode 100644
index 0000000..b67570b
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/cat_names.txt
@@ -0,0 +1,17 @@
+Top cat names of 2013
+
+1. Angel
+2. Charlie
+3. Mittens
+4. Milkshake
+5. Oreo
+6. Ella
+7. Lily
+8. Ellie
+9. Pepsi
+10. Amber
+11. Molly
+12. Truffles
+13. Peanut
+14. Tiger Lilly
+15. Snowball
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/dog_names.txt b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/dog_names.txt
new file mode 100644
index 0000000..ca43dd6
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/dog_names.txt
@@ -0,0 +1,17 @@
+Top dog names of 2013
+
+1. Gus
+2. Trapper
+3. Finn
+4. Bailey
+5. Cooper
+6. Hawkeye
+7. Wrigley
+8. Boomer
+9. Ace
+10. Butch
+11. Delgado
+12. Evan
+13. Lucky
+14. Otto
+15. Buddy
\ No newline at end of file
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/example.docx b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/example.docx
new file mode 100644
index 0000000..1f6e016
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/raw/example.docx
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/app_strings.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/app_strings.xml
new file mode 100644
index 0000000..fa60e14
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/app_strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright 2013 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.
+-->
+
+
+<resources>
+ <string name="log_in">Log in</string>
+ <string name="log_out">Log out</string>
+ <string name="logged_in_info">You are currently logged in, which means the documents in MyCloud are visible to other applications.</string>
+ <string name="logged_out_info">You are currently logged out, so MyCloud is not visible as a document provider.</string>
+ <string name="root_summary">cloudy with a chance of …</string>
+ <string name="key_logged_in">logged_in</string>
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/arrays.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..b79a5a9
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/arrays.xml
@@ -0,0 +1,34 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+ <array name="image_res_ids">
+ <item>@raw/android_dinner</item>
+ <item>@raw/android_rose</item>
+ <item>@raw/android_pumpkins_fall</item>
+ <item>@raw/android_computer_back</item>
+ <item>@raw/android_computer_android_studio</item>
+ </array>
+
+ <array name="text_res_ids">
+ <item>@raw/cat_names</item>
+ <item>@raw/dog_names</item>
+ </array>
+
+ <array name="docx_res_ids">
+ <item>@raw/example</item>
+ </array>
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..d3674af
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">MyCloud</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ \nA simple implementation of a documents provider using the storage access framework in
+ Android 4.4.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/strings.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..df03273
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="sample_action">Log in</string>
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/styles.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..b325e36
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/styles.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <style name="MyAppTheme" parent="AppTheme">
+ <item name="android:textViewStyle">@style/MyTextViewStyle</item>
+ <item name="android:actionBarStyle">@style/MyActionBarStyle</item>
+ <item name="android:actionMenuTextColor">@android:color/white</item>
+ </style>
+
+ <style name="MyActionBarStyle" parent="android:Widget.Holo.Light.ActionBar.Solid.Inverse">
+ <item name="android:background">#5E2D79</item>
+ <item name="android:backgroundSplit">#5E2D79</item>
+ </style>
+
+ <style name="MyTextViewStyle" parent="android:TextAppearance.Holo.Widget.TextView">
+ <item name="android:textSize">18sp</item>
+ <item name="android:paddingRight">@dimen/margin_medium</item>
+ <item name="android:paddingLeft">@dimen/margin_medium</item>
+ <item name="android:fontFamily">sans-serif-light</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..d3f82ff
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/StorageProviderSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,51 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="AppTheme" parent="Theme.Base" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+
+ <style name="Widget.SampleOutput">
+ <item name="android:padding">@dimen/margin_medium</item>
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Log" parent="Widget.SampleOutput">
+ <item name="android:typeface">monospace</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/StorageProvider/build.gradle b/prebuilts/gradle/StorageProvider/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/StorageProvider/gradlew b/prebuilts/gradle/StorageProvider/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/StorageProvider/gradlew.bat b/prebuilts/gradle/StorageProvider/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/StorageProvider/settings.gradle b/prebuilts/gradle/StorageProvider/settings.gradle
new file mode 100644
index 0000000..d4b818f
--- /dev/null
+++ b/prebuilts/gradle/StorageProvider/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'StorageProviderSample'
diff --git a/prebuilts/gradle/TextLinkify/README.txt b/prebuilts/gradle/TextLinkify/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/build.gradle b/prebuilts/gradle/TextLinkify/TextLinkifySample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/AndroidManifest.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..49b4eae
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.textlinkify"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="4"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/textlinkify/MainActivity.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/textlinkify/MainActivity.java
new file mode 100644
index 0000000..c9325a9
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/java/com/example/android/textlinkify/MainActivity.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2013 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.textlinkify;
+
+import android.app.Activity;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.text.Html;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.method.LinkMovementMethod;
+import android.text.style.StyleSpan;
+import android.text.style.URLSpan;
+import android.widget.TextView;
+
+/**
+ * This sample demonstrates how clickable links can be added to a
+ * {@link android.widget.TextView}.
+ *
+ * <p>This can be done in three ways:
+ * <ul>
+ * <li><b>Automatically:</b> Text added to a TextView can automatically be linkified by enabling
+ * autoLinking. In XML, use the android:autoLink property, programatically call
+ * {@link android.widget.TextView#setAutoLinkMask(int)} using an option from
+ * {@link android.text.util.Linkify}</li>
+ *
+ * <li><b>Parsing a String as HTML:</b> See {@link android.text.Html#fromHtml(String)})</li>
+ *
+ * <li><b>Manually by constructing a {@link android.text.SpannableString}:</b> Consisting of
+ * {@link android.text.style.StyleSpan} and {@link android.text.style.URLSpan} objects that
+ * are contained within a {@link android.text.SpannableString}</li>
+ * </ul></p>
+ *
+ */
+public class MainActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.sample_main);
+
+ // BEGIN_INCLUDE(text_auto_linkify)
+ /*
+ * text_auto_linkify shows the android:autoLink property, which
+ * automatically linkifies things like URLs and phone numbers
+ * found in the text. No java code is needed to make this
+ * work.
+ * This can also be enabled programmatically by calling
+ * .setAutoLinkMask(Linkify.ALL) before the text is set on the TextView.
+ *
+ * See android.text.util.Linkify for other options, for example only
+ * auto-linking email addresses or phone numbers
+ */
+ // END_INCLUDE(text_auto_linkify)
+
+ // BEGIN_INCLUDE(text_html_resource)
+ /*
+ * text_html_resource has links specified by putting anchor tags (<a>) in the string
+ * resource. By default these links will appear but not
+ * respond to user input. To make them active, you need to
+ * call setMovementMethod() on the TextView object.
+ */
+ TextView textViewResource = (TextView) findViewById(R.id.text_html_resource);
+ textViewResource.setText(
+ Html.fromHtml(getResources().getString(R.string.link_text_manual)));
+ textViewResource.setMovementMethod(LinkMovementMethod.getInstance());
+ // END_INCLUDE(text_html_resource)
+
+ // BEGIN_INCLUDE(text_html_program)
+ /*
+ * text_html_program shows creating text with links from HTML in the Java
+ * code, rather than from a string resource. Note that for a
+ * fixed string, using a (localizable) resource as shown above
+ * is usually a better way to go; this example is intended to
+ * illustrate how you might display text that came from a
+ * dynamic source (eg, the network).
+ */
+ TextView textViewHtml = (TextView) findViewById(R.id.text_html_program);
+ textViewHtml.setText(
+ Html.fromHtml(
+ "<b>text_html_program: Constructed from HTML programmatically.</b>"
+ + " Text with a <a href=\"http://www.google.com\">link</a> "
+ + "created in the Java source code using HTML."));
+ textViewHtml.setMovementMethod(LinkMovementMethod.getInstance());
+ // END_INCLUDE(text_html_program)
+
+ // BEGIN_INCLUDE(text_spannable)
+ /*
+ * text_spannable illustrates constructing a styled string containing a
+ * link without using HTML at all. Again, for a fixed string
+ * you should probably be using a string resource, not a
+ * hardcoded value.
+ */
+ SpannableString ss = new SpannableString(
+ "text_spannable: Manually created spans. Click here to dial the phone.");
+
+ /*
+ * Make the first 38 characters bold by applying a StyleSpan with bold typeface.
+ *
+ * Characters 45 to 49 (the word "here") is made clickable by applying a URLSpan
+ * pointing to a telephone number. Clicking it opens the "tel:" URL that starts the dialer.
+ *
+ * The SPAN_EXCLUSIVE_EXCLUSIVE flag defines this span as exclusive, which means
+ * that it will not expand to include text inserted on either side of this span.
+ */
+ ss.setSpan(new StyleSpan(Typeface.BOLD), 0, 39,
+ Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+ ss.setSpan(new URLSpan("tel:4155551212"), 40 + 6, 40 + 10,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+
+ TextView textViewSpan = (TextView) findViewById(R.id.text_spannable);
+ textViewSpan.setText(ss);
+
+ /*
+ * Set the movement method to move between links in this TextView.
+ * This means that the user traverses through links in this TextView, automatically
+ * handling appropriate scrolling and key commands.
+ */
+ textViewSpan.setMovementMethod(LinkMovementMethod.getInstance());
+ // END_INCLUDE(text_spannable)
+ }
+
+}
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..eae36bc
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..f727f48
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..51199d3
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..c49ec6a
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..8f35a70
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,72 @@
+<!--
+ Copyright 2013 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.
+-->
+
+ <ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ tools:context=".MainActivity">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin">
+
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/intro" />
+
+ <!-- text_auto_linkify automatically linkifies things like URLs and phone numbers. -->
+ <TextView
+ android:id="@+id/text_auto_linkify"
+ style="@style/LinkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:autoLink="all"
+ android:text="@string/link_text_auto" />
+
+ <!--
+ text_html_resource uses a string resource containing explicit anchor tags (<a>)
+ to specify links.
+ -->
+ <TextView
+ android:id="@+id/text_html_resource"
+ style="@style/LinkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <!-- text_html_program builds the text in the Java code using HTML. -->
+ <TextView
+ android:id="@+id/text_html_program"
+ style="@style/LinkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <!-- text_spannable builds the text in the Java code without using HTML. -->
+ <TextView
+ android:id="@+id/text_spannable"
+ style="@style/LinkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+ </ScrollView>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..560bd44
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+ -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/base-strings.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..f2eb104
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/base-strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">TextLinkify</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample illustrates how links can be added to a TextView. This can be done either
+ automatically by setting the "autoLink" property or explicitly.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/dimens.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..3b1975a
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/strings.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..c50774e
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/strings.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <string name="intro">This sample illustrates how links can be added to a TextView.
+ \nThis can be done either automatically by setting the <i>autoLink</i> property
+ or explicitly.</string>
+ <string name="link_text_auto"><b>text_auto_linkify: Various kinds
+ of data that will be auto-linked.</b>
+ In this text are some things that are actionable. For instance,
+ you can click on http://www.google.com and it will launch the
+ web browser. You can click on google.com too. If you
+ click on (415) 555-1212 it should dial the phone. Or just write
+ foobar@example.com for an e-mail link. If you have a URI like
+ http://www.example.com/lala/foobar@example.com you should get the
+ full link not the e-mail address. Or you can put a location
+ like 1600 Amphitheatre Parkway, Mountain View, CA 94043. To summarize:
+ https://www.google.com, or 650-253-0000, somebody@example.com,
+ or 9606 North MoPac Expressway, Suite 400, Austin, TX 78759.</string>
+ <string name="link_text_manual"><![CDATA[<b>text_html_resource:
+ Explicit links using <a> markup.</b>
+ This has markup for a <a href="http://www.google.com">link</a> specified
+ via an <a> tag. Use a \"tel:\" URL
+ to <a href="tel:4155551212">dial a phone number</a>.]]></string>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/styles.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..29c4230
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/styles.xml
@@ -0,0 +1,22 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="LinkText">
+ <item name="android:paddingTop">9dp</item>
+ <item name="android:paddingBottom">9dp</item>
+ </style>
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-styles.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/AndroidManifest.xml b/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/AndroidManifest.xml
new file mode 100644
index 0000000..e368f05
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2013 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.textlinkify.tests"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <uses-sdk
+ android:minSdkVersion="18"
+ android:targetSdkVersion="19" />
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ Specifies the instrumentation test runner used to run the tests.
+ -->
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.example.android.textlinkify"
+ android:label="Tests for com.example.android.textlinkify" />
+
+</manifest>
\ No newline at end of file
diff --git a/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/src/com/example/android/textlinkify/tests/SampleTests.java b/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/src/com/example/android/textlinkify/tests/SampleTests.java
new file mode 100644
index 0000000..90a91cc
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/TextLinkifySample/tests/src/com/example/android/textlinkify/tests/SampleTests.java
@@ -0,0 +1,79 @@
+/*
+* Copyright 2013 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.
+*/
+
+
+
+/*
+* Copyright (C) 2013 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.textlinkify.tests;
+
+import com.example.android.textlinkify.*;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+* Tests for TextLinkify sample.
+*/
+public class SampleTests extends ActivityInstrumentationTestCase2<MainActivity> {
+
+ private MainActivity mTestActivity;
+ private TextLinkifyFragment mTestFragment;
+
+ public SampleTests() {
+ super(MainActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // Starts the activity under test using the default Intent with:
+ // action = {@link Intent#ACTION_MAIN}
+ // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+ // All other fields are null or empty.
+ mTestActivity = getActivity();
+ mTestFragment = (TextLinkifyFragment)
+ mTestActivity.getSupportFragmentManager().getFragments().get(1);
+ }
+
+ /**
+ * Test if the test fixture has been set up correctly.
+ */
+ public void testPreconditions() {
+ //Try to add a message to add context to your assertions. These messages will be shown if
+ //a tests fails and make it easy to understand why a test failed
+ assertNotNull("mTestActivity is null", mTestActivity);
+ assertNotNull("mTestFragment is null", mTestFragment);
+ }
+
+ /**
+ * Add more tests below.
+ */
+
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/TextLinkify/build.gradle b/prebuilts/gradle/TextLinkify/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/TextLinkify/gradlew b/prebuilts/gradle/TextLinkify/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/TextLinkify/gradlew.bat b/prebuilts/gradle/TextLinkify/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/TextLinkify/settings.gradle b/prebuilts/gradle/TextLinkify/settings.gradle
new file mode 100644
index 0000000..38e7ddd
--- /dev/null
+++ b/prebuilts/gradle/TextLinkify/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'TextLinkifySample'
diff --git a/prebuilts/gradle/TextSwitcher/README.txt b/prebuilts/gradle/TextSwitcher/README.txt
new file mode 100644
index 0000000..9616c58
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/README.txt
@@ -0,0 +1,18 @@
+Build Instructions
+-------------------
+
+This sample uses the Gradle build system. To build this project, use the
+"gradlew build" command or use "Import Project" in Android Studio.
+
+To see a list of all available commands, run "gradlew tasks".
+
+Dependencies
+-------------
+
+- Android SDK Build-tools v18.1
+- Android Support Repository v2
+
+Dependencies are available for download via the Android SDK Manager.
+
+Android Studio is available for download at:
+ http://developer.android.com/sdk/installing/studio.html
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/build.gradle b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/build.gradle
new file mode 100644
index 0000000..5681239
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/build.gradle
@@ -0,0 +1,58 @@
+
+
+
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.8.+'
+ }
+}
+
+apply plugin: 'android'
+
+dependencies {
+ // Add the support lib that is appropriate for SDK 4
+ compile "com.android.support:support-v4:19.0.+"
+}
+
+// The sample build uses multiple directories to
+// keep boilerplate and common code separate from
+// the main sample code.
+List<String> dirs = [
+ 'main', // main sample code; look here for the interesting stuff.
+ 'common', // components that are reused by multiple samples
+ 'template'] // boilerplate code that is generated by the sample template process
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.1"
+
+ sourceSets {
+ main {
+ dirs.each { dir ->
+ java.srcDirs "src/${dir}/java"
+ res.srcDirs "src/${dir}/res"
+ }
+ }
+ instrumentTest.setRoot('tests')
+ instrumentTest.java.srcDirs = ['tests/src']
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/AndroidManifest.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..7f512a3
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.android.textswitcher"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="4"
+ android:targetSdkVersion="17" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".MainActivity"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/Log.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/Log.java
new file mode 100644
index 0000000..17503c5
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/Log.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Helper class for a list (or tree) of LoggerNodes.
+ *
+ * <p>When this is set as the head of the list,
+ * an instance of it can function as a drop-in replacement for {@link android.util.Log}.
+ * Most of the methods in this class server only to map a method call in Log to its equivalent
+ * in LogNode.</p>
+ */
+public class Log {
+ // Grabbing the native values from Android's native logging facilities,
+ // to make for easy migration and interop.
+ public static final int NONE = -1;
+ public static final int VERBOSE = android.util.Log.VERBOSE;
+ public static final int DEBUG = android.util.Log.DEBUG;
+ public static final int INFO = android.util.Log.INFO;
+ public static final int WARN = android.util.Log.WARN;
+ public static final int ERROR = android.util.Log.ERROR;
+ public static final int ASSERT = android.util.Log.ASSERT;
+
+ // Stores the beginning of the LogNode topology.
+ private static LogNode mLogNode;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public static LogNode getLogNode() {
+ return mLogNode;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to.
+ */
+ public static void setLogNode(LogNode node) {
+ mLogNode = node;
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void println(int priority, String tag, String msg, Throwable tr) {
+ if (mLogNode != null) {
+ mLogNode.println(priority, tag, msg, tr);
+ }
+ }
+
+ /**
+ * Instructs the LogNode to print the log data provided. Other LogNodes can
+ * be chained to the end of the LogNode as desired.
+ *
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ */
+ public static void println(int priority, String tag, String msg) {
+ println(priority, tag, msg, null);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void v(String tag, String msg, Throwable tr) {
+ println(VERBOSE, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at VERBOSE priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void v(String tag, String msg) {
+ v(tag, msg, null);
+ }
+
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void d(String tag, String msg, Throwable tr) {
+ println(DEBUG, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at DEBUG priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void d(String tag, String msg) {
+ d(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void i(String tag, String msg, Throwable tr) {
+ println(INFO, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at INFO priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void i(String tag, String msg) {
+ i(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, String msg, Throwable tr) {
+ println(WARN, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void w(String tag, String msg) {
+ w(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at WARN priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void w(String tag, Throwable tr) {
+ w(tag, null, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void e(String tag, String msg, Throwable tr) {
+ println(ERROR, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ERROR priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void e(String tag, String msg) {
+ e(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, String msg, Throwable tr) {
+ println(ASSERT, tag, msg, tr);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged.
+ */
+ public static void wtf(String tag, String msg) {
+ wtf(tag, msg, null);
+ }
+
+ /**
+ * Prints a message at ASSERT priority.
+ *
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public static void wtf(String tag, Throwable tr) {
+ wtf(tag, null, tr);
+ }
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogFragment.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogFragment.java
new file mode 100644
index 0000000..b302acd
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogFragment.java
@@ -0,0 +1,109 @@
+/*
+* Copyright 2013 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.
+*/
+/*
+ * Copyright 2013 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.common.logger;
+
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ScrollView;
+
+/**
+ * Simple fraggment which contains a LogView and uses is to output log data it receives
+ * through the LogNode interface.
+ */
+public class LogFragment extends Fragment {
+
+ private LogView mLogView;
+ private ScrollView mScrollView;
+
+ public LogFragment() {}
+
+ public View inflateViews() {
+ mScrollView = new ScrollView(getActivity());
+ ViewGroup.LayoutParams scrollParams = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ mScrollView.setLayoutParams(scrollParams);
+
+ mLogView = new LogView(getActivity());
+ ViewGroup.LayoutParams logParams = new ViewGroup.LayoutParams(scrollParams);
+ logParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ mLogView.setLayoutParams(logParams);
+ mLogView.setClickable(true);
+ mLogView.setFocusable(true);
+ mLogView.setTypeface(Typeface.MONOSPACE);
+
+ // Want to set padding as 16 dips, setPadding takes pixels. Hooray math!
+ int paddingDips = 16;
+ double scale = getResources().getDisplayMetrics().density;
+ int paddingPixels = (int) ((paddingDips * (scale)) + .5);
+ mLogView.setPadding(paddingPixels, paddingPixels, paddingPixels, paddingPixels);
+ mLogView.setCompoundDrawablePadding(paddingPixels);
+
+ mLogView.setGravity(Gravity.BOTTOM);
+ mLogView.setTextAppearance(getActivity(), android.R.style.TextAppearance_Holo_Medium);
+
+ mScrollView.addView(mLogView);
+ return mScrollView;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ View result = inflateViews();
+
+ mLogView.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
+ }
+ });
+ return result;
+ }
+
+ public LogView getLogView() {
+ return mLogView;
+ }
+}
\ No newline at end of file
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogNode.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogNode.java
new file mode 100644
index 0000000..bc37cab
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogNode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+/**
+ * Basic interface for a logging system that can output to one or more targets.
+ * Note that in addition to classes that will output these logs in some format,
+ * one can also implement this interface over a filter and insert that in the chain,
+ * such that no targets further down see certain data, or see manipulated forms of the data.
+ * You could, for instance, write a "ToHtmlLoggerNode" that just converted all the log data
+ * it received to HTML and sent it along to the next node in the chain, without printing it
+ * anywhere.
+ */
+public interface LogNode {
+
+ /**
+ * Instructs first LogNode in the list to print the log data provided.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ public void println(int priority, String tag, String msg, Throwable tr);
+
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogView.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogView.java
new file mode 100644
index 0000000..c01542b
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogView.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+import android.app.Activity;
+import android.content.Context;
+import android.util.*;
+import android.widget.TextView;
+
+/** Simple TextView which is used to output log data received through the LogNode interface.
+*/
+public class LogView extends TextView implements LogNode {
+
+ public LogView(Context context) {
+ super(context);
+ }
+
+ public LogView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public LogView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ /**
+ * Formats the log data and prints it out to the LogView.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+
+
+ String priorityStr = null;
+
+ // For the purposes of this View, we want to print the priority as readable text.
+ switch(priority) {
+ case android.util.Log.VERBOSE:
+ priorityStr = "VERBOSE";
+ break;
+ case android.util.Log.DEBUG:
+ priorityStr = "DEBUG";
+ break;
+ case android.util.Log.INFO:
+ priorityStr = "INFO";
+ break;
+ case android.util.Log.WARN:
+ priorityStr = "WARN";
+ break;
+ case android.util.Log.ERROR:
+ priorityStr = "ERROR";
+ break;
+ case android.util.Log.ASSERT:
+ priorityStr = "ASSERT";
+ break;
+ default:
+ break;
+ }
+
+ // Handily, the Log class has a facility for converting a stack trace into a usable string.
+ String exceptionStr = null;
+ if (tr != null) {
+ exceptionStr = android.util.Log.getStackTraceString(tr);
+ }
+
+ // Take the priority, tag, message, and exception, and concatenate as necessary
+ // into one usable line of text.
+ final StringBuilder outputBuilder = new StringBuilder();
+
+ String delimiter = "\t";
+ appendIfNotNull(outputBuilder, priorityStr, delimiter);
+ appendIfNotNull(outputBuilder, tag, delimiter);
+ appendIfNotNull(outputBuilder, msg, delimiter);
+ appendIfNotNull(outputBuilder, exceptionStr, delimiter);
+
+ // In case this was originally called from an AsyncTask or some other off-UI thread,
+ // make sure the update occurs within the UI thread.
+ ((Activity) getContext()).runOnUiThread( (new Thread(new Runnable() {
+ @Override
+ public void run() {
+ // Display the text we just generated within the LogView.
+ appendToLog(outputBuilder.toString());
+ }
+ })));
+
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /** Takes a string and adds to it, with a separator, if the bit to be added isn't null. Since
+ * the logger takes so many arguments that might be null, this method helps cut out some of the
+ * agonizing tedium of writing the same 3 lines over and over.
+ * @param source StringBuilder containing the text to append to.
+ * @param addStr The String to append
+ * @param delimiter The String to separate the source and appended strings. A tab or comma,
+ * for instance.
+ * @return The fully concatenated String as a StringBuilder
+ */
+ private StringBuilder appendIfNotNull(StringBuilder source, String addStr, String delimiter) {
+ if (addStr != null) {
+ if (addStr.length() == 0) {
+ delimiter = "";
+ }
+
+ return source.append(addStr).append(delimiter);
+ }
+ return source;
+ }
+
+ // The next LogNode in the chain.
+ LogNode mNext;
+
+ /** Outputs the string as a new line of log data in the LogView. */
+ public void appendToLog(String s) {
+ append("\n" + s);
+ }
+
+
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogWrapper.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogWrapper.java
new file mode 100644
index 0000000..16a9e7b
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/LogWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.common.logger;
+
+import android.util.Log;
+
+/**
+ * Helper class which wraps Android's native Log utility in the Logger interface. This way
+ * normal DDMS output can be one of the many targets receiving and outputting logs simultaneously.
+ */
+public class LogWrapper implements LogNode {
+
+ // For piping: The next node to receive Log data after this one has done its work.
+ private LogNode mNext;
+
+ /**
+ * Returns the next LogNode in the linked list.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+ /**
+ * Prints data out to the console using Android's native log mechanism.
+ * @param priority Log level of the data being logged. Verbose, Error, etc.
+ * @param tag Tag for for the log data. Can be used to organize log statements.
+ * @param msg The actual message to be logged. The actual message to be logged.
+ * @param tr If an exception was thrown, this can be sent along for the logging facilities
+ * to extract and print useful information.
+ */
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ // There actually are log methods that don't take a msg parameter. For now,
+ // if that's the case, just convert null to the empty string and move on.
+ String useMsg = msg;
+ if (useMsg == null) {
+ useMsg = "";
+ }
+
+ // If an exeption was provided, convert that exception to a usable string and attach
+ // it to the end of the msg method.
+ if (tr != null) {
+ msg += "\n" + Log.getStackTraceString(tr);
+ }
+
+ // This is functionally identical to Log.x(tag, useMsg);
+ // For instance, if priority were Log.VERBOSE, this would be the same as Log.v(tag, useMsg)
+ Log.println(priority, tag, useMsg);
+
+ // If this isn't the last node in the chain, move things along.
+ if (mNext != null) {
+ mNext.println(priority, tag, msg, tr);
+ }
+ }
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
new file mode 100644
index 0000000..19967dc
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/common/logger/MessageOnlyLogFilter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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.common.logger;
+
+/**
+ * Simple {@link LogNode} filter, removes everything except the message.
+ * Useful for situations like on-screen log output where you don't want a lot of metadata displayed,
+ * just easy-to-read message updates as they're happening.
+ */
+public class MessageOnlyLogFilter implements LogNode {
+
+ LogNode mNext;
+
+ /**
+ * Takes the "next" LogNode as a parameter, to simplify chaining.
+ *
+ * @param next The next LogNode in the pipeline.
+ */
+ public MessageOnlyLogFilter(LogNode next) {
+ mNext = next;
+ }
+
+ public MessageOnlyLogFilter() {
+ }
+
+ @Override
+ public void println(int priority, String tag, String msg, Throwable tr) {
+ if (mNext != null) {
+ getNext().println(Log.NONE, null, msg, null);
+ }
+ }
+
+ /**
+ * Returns the next LogNode in the chain.
+ */
+ public LogNode getNext() {
+ return mNext;
+ }
+
+ /**
+ * Sets the LogNode data will be sent to..
+ */
+ public void setNext(LogNode node) {
+ mNext = node;
+ }
+
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/textswitcher/MainActivity.java b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/textswitcher/MainActivity.java
new file mode 100644
index 0000000..a8cbb5e
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/java/com/example/android/textswitcher/MainActivity.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 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.textswitcher;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.Button;
+import android.widget.TextSwitcher;
+import android.widget.TextView;
+import android.widget.ViewSwitcher.ViewFactory;
+
+/**
+ * This sample shows the use of the {@link android.widget.TextSwitcher} View with animations. A
+ * {@link android.widget.TextSwitcher} is a special type of {@link android.widget.ViewSwitcher} that animates
+ * the current text out and new text in when
+ * {@link android.widget.TextSwitcher#setText(CharSequence)} is called.
+ */
+public class MainActivity extends Activity {
+ private TextSwitcher mSwitcher;
+ private int mCounter = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.sample_main);
+
+ // Get the TextSwitcher view from the layout
+ mSwitcher = (TextSwitcher) findViewById(R.id.switcher);
+
+ // BEGIN_INCLUDE(setup)
+ // Set the factory used to create TextViews to switch between.
+ mSwitcher.setFactory(mFactory);
+
+ /*
+ * Set the in and out animations. Using the fade_in/out animations
+ * provided by the framework.
+ */
+ Animation in = AnimationUtils.loadAnimation(this,
+ android.R.anim.fade_in);
+ Animation out = AnimationUtils.loadAnimation(this,
+ android.R.anim.fade_out);
+ mSwitcher.setInAnimation(in);
+ mSwitcher.setOutAnimation(out);
+ // END_INCLUDE(setup)
+
+ /*
+ * Setup the 'next' button. The counter is incremented when clicked and
+ * the new value is displayed in the TextSwitcher. The change of text is
+ * automatically animated using the in/out animations set above.
+ */
+ Button nextButton = (Button) findViewById(R.id.button);
+ nextButton.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ mCounter++;
+ // BEGIN_INCLUDE(settext)
+ mSwitcher.setText(String.valueOf(mCounter));
+ // END_INCLUDE(settext)
+ }
+ });
+
+ // Set the initial text without an animation
+ mSwitcher.setCurrentText(String.valueOf(mCounter));
+
+ }
+
+ // BEGIN_INCLUDE(factory)
+ /**
+ * The {@link android.widget.ViewSwitcher.ViewFactory} used to create {@link android.widget.TextView}s that the
+ * {@link android.widget.TextSwitcher} will switch between.
+ */
+ private ViewFactory mFactory = new ViewFactory() {
+
+ @Override
+ public View makeView() {
+
+ // Create a new TextView
+ TextView t = new TextView(MainActivity.this);
+ t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
+ t.setTextAppearance(MainActivity.this, android.R.style.TextAppearance_Large);
+ return t;
+ }
+ };
+ // END_INCLUDE(factory)
+}
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/ic_launcher.png b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..641bab2
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/tile.9.png b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/tile.9.png
new file mode 100644
index 0000000..1358628
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-hdpi/tile.9.png
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-mdpi/ic_launcher.png b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..e29c59f
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xhdpi/ic_launcher.png b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d23193b
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xxhdpi/ic_launcher.png b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..22bfd45
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/activity_main.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..be1aa49
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,36 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout style="@style/Widget.SampleMessageTile"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView style="@style/Widget.SampleMessage"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/horizontal_page_margin"
+ android:layout_marginRight="@dimen/horizontal_page_margin"
+ android:layout_marginTop="@dimen/vertical_page_margin"
+ android:layout_marginBottom="@dimen/vertical_page_margin"
+ android:text="@string/intro_message" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/sample_main.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/sample_main.xml
new file mode 100644
index 0000000..a5a7053
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/layout/sample_main.xml
@@ -0,0 +1,47 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/LinearLayout1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top|center_horizontal"
+ android:gravity="center_horizontal"
+ android:orientation="vertical"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context=".MainActivity" >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/intro" />
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/next" />
+
+ <TextSwitcher
+ android:id="@+id/switcher"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/dimens.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..686fe89
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw600dp devices (e.g. 7" tablets) here.
+ -->
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-dimens.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-dimens.xml
new file mode 100644
index 0000000..22074a2
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-dimens.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-styles.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-styles.xml
new file mode 100644
index 0000000..03d1974
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw600dp/template-styles.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceLarge</item>
+ <item name="android:lineSpacingMultiplier">1.2</item>
+ <item name="android:shadowDy">-6.5</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw720dp-land/dimens.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw720dp-land/dimens.xml
new file mode 100644
index 0000000..560bd44
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+ -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v11/styles.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v11/styles.xml
new file mode 100644
index 0000000..91f4523
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v11/styles.xml
@@ -0,0 +1,27 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v14/styles.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v14/styles.xml
new file mode 100644
index 0000000..c2b6a6b
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values-v14/styles.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/base-strings.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/base-strings.xml
new file mode 100644
index 0000000..2497e86
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/base-strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+
+
+<resources>
+ <string name="app_name">TextSwitcher</string>
+ <string name="intro_message">
+ <![CDATA[
+
+
+ This sample illustrates the use of a TextSwitcher to display text.
+ \n\nClick the button below to set new text in the TextSwitcher and observe the
+ in and out fade animations.
+
+
+ ]]>
+ </string>
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/dimens.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..3b1975a
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/strings.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..612b6cb
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2013 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.
+-->
+
+<resources>
+
+ <string name="intro">This sample illustrates the use of a <b>TextSwitcher</b> to display text.
+\n\n<b>Click the button</b> below to set new text in the TextSwitcher and observe the in and out
+ fade animations.</string>
+ <string name="next">Next</string>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-dimens.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-dimens.xml
new file mode 100644
index 0000000..39e710b
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-dimens.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
+
+ <dimen name="margin_tiny">4dp</dimen>
+ <dimen name="margin_small">8dp</dimen>
+ <dimen name="margin_medium">16dp</dimen>
+ <dimen name="margin_large">32dp</dimen>
+ <dimen name="margin_huge">64dp</dimen>
+
+ <!-- Semantic definitions -->
+
+ <dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
+ <dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-styles.xml b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-styles.xml
new file mode 100644
index 0000000..404623e
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/TextSwitcherSample/src/main/res/values/template-styles.xml
@@ -0,0 +1,42 @@
+<!--
+ Copyright 2013 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.
+ -->
+
+<resources>
+
+ <!-- Activity themes -->
+
+ <style name="Theme.Base" parent="android:Theme.Holo.Light" />
+
+ <style name="Theme.Sample" parent="Theme.Base" />
+
+ <style name="AppTheme" parent="Theme.Sample" />
+ <!-- Widget styling -->
+
+ <style name="Widget" />
+
+ <style name="Widget.SampleMessage">
+ <item name="android:textAppearance">?android:textAppearanceMedium</item>
+ <item name="android:lineSpacingMultiplier">1.1</item>
+ </style>
+
+ <style name="Widget.SampleMessageTile">
+ <item name="android:background">@drawable/tile</item>
+ <item name="android:shadowColor">#7F000000</item>
+ <item name="android:shadowDy">-3.5</item>
+ <item name="android:shadowRadius">2</item>
+ </style>
+
+</resources>
diff --git a/prebuilts/gradle/TextSwitcher/build.gradle b/prebuilts/gradle/TextSwitcher/build.gradle
new file mode 100644
index 0000000..584ba87
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/build.gradle
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.jar b/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..8c0fb64
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.properties b/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..861eddc
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Apr 10 15:27:10 PDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/prebuilts/gradle/TextSwitcher/gradlew b/prebuilts/gradle/TextSwitcher/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/prebuilts/gradle/TextSwitcher/gradlew.bat b/prebuilts/gradle/TextSwitcher/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/prebuilts/gradle/TextSwitcher/settings.gradle b/prebuilts/gradle/TextSwitcher/settings.gradle
new file mode 100644
index 0000000..6740a95
--- /dev/null
+++ b/prebuilts/gradle/TextSwitcher/settings.gradle
@@ -0,0 +1,4 @@
+
+
+
+include 'TextSwitcherSample'
diff --git a/templates/base/_MODULE_/build.gradle.ftl b/templates/base/_MODULE_/build.gradle.ftl
index 8c7ced1..3842a46 100644
--- a/templates/base/_MODULE_/build.gradle.ftl
+++ b/templates/base/_MODULE_/build.gradle.ftl
@@ -19,7 +19,7 @@
}
dependencies {
- classpath 'com.android.tools.build:gradle:0.6.+'
+ classpath 'com.android.tools.build:gradle:0.8.+'
}
}
@@ -27,20 +27,23 @@
dependencies {
<#if !sample.auto_add_support_lib?has_content || sample.auto_add_support_lib == "true">
- // Add the support lib that is appropriate for SDK ${sample.minSdk}
+ // Add the support lib that is appropriate for SDK ${sample.minSdk}
<#if sample.minSdk?number < 7>
- compile "com.android.support:support-v4:18.0.+"
+ compile "com.android.support:support-v4:19.0.+"
<#elseif sample.minSdk?number < 13>
- compile "com.android.support:support-v4:18.0.+"
- compile "com.android.support:gridlayout-v7:18.0.+"
+ compile "com.android.support:support-v4:19.0.+"
+ compile "com.android.support:gridlayout-v7:19.0.+"
<#else>
- compile "com.android.support:support-v13:18.0.+"
+ compile "com.android.support:support-v13:19.0.+"
</#if>
</#if>
<#list sample.dependency as dep>
compile "${dep}"
</#list>
+<#list sample.dependency_external as dep>
+ compile files(${dep})
+</#list>
}
// The sample build uses multiple directories to
@@ -55,7 +58,7 @@
<#-- Note that target SDK is hardcoded in this template. We expect all samples
to always use the most current SDK as their target. -->
compileSdkVersion ${compile_sdk}
- buildToolsVersion "19"
+ buildToolsVersion "19.0.1"
sourceSets {
main {
@@ -68,6 +71,13 @@
}
instrumentTest.setRoot('tests')
instrumentTest.java.srcDirs = ['tests/src']
+
+<#if sample.defaultConfig?has_content>
+ defaultConfig {
+ ${sample.defaultConfig}
+ }
+<#else>
+</#if>
}
}
// BEGIN_EXCLUDE
diff --git a/templates/create/_MODULE_/build.gradle.ftl b/templates/create/_MODULE_/build.gradle.ftl
index e81142b..fd3461a 100644
--- a/templates/create/_MODULE_/build.gradle.ftl
+++ b/templates/create/_MODULE_/build.gradle.ftl
@@ -25,7 +25,7 @@
}
dependencies {
- classpath 'com.android.tools.build:gradle:0.6.+'
+ classpath 'com.android.tools.build:gradle:0.8.+'
}
}
diff --git a/templates/create/gradle/wrapper/gradle-wrapper.properties b/templates/create/gradle/wrapper/gradle-wrapper.properties
index 861eddc..56f685a 100644
--- a/templates/create/gradle/wrapper/gradle-wrapper.properties
+++ b/templates/create/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-bin.zip
diff --git a/templates/include/common.ftl b/templates/include/common.ftl
index 59f6410..0cc5add 100644
--- a/templates/include/common.ftl
+++ b/templates/include/common.ftl
@@ -44,4 +44,4 @@
<#-- Set the global build tools version -->
-<#assign build_tools_version='"18.1"'/>
+<#assign build_tools_version='"19.0.1"'/>