diff options
author | Rob Tsuk <robtsuk@google.com> | 2012-06-26 13:55:12 -0700 |
---|---|---|
committer | Rob Tsuk <robtsuk@google.com> | 2012-06-26 14:22:37 -0700 |
commit | e4604930eb7f31d67afbf3eebb654485b5cfe6f1 (patch) | |
tree | fcd2ae890cc566d42518316c9ee6aa7b9a8edbbe | |
parent | 780257c6a6dc8a971731c1fc0f810c4348397aa6 (diff) | |
download | adk2012-master.tar.gz |
Change-Id: I79d3421ecac1a5258ed4bfe7703479c225d2fc1e
101 files changed, 4451 insertions, 5 deletions
diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..3f9691c --- /dev/null +++ b/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> + <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="gen"/> + <classpathentry kind="output" path="bin/classes"/> +</classpath> @@ -1,5 +1,2 @@ -*.swp -*~ -TAGS -tags -cscope.out +bin/ +gen/
\ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..584b9d9 --- /dev/null +++ b/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>ADK 2012</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.android.ide.eclipse.adt.ApkBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>com.android.ide.eclipse.adt.AndroidNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..f1a7d20 --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.android.apps.adk2" + android:versionCode="1" + android:versionName="1.0" > + + <uses-sdk + android:minSdkVersion="10" + android:targetSdkVersion="15" /> + + <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + + <uses-feature + android:name="android.hardware.usb.accessory" + android:required="true" /> + + <application + android:hardwareAccelerated="true" + android:icon="@drawable/ic_launcher_adk" + android:label="@string/app_short_name" + android:theme="@style/Theme.ADK2" > + <uses-library android:name="com.android.future.usb.accessory" /> + + <activity + android:name=".activity.ConnectActivity" + android:label="@string/app_short_name" + android:screenOrientation="portrait" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity + android:name=".activity.BTDeviceListActivity" + android:label="@string/bluetooth" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.HomeActivity" + android:label="@string/app_short_name" + android:screenOrientation="portrait" > + </activity> + <activity + android:name=".activity.AlarmActivity" + android:label="@string/alarm" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ClockActivity" + android:label="@string/clock" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.VolumeActivity" + android:label="@string/volume" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ColorActivity" + android:label="@string/color" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ColorRGBActivity" + android:label="@string/color" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ColorCameraActivity" + android:label="@string/color" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ColorSensorActivity" + android:label="@string/color_sensor" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.ColorCombinationsActivity" + android:label="@string/color_combinations" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.BrightnessActivity" + android:label="@string/brightness" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.DisplayActivity" + android:label="@string/display" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.PresetsActivity" + android:label="@string/presets" + android:screenOrientation="portrait" /> + <activity + android:name=".activity.LicenseActivity" + android:label="@string/licenses" + android:screenOrientation="portrait" /> + <activity + android:name="USBAccessoryActivity" + android:label="@string/app_long_name" + android:launchMode="singleInstance" + android:taskAffinity="" > + <intent-filter> + <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" /> + </intent-filter> + + <meta-data + android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" + android:resource="@xml/usb_accessory_filter" /> + </activity> + </application> + +</manifest>
\ No newline at end of file diff --git a/lint.xml b/lint.xml new file mode 100644 index 0000000..b0d4a8d --- /dev/null +++ b/lint.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lint> + <issue id="Deprecated" severity="informational" /> +</lint>
\ No newline at end of file diff --git a/proguard-project.txt b/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/project.properties b/project.properties new file mode 100644 index 0000000..e0a848d --- /dev/null +++ b/project.properties @@ -0,0 +1,14 @@ +# 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=Google Inc.:Google APIs:15 diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..99b9c53 --- /dev/null +++ b/res/drawable-hdpi/ic_launcher.png diff --git a/res/drawable-hdpi/ic_launcher_adk.png b/res/drawable-hdpi/ic_launcher_adk.png Binary files differnew file mode 100644 index 0000000..dcff319 --- /dev/null +++ b/res/drawable-hdpi/ic_launcher_adk.png diff --git a/res/drawable-hdpi/scrubber_control_holo_dark.png b/res/drawable-hdpi/scrubber_control_holo_dark.png Binary files differnew file mode 100644 index 0000000..5947ee1 --- /dev/null +++ b/res/drawable-hdpi/scrubber_control_holo_dark.png diff --git a/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..1dcd3b0 --- /dev/null +++ b/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..6221a0f --- /dev/null +++ b/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..6a162ed --- /dev/null +++ b/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..b785ebd --- /dev/null +++ b/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..5a22af5 --- /dev/null +++ b/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..1ebd9f6 --- /dev/null +++ b/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png diff --git a/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..74800a4 --- /dev/null +++ b/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png diff --git a/res/drawable-ldpi/ic_launcher.png b/res/drawable-ldpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..bb4cf8e --- /dev/null +++ b/res/drawable-ldpi/ic_launcher.png diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..831e794 --- /dev/null +++ b/res/drawable-mdpi/ic_launcher.png diff --git a/res/drawable-mdpi/ic_launcher_adk.png b/res/drawable-mdpi/ic_launcher_adk.png Binary files differnew file mode 100644 index 0000000..3e7e712 --- /dev/null +++ b/res/drawable-mdpi/ic_launcher_adk.png diff --git a/res/drawable-mdpi/scrubber_control_holo_dark.png b/res/drawable-mdpi/scrubber_control_holo_dark.png Binary files differnew file mode 100644 index 0000000..90ece2a --- /dev/null +++ b/res/drawable-mdpi/scrubber_control_holo_dark.png diff --git a/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..3a7665b --- /dev/null +++ b/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..dac988a --- /dev/null +++ b/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..ce62fbe --- /dev/null +++ b/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..bd349fd --- /dev/null +++ b/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..fd9ca52 --- /dev/null +++ b/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..f5cc83e --- /dev/null +++ b/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png diff --git a/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..26eaa3d --- /dev/null +++ b/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png diff --git a/res/drawable-xhdpi/ab_rainbow_bg.9.png b/res/drawable-xhdpi/ab_rainbow_bg.9.png Binary files differnew file mode 100644 index 0000000..7db3425 --- /dev/null +++ b/res/drawable-xhdpi/ab_rainbow_bg.9.png diff --git a/res/drawable-xhdpi/adk_outline.png b/res/drawable-xhdpi/adk_outline.png Binary files differnew file mode 100644 index 0000000..a270793 --- /dev/null +++ b/res/drawable-xhdpi/adk_outline.png diff --git a/res/drawable-xhdpi/ic_alarm.png b/res/drawable-xhdpi/ic_alarm.png Binary files differnew file mode 100644 index 0000000..bebd61e --- /dev/null +++ b/res/drawable-xhdpi/ic_alarm.png diff --git a/res/drawable-xhdpi/ic_brightness.png b/res/drawable-xhdpi/ic_brightness.png Binary files differnew file mode 100644 index 0000000..d46da9f --- /dev/null +++ b/res/drawable-xhdpi/ic_brightness.png diff --git a/res/drawable-xhdpi/ic_clock.png b/res/drawable-xhdpi/ic_clock.png Binary files differnew file mode 100644 index 0000000..524f073 --- /dev/null +++ b/res/drawable-xhdpi/ic_clock.png diff --git a/res/drawable-xhdpi/ic_color.png b/res/drawable-xhdpi/ic_color.png Binary files differnew file mode 100644 index 0000000..4de662c --- /dev/null +++ b/res/drawable-xhdpi/ic_color.png diff --git a/res/drawable-xhdpi/ic_display.png b/res/drawable-xhdpi/ic_display.png Binary files differnew file mode 100644 index 0000000..867bfb3 --- /dev/null +++ b/res/drawable-xhdpi/ic_display.png diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..42b2269 --- /dev/null +++ b/res/drawable-xhdpi/ic_launcher.png diff --git a/res/drawable-xhdpi/ic_launcher_adk.png b/res/drawable-xhdpi/ic_launcher_adk.png Binary files differnew file mode 100644 index 0000000..c762de0 --- /dev/null +++ b/res/drawable-xhdpi/ic_launcher_adk.png diff --git a/res/drawable-xhdpi/ic_lock.png b/res/drawable-xhdpi/ic_lock.png Binary files differnew file mode 100644 index 0000000..bba0c72 --- /dev/null +++ b/res/drawable-xhdpi/ic_lock.png diff --git a/res/drawable-xhdpi/ic_presets.png b/res/drawable-xhdpi/ic_presets.png Binary files differnew file mode 100644 index 0000000..d8d6be8 --- /dev/null +++ b/res/drawable-xhdpi/ic_presets.png diff --git a/res/drawable-xhdpi/ic_unlock.png b/res/drawable-xhdpi/ic_unlock.png Binary files differnew file mode 100644 index 0000000..f8860a2 --- /dev/null +++ b/res/drawable-xhdpi/ic_unlock.png diff --git a/res/drawable-xhdpi/ic_volume.png b/res/drawable-xhdpi/ic_volume.png Binary files differnew file mode 100644 index 0000000..8e8784d --- /dev/null +++ b/res/drawable-xhdpi/ic_volume.png diff --git a/res/drawable/home_button_bg.xml b/res/drawable/home_button_bg.xml new file mode 100644 index 0000000..2428828 --- /dev/null +++ b/res/drawable/home_button_bg.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@color/home_button_pressed" /> + <item android:drawable="@color/home_button_normal" /> +</selector>
\ No newline at end of file diff --git a/res/layout/alert_dialog.xml b/res/layout/alert_dialog.xml new file mode 100644 index 0000000..f8c0aed --- /dev/null +++ b/res/layout/alert_dialog.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:id="@+id/username_view" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginLeft="20dip" + android:layout_marginRight="20dip" + android:text="@string/set_bt_name_title" + android:gravity="left" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <EditText + android:id="@+id/btname_edit" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:layout_marginLeft="20dip" + android:layout_marginRight="20dip" + android:scrollHorizontally="true" + android:autoText="false" + android:capitalize="none" + android:gravity="fill_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/color_camera.xml b/res/layout/color_camera.xml new file mode 100644 index 0000000..87a9157 --- /dev/null +++ b/res/layout/color_camera.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<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" + > + + <RelativeLayout + android:id="@+id/camera_frame" + android:layout_width="match_parent" + android:layout_height="300dip" + > + + <SurfaceView + android:id="@+id/camera_surface" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerInParent="true" + /> + + <View tools:ignore="PxUsage" + android:layout_width="40px" + android:layout_height="40px" + android:layout_centerInParent="true" + android:background="#ff000000" + /> + + <View tools:ignore="PxUsage" + android:id="@+id/sample_preview" + android:layout_width="160px" + android:layout_height="160px" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:visible="false" + /> + + </RelativeLayout> + + <Button + android:id="@+id/color_sample_button" + android:layout_width="50dip" + android:layout_height="50dip" + android:layout_below="@+id/camera_frame" + android:layout_centerHorizontal="true" + /> + +</RelativeLayout>
\ No newline at end of file diff --git a/res/layout/color_combinations.xml b/res/layout/color_combinations.xml new file mode 100644 index 0000000..a29713f --- /dev/null +++ b/res/layout/color_combinations.xml @@ -0,0 +1,77 @@ +<?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:padding="25dip" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="64dp" > + + <View + android:id="@+id/color_combo1" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@color/combination_color" /> + + <View + android:id="@+id/color_combo2" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@color/combination_color" /> + + <View + android:id="@+id/color_combo3" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@color/combination_color" /> + + <View + android:id="@+id/color_combo4" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@color/combination_color" /> + + <View + android:id="@+id/color_combo5" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="@color/combination_color" /> + </LinearLayout> + + <RadioGroup + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/color_combination_group" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="25dip" > + + <RadioButton + android:id="@+id/radio_monochromatic" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/monochromatic" /> + + <RadioButton + android:id="@+id/radio_analogous" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/analogous" /> + + <RadioButton + android:id="@+id/radio_triad" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/triad" /> + </RadioGroup> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/color_rgb.xml b/res/layout/color_rgb.xml new file mode 100644 index 0000000..6236391 --- /dev/null +++ b/res/layout/color_rgb.xml @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="utf-8"?> +<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:orientation="vertical" + android:padding="25dip" + tools:ignore="NestedWeights" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="25dip" + android:orientation="horizontal" > + + <View + android:id="@+id/original_color" + android:layout_width="0dip" + android:layout_height="50dip" + android:layout_weight="1" + android:background="#ff0000" /> + + <View + android:id="@+id/new_color" + android:layout_width="0dip" + android:layout_height="50dip" + android:layout_weight="1" + android:background="#ffff00" /> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="25dip" + android:orientation="horizontal" > + + <TextView + android:id="@+id/color_hex" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1.5" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:id="@+id/color_r" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:id="@+id/color_g" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:id="@+id/color_b" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + </LinearLayout> + + <com.google.android.apps.adk2.views.Slider + android:id="@+id/seek_bar_r" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="25dip" /> + + <com.google.android.apps.adk2.views.Slider + android:id="@+id/seek_bar_g" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="25dip" /> + + <com.google.android.apps.adk2.views.Slider + android:id="@+id/seek_bar_b" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="25dip" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/color_sensor.xml b/res/layout/color_sensor.xml new file mode 100644 index 0000000..dcff0ae --- /dev/null +++ b/res/layout/color_sensor.xml @@ -0,0 +1,43 @@ +<?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" > + + <View + android:layout_width="0dip" + android:layout_height="0dip" + android:layout_weight="1" + android:gravity="center" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="10dip" + android:gravity="center" + android:text="@string/capture_prompt" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <com.google.android.apps.adk2.views.ColorSensorView + android:id="@+id/color_sensor_view" + android:layout_width="200dip" + android:layout_height="200dip" + android:layout_gravity="center" + android:layout_margin="25dip" + android:gravity="center" /> + + <Button + android:id="@+id/color_sample_button" + android:layout_width="match_parent" + android:layout_height="80dip" + android:layout_margin="25dip" + android:gravity="center" + android:text="@string/capture" /> + + <View + android:layout_width="0dip" + android:layout_height="0dip" + android:layout_weight="1" + android:gravity="center" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/connect.xml b/res/layout/connect.xml new file mode 100644 index 0000000..2aefb0f --- /dev/null +++ b/res/layout/connect.xml @@ -0,0 +1,63 @@ +<?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:padding="5dp" > + + <View + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:text="@string/connect_please" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <View + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <ImageView + android:id="@+id/imageView1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:contentDescription="@string/adk_description" + android:src="@drawable/adk_outline" /> + + <View + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:text="@string/plug_in_or_use_bluetooth" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <View + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + + <Button + android:id="@+id/connect_bluetooth_button" + android:layout_width="match_parent" + android:layout_height="80dip" + android:layout_margin="25dip" + android:gravity="center" + android:text="@string/bluetooth" /> + + <View + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/device_list.xml b/res/layout/device_list.xml new file mode 100644 index 0000000..866d36e --- /dev/null +++ b/res/layout/device_list.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/title_paired_devices" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/title_paired_devices" + android:textAppearance="?android:attr/textAppearanceLarge" + android:visibility="gone" /> + + <ListView + android:id="@+id/paired_devices" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/device_name.xml b/res/layout/device_name.xml new file mode 100644 index 0000000..8fa358c --- /dev/null +++ b/res/layout/device_name.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:padding="5dp" +/>
\ No newline at end of file diff --git a/res/layout/display.xml b/res/layout/display.xml new file mode 100644 index 0000000..d30ad23 --- /dev/null +++ b/res/layout/display.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/display_group" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:padding="25dip" > + + <!-- + AdkShowAnimation, + AdkShowAccel, + AdkShowMag, + AdkShowTemp, + AdkShowHygro, + AdkShowBaro, + AdkShowProx, + AdkShowColor, + --> + + <RadioButton + android:id="@+id/radio_animation" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/leds_animation" /> + + <RadioButton + android:id="@+id/radio_accell" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/accel" /> + + <RadioButton + android:id="@+id/radio_mag" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/mag" /> + + <RadioButton + android:id="@+id/radio_temperature" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/temperature" /> + + <RadioButton + android:id="@+id/radio_hygro" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/hygro" /> + + <RadioButton + android:id="@+id/radio_baro" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/baro" /> + + <RadioButton + android:id="@+id/radio_prox" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/prox" /> + + <RadioButton + android:id="@+id/radio_color" + style="@android:style/TextAppearance.DeviceDefault.Large" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/color" /> + +</RadioGroup>
\ No newline at end of file diff --git a/res/layout/home.xml b/res/layout/home.xml new file mode 100644 index 0000000..b0c5133 --- /dev/null +++ b/res/layout/home.xml @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<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:orientation="vertical" + > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:orientation="horizontal" + > + + <include + tools:ignore="NestedWeights" + layout="@layout/home_button" + android:id="@+id/clock_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + <View tools:ignore="PxUsage" + android:layout_width="1px" + android:layout_height="match_parent" + android:background="@color/home_activity_divider" + /> + + <include layout="@layout/home_button" + android:id="@+id/alarm_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + </LinearLayout> + + <View tools:ignore="PxUsage" + android:layout_width="match_parent" + android:layout_height="1px" + android:background="@color/home_activity_divider" + /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:orientation="horizontal" + > + + <include + tools:ignore="NestedWeights" + layout="@layout/home_button" + android:id="@+id/volume_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + <View + tools:ignore="PxUsage" + android:layout_width="1px" + android:layout_height="match_parent" + android:background="@color/home_activity_divider" + /> + + <include + layout="@layout/home_button" + android:id="@+id/color_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + </LinearLayout> + + <View + tools:ignore="PxUsage" + android:layout_width="match_parent" + android:layout_height="1px" + android:background="@color/home_activity_divider" + /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:orientation="horizontal" + > + + <include + tools:ignore="NestedWeights" + layout="@layout/home_button" + android:id="@+id/brightness_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + <View tools:ignore="PxUsage" + android:layout_width="1px" + android:layout_height="match_parent" + android:background="@color/home_activity_divider" + /> + + <include + layout="@layout/home_button" + android:id="@+id/display_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + </LinearLayout> + + <View + tools:ignore="PxUsage" + android:layout_width="match_parent" + android:layout_height="1px" + android:background="@color/home_activity_divider" + /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:orientation="horizontal" + > + + <include + tools:ignore="NestedWeights" + layout="@layout/home_button" + android:id="@+id/presets_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + <View + tools:ignore="PxUsage" + android:layout_width="1px" + android:layout_height="match_parent" + android:background="@color/home_activity_divider" + /> + + <include + layout="@layout/home_button" + android:id="@+id/lock_button" + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + /> + + </LinearLayout> + + <View + tools:ignore="PxUsage" + android:layout_width="match_parent" + android:layout_height="1px" + android:background="@color/home_activity_divider" + /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/home_button.xml b/res/layout/home_button.xml new file mode 100644 index 0000000..1854d55 --- /dev/null +++ b/res/layout/home_button.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<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:orientation="vertical" + android:background="@drawable/home_button_bg" + android:clickable="true" + > + + <ImageView tools:ignore="ContentDescription" + android:id="@+id/icon" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginBottom="14dip" + android:scaleType="center" + /> + + <TextView + android:id="@+id/label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_alignParentBottom="true" + android:layout_marginBottom="14dip" + android:textColor="@color/home_button_label" + /> + +</RelativeLayout> diff --git a/res/layout/licenses.xml b/res/layout/licenses.xml new file mode 100644 index 0000000..7bd39d6 --- /dev/null +++ b/res/layout/licenses.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/license_scroll" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/license_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + </TextView> + +</ScrollView>
\ No newline at end of file diff --git a/res/layout/preset_name_dialog.xml b/res/layout/preset_name_dialog.xml new file mode 100644 index 0000000..339bb73 --- /dev/null +++ b/res/layout/preset_name_dialog.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/preset_name_root_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:padding="10dp" > + + <TextView + android:id="@+id/preset_name_label" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/name" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <EditText + android:id="@+id/preset_name_edit" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="text" > + + <requestFocus /> + </EditText> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + <Button + android:id="@+id/preset_edit_cancel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@android:string/cancel" /> + + <Button + android:id="@+id/preset_edit_rename" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/rename" /> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/presets.xml b/res/layout/presets.xml new file mode 100644 index 0000000..0a7d73a --- /dev/null +++ b/res/layout/presets.xml @@ -0,0 +1,21 @@ +<?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" > + + <ListView + android:id="@android:id/list" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:drawSelectorOnTop="false" + android:choiceMode="multipleChoiceModal" /> + + <TextView + android:id="@android:id/empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:text="@string/no_presets" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/seekbar_preference.xml b/res/layout/seekbar_preference.xml new file mode 100644 index 0000000..2fc3a29 --- /dev/null +++ b/res/layout/seekbar_preference.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="10dip" + android:paddingLeft="8dip" + android:paddingBottom="14dip" + android:paddingRight="?android:attr/scrollbarSize" + > + + <TextView android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + + <SeekBar android:id="@+id/seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="12dip" + android:layout_below="@android:id/title" + android:layout_alignLeft="@android:id/title" + /> +</RelativeLayout> diff --git a/res/layout/time_dialog.xml b/res/layout/time_dialog.xml new file mode 100644 index 0000000..3ef9dd2 --- /dev/null +++ b/res/layout/time_dialog.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + > + + <TimePicker android:id="@+id/time_picker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/menu/home_menu.xml b/res/menu/home_menu.xml new file mode 100644 index 0000000..ca6d261 --- /dev/null +++ b/res/menu/home_menu.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item + android:id="@+id/disconnect_menu" + android:showAsAction="never" + android:title="@string/disconnect"> + </item> + <item android:id="@+id/change_bt_name" android:title="@string/change_bt_name"></item><item + android:id="@+id/license_menu" + android:showAsAction="always" + android:title="@string/licenses"> + </item> + + +</menu>
\ No newline at end of file diff --git a/res/menu/list_select_menu.xml b/res/menu/list_select_menu.xml new file mode 100644 index 0000000..8017a78 --- /dev/null +++ b/res/menu/list_select_menu.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item + android:id="@+id/delete_preset" + android:icon="@android:drawable/ic_menu_delete" + android:showAsAction="ifRoom" + android:title="@string/delete"/> + + <item + android:id="@+id/edit_preset" + android:icon="@android:drawable/ic_menu_edit" + android:showAsAction="always" + android:title="@string/edit"/> + +</menu>
\ No newline at end of file diff --git a/res/menu/presets_menu.xml b/res/menu/presets_menu.xml new file mode 100644 index 0000000..56082b2 --- /dev/null +++ b/res/menu/presets_menu.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item + android:id="@+id/new_preset" + android:showAsAction="always" + android:title="@string/new_preset"> + </item> + +</menu>
\ No newline at end of file diff --git a/res/values/arrays.xml b/res/values/arrays.xml new file mode 100644 index 0000000..88cb3d3 --- /dev/null +++ b/res/values/arrays.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string-array name="alarm_sounds"> + <item>Silent</item> + <item>Cesium</item> + <item>Fermium</item> + <item>Hassium</item> + <item>Neptunium</item> + <item>Nobelium</item> + <item>Plutonium</item> + </string-array> + +</resources>
\ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml new file mode 100644 index 0000000..3d5dbaf --- /dev/null +++ b/res/values/attrs.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources> + <declare-styleable name = "ActivityPreference"> + <attr name="classname" format = "string"/> + </declare-styleable> + + <declare-styleable name = "SeekBarPreference"> + <attr name="max" format = "integer"/> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml new file mode 100644 index 0000000..cb03548 --- /dev/null +++ b/res/values/colors.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="window_background">#000000</color> + + <color name="home_button_normal">#000000</color> + <color name="home_button_pressed">#257391</color> + + <color name="home_activity_divider">#666666</color> + <color name="home_button_label">#eeeeee</color> + + <color name="combination_color">#eeeeee</color> +</resources>
\ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100644 index 0000000..6e94c2b --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_short_name">ADK 2012</string> + <string name="app_long_name">ADK DemoKit 2012</string> + <string name="clock">Clock</string> + <string name="capture">Capture</string> + <string name="adk_description">A picture of the 2012 ADK.</string> + <string name="capture_prompt">When ready press the capture button below.</string> + <string name="alarm">Alarm</string> + <string name="volume">Volume</string> + <string name="color">Color</string> + <string name="color_sensor">Color sensor</string> + <string name="color_combinations">Color combinations</string> + <string name="brightness">Brightness</string> + <string name="bluetooth">Use Bluetooth</string> + <string name="display">Display</string> + <string name="presets">Presets</string> + <string name="locked">Locked</string> + <string name="unlocked">Unlocked</string> + <string name="time">Time</string> + <string name="accel">Acceleration</string> + <string name="temperature">Temperature</string> + <string name="hygro">Hygro</string> + <string name="leds_animation">LEDs animation</string> + <string name="baro">Pressure</string> + <string name="mag">Magnetic</string> + <string name="prox">Proximity</string> + <string name="no_presets">No presets</string> + <string name="new_preset">New preset</string> + <string name="name">Name</string> + <string name="delete">Delete</string> + <string name="edit">Edit</string> + <string name="rename">Rename</string> + <string name="cancel">Cancel</string> + <string name="create">Create</string> + <string name="disconnect">Disconnect</string> + <string name="title_paired_devices">Paired devices</string> + <string name="set">Set</string> + <string name="licenses">Licenses</string> + <string name="monochromatic">Monochromatic</string> + <string name="analogous">Analogous</string> + <string name="triad">Triad</string> + <string name="complementary">Complementary</string> + <string name="shade">Shade</string> + <string name="connect_please">Your ADK is not connected.</string> + <string name="plug_in_or_use_bluetooth">Please plug in the USB cable or use Bluetooth to connect to the ADK.</string> + <string name="fake_it">Fake it</string> + <string name="none_paired">None paired</string> + <string name="select_device">Select device</string> + <string name="pref_alarm_on_title">Turn ADK alarm on</string> + <string name="pref_alarm_vibrate_title">Vibrate</string> + <string name="pref_alarm_time_title">Time</string> + <string name="pref_alarm_sound_title">ADK alarm sound</string> + <string name="pref_clock_set_time_title">Set time</string> + <string name="pref_volume_title">Volume</string> + <string name="pref_color_base">Base</string> + <string name="pref_color_camera">Capture with phone camera</string> + <string name="pref_color_colorimeter">Capture with ADK color sensor</string> + <string name="pref_color_combinations">Combinations</string> + <string name="sync_width_adk_clock">Sync with ADK clock</string> + <string name="tbd">{tbd}</string> + + <plurals name="number_of_presets_deleted"> + <item quantity="one">Deleted one preset.</item> + <item quantity="two">Deleted two presets.</item> + <item quantity="other">Deleted %d presets.</item> + </plurals> + <string name="change_bt_name">Change Bluetooth Name</string> + <string name="set_bt_name_title">Set Bluetooth Name</string> + <string name="set_bt_name_ok">OK</string> + <string name="set_bt_name_cancel">Cancel</string> + +</resources>
\ No newline at end of file diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 0000000..e0f48b1 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <style name="Theme.ADK2" parent="android:style/Theme.Holo"> + <item name="android:actionBarStyle">@style/Theme.ADK2_ActionBar</item> + <item name="android:windowBackground">@color/window_background</item> + </style> + + <style name="Theme.ADK2_ActionBar" parent="@android:style/Widget.Holo.ActionBar"> + <item name="android:background">@drawable/ab_rainbow_bg</item> + </style> +</resources>
\ No newline at end of file diff --git a/res/xml/alarm_preferences.xml b/res/xml/alarm_preferences.xml new file mode 100644 index 0000000..db0e01a --- /dev/null +++ b/res/xml/alarm_preferences.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <CheckBoxPreference + android:defaultValue="true" + android:key="alarm_on" + android:title="@string/pref_alarm_on_title" /> + + <com.google.android.apps.adk2.widget.TimeDialogPreference + android:dialogLayout="@layout/time_dialog" + android:key="alarm_time" + android:negativeButtonText="@string/cancel" + android:positiveButtonText="@string/set" + android:title="@string/pref_alarm_time_title" /> + /> + <ListPreference + android:key="alarm_sound" + android:summary="{tbd}" + android:title="@string/pref_alarm_sound_title" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/brightness_preferences.xml b/res/xml/brightness_preferences.xml new file mode 100644 index 0000000..5e09845 --- /dev/null +++ b/res/xml/brightness_preferences.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" > + + <com.google.android.apps.adk2.widget.SeekBarPreference + adk2012:max="255" + android:key="brightness" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/clock_preferences.xml b/res/xml/clock_preferences.xml new file mode 100644 index 0000000..76b45cb --- /dev/null +++ b/res/xml/clock_preferences.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <com.google.android.apps.adk2.widget.TimeDialogPreference + android:dialogLayout="@layout/time_dialog" + android:key="time" + android:negativeButtonText="@string/cancel" + android:positiveButtonText="@string/set" + android:title="@string/pref_clock_set_time_title" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/color_preferences.xml b/res/xml/color_preferences.xml new file mode 100644 index 0000000..84be4e3 --- /dev/null +++ b/res/xml/color_preferences.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" > + + <com.google.android.apps.adk2.widget.ActivityPreference + adk2012:classname="com.google.android.apps.adk2.activity.ColorRGBActivity" + android:key="color" + android:title="@string/pref_color_base" /> + <com.google.android.apps.adk2.widget.ActivityPreference + adk2012:classname="com.google.android.apps.adk2.activity.ColorSensorActivity" + android:key="color" + android:title="@string/pref_color_colorimeter" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/display_preferences.xml b/res/xml/display_preferences.xml new file mode 100644 index 0000000..98407a5 --- /dev/null +++ b/res/xml/display_preferences.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <PreferenceCategory> + <CheckBoxPreference + android:defaultValue="true" + android:key="checkboxPref" + android:title="Use PIN" /> + <CheckBoxPreference + android:defaultValue="false" + android:key="checkboxPref2" + android:title="Don't use PIN" /> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file diff --git a/res/xml/usb_accessory_filter.xml b/res/xml/usb_accessory_filter.xml new file mode 100644 index 0000000..1ecc060 --- /dev/null +++ b/res/xml/usb_accessory_filter.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <usb-accessory + manufacturer="Google, Inc." + model="DemoKit" + version="2.0" /> + +</resources>
\ No newline at end of file diff --git a/res/xml/volume_preferences.xml b/res/xml/volume_preferences.xml new file mode 100644 index 0000000..73e8616 --- /dev/null +++ b/res/xml/volume_preferences.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" > + + <com.google.android.apps.adk2.widget.SeekBarPreference + adk2012:max="255" + android:key="volume" + android:title="@string/pref_volume_title" /> + +</PreferenceScreen>
\ No newline at end of file diff --git a/src/com/google/android/apps/adk2/ADK.java b/src/com/google/android/apps/adk2/ADK.java new file mode 100644 index 0000000..d6a1f41 --- /dev/null +++ b/src/com/google/android/apps/adk2/ADK.java @@ -0,0 +1,20 @@ +/* + * 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.google.android.apps.adk2; + +public final class ADK { + public static final String TAG = "ADK_2012"; +} diff --git a/src/com/google/android/apps/adk2/BTConnection.java b/src/com/google/android/apps/adk2/BTConnection.java new file mode 100644 index 0000000..d9568b0 --- /dev/null +++ b/src/com/google/android/apps/adk2/BTConnection.java @@ -0,0 +1,61 @@ +/* + * 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.google.android.apps.adk2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.UUID; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; + +public class BTConnection extends Connection { + + private final BluetoothAdapter mAdapter; + private BluetoothSocket mSocket; + + private static final UUID MY_UUID_INSECURE = UUID + .fromString("1dd35050-a437-11e1-b3dd-0800200c9a66"); + + public BTConnection(String address) { + mAdapter = BluetoothAdapter.getDefaultAdapter(); + BluetoothDevice device = mAdapter.getRemoteDevice(address); + try { + mSocket = device + .createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE); + mSocket.connect(); + } catch (IOException e) { + } + } + + @Override + public InputStream getInputStream() throws IOException { + return mSocket.getInputStream(); + } + + @Override + public OutputStream getOutputStream() throws IOException { + return mSocket.getOutputStream(); + } + + @Override + public void close() throws IOException { + mSocket.close(); + } + +} diff --git a/src/com/google/android/apps/adk2/Connection.java b/src/com/google/android/apps/adk2/Connection.java new file mode 100644 index 0000000..ab889c1 --- /dev/null +++ b/src/com/google/android/apps/adk2/Connection.java @@ -0,0 +1,28 @@ +/* + * 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.google.android.apps.adk2; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public abstract class Connection { + public abstract InputStream getInputStream() throws IOException; + + public abstract OutputStream getOutputStream() throws IOException; + + public abstract void close() throws IOException; +} diff --git a/src/com/google/android/apps/adk2/Preferences.java b/src/com/google/android/apps/adk2/Preferences.java new file mode 100644 index 0000000..ec88249 --- /dev/null +++ b/src/com/google/android/apps/adk2/Preferences.java @@ -0,0 +1,45 @@ +/* + * 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.google.android.apps.adk2; + +import android.graphics.Color; + +public final class Preferences { + + // Preference Keys + public static final String PREF_ALARM_ON = "alarm_on"; + public static final String PREF_ALARM_TIME = "alarm_time"; + public static final String PREF_ALARM_SOUND = "alarm_sound"; + public static final String PREF_COLOR = "color"; + public static final String PREF_DISPLAY = "display"; + public static final String PREF_BRIGHTNESS = "brightness"; + public static final String PREF_VOLUME = "volume"; + + public static final String PREF_TIME = "time"; + + public static final String PREF_COLOR_SENSOR = "color_sensor"; + public static final String PREF_LOCKED = "locked"; + + public static final String PREF_LICENSE_TEXT = "license_text"; + + public static final String[] SETTINGS_PREFERENCES = { PREF_ALARM_ON, + PREF_ALARM_TIME, PREF_COLOR, PREF_BRIGHTNESS, PREF_VOLUME }; + + // Defaults + public static final int PREF_DEFAULT_COLOR = Color.argb(255, 128, 64, 32); + public static final int DEFAULT_ALARM_TIME = 390; // 390 = 6:30am + +} diff --git a/src/com/google/android/apps/adk2/Presets.java b/src/com/google/android/apps/adk2/Presets.java new file mode 100644 index 0000000..4eb03ee --- /dev/null +++ b/src/com/google/android/apps/adk2/Presets.java @@ -0,0 +1,129 @@ +/* + * 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.google.android.apps.adk2; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; + +import android.content.Context; +import android.content.SharedPreferences; + +public class Presets { + private ArrayList<Preset> mPresets; + private final static String kFileName = "foo.dat"; + + public static class Preset implements Serializable { + private static final long serialVersionUID = 8075462052014816810L; + private String mName; + private Boolean mAlarmOn; + private int mAlarmTime; + private String mAlarmSound; + private int mVolume; + private int mColor; + private int mBrightness; + private int mDisplay; + + Preset(String name) { + mName = name; + } + + public String getName() { + return mName; + } + + public void setName(String name) { + mName = name; + } + + public String toString() { + return mName; + } + + public void applyToPreferences(SharedPreferences thePrefs) { + SharedPreferences.Editor editor = thePrefs.edit(); + + editor.putBoolean(Preferences.PREF_ALARM_ON, mAlarmOn); + editor.putInt(Preferences.PREF_ALARM_TIME, mAlarmTime); + editor.putString(Preferences.PREF_ALARM_SOUND, mAlarmSound); + + editor.putInt(Preferences.PREF_VOLUME, mVolume); + + editor.putInt(Preferences.PREF_COLOR, mColor); + + editor.putInt(Preferences.PREF_BRIGHTNESS, mBrightness); + + editor.putInt(Preferences.PREF_DISPLAY, mDisplay); + + editor.commit(); + } + + void extractFromPreferences(SharedPreferences thePrefs) { + mAlarmOn = thePrefs.getBoolean(Preferences.PREF_ALARM_ON, false); + mAlarmTime = thePrefs.getInt(Preferences.PREF_ALARM_TIME, + Preferences.DEFAULT_ALARM_TIME); + mAlarmSound = thePrefs.getString(Preferences.PREF_ALARM_SOUND, ""); + + mVolume = thePrefs.getInt(Preferences.PREF_VOLUME, 0); + + mColor = thePrefs.getInt(Preferences.PREF_COLOR, 0); + + mBrightness = thePrefs.getInt(Preferences.PREF_BRIGHTNESS, 0); + + mDisplay = thePrefs.getInt(Preferences.PREF_DISPLAY, 0); + } + + } + + public Presets() { + mPresets = new ArrayList<Preset>(); + } + + public void save(Context context) throws IOException { + FileOutputStream fos = context.openFileOutput(kFileName, + Context.MODE_PRIVATE); + ObjectOutputStream os = new ObjectOutputStream(fos); + os.writeObject(mPresets); + os.close(); + } + + @SuppressWarnings("unchecked") + public void load(Context context) throws IOException, + ClassNotFoundException { + FileInputStream fis = context.openFileInput(kFileName); + ObjectInputStream is = new ObjectInputStream(fis); + Object readObject = is.readObject(); + if (readObject != null) { + mPresets = (ArrayList<Preset>) readObject; + } + } + + public ArrayList<Preset> getPresets() { + return mPresets; + } + + public Preset makeNewPreset(SharedPreferences thePrefs) { + Preset preset = new Preset("Untitled"); + preset.extractFromPreferences(thePrefs); + mPresets.add(preset); + return preset; + } + +} diff --git a/src/com/google/android/apps/adk2/USBAccessoryActivity.java b/src/com/google/android/apps/adk2/USBAccessoryActivity.java new file mode 100644 index 0000000..9ca10b4 --- /dev/null +++ b/src/com/google/android/apps/adk2/USBAccessoryActivity.java @@ -0,0 +1,37 @@ +/* + * 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.google.android.apps.adk2; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; + +import com.google.android.apps.adk2.activity.HomeActivity; + +// receive USB_DEVICE_ATTACHED events and launch the main activity +public final class USBAccessoryActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent i = (new Intent(this, HomeActivity.class)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(i); + + finish(); + } +} diff --git a/src/com/google/android/apps/adk2/UsbConnection.java b/src/com/google/android/apps/adk2/UsbConnection.java new file mode 100644 index 0000000..ecd539a --- /dev/null +++ b/src/com/google/android/apps/adk2/UsbConnection.java @@ -0,0 +1,95 @@ +/* + * 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.google.android.apps.adk2; + +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import com.android.future.usb.UsbAccessory; +import com.android.future.usb.UsbManager; +import com.google.android.apps.adk2.activity.ConnectActivity; + +public class UsbConnection extends Connection { + Activity mActivity; + FileInputStream mInputStream; + FileOutputStream mOutputStream; + ParcelFileDescriptor mFileDescriptor; + UsbAccessory mAccessory; + + private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION"; + + private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { + UsbAccessory accessory = UsbManager.getAccessory(intent); + if (accessory != null && accessory.equals(mAccessory)) { + Log.i(ADK.TAG, "closing accessory"); + Intent connectIntent = new Intent(mActivity, + ConnectActivity.class); + connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + mActivity.startActivity(connectIntent); + } + } + } + }; + + public UsbConnection(Activity activity, UsbManager usbManager, + UsbAccessory accessory) { + mActivity = activity; + mFileDescriptor = usbManager.openAccessory(accessory); + if (mFileDescriptor != null) { + mAccessory = accessory; + FileDescriptor fd = mFileDescriptor.getFileDescriptor(); + mInputStream = new FileInputStream(fd); + mOutputStream = new FileOutputStream(fd); + } + IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); + filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); + mActivity.registerReceiver(mUsbReceiver, filter); + } + + @Override + public InputStream getInputStream() { + return mInputStream; + } + + @Override + public OutputStream getOutputStream() { + return mOutputStream; + } + + public void close() throws IOException { + if (mFileDescriptor != null) { + mFileDescriptor.close(); + } + mActivity.unregisterReceiver(mUsbReceiver); + } + +} diff --git a/src/com/google/android/apps/adk2/Utilities.java b/src/com/google/android/apps/adk2/Utilities.java new file mode 100644 index 0000000..99e9fd4 --- /dev/null +++ b/src/com/google/android/apps/adk2/Utilities.java @@ -0,0 +1,144 @@ +/* + * 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.google.android.apps.adk2; + +import java.util.Date; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.preference.Preference; +import android.preference.PreferenceManager; + +public class Utilities { + public static void centerAround(int x, int y, Drawable d) { + int w = d.getIntrinsicWidth(); + int h = d.getIntrinsicHeight(); + int left = x - w / 2; + int top = y - h / 2; + int right = left + w; + int bottom = top + h; + d.setBounds(left, top, right, bottom); + } + + public static int indexOf(int searchArray[], int itemToFind) { + for (int i = 0; i < searchArray.length; ++i) { + if (itemToFind == searchArray[i]) { + return i; + } + } + return -1; + } + + public static int indexOf(String searchArray[], String itemToFind) { + for (int i = 0; i < searchArray.length; ++i) { + if (itemToFind.equals(searchArray[i])) { + return i; + } + } + return -1; + } + + public static int stringToFourCC(String stringCode) { + int theCode = 0; + int count = Math.max(stringCode.length(), 4); + for (int i = 0; i < count; ++i) { + char c = stringCode.charAt(i); + theCode <<= 8; + theCode |= c; + } + return theCode; + } + + public static String fourCCToString(int fourCC) { + StringBuilder sb = new StringBuilder(); + sb.append('\''); + sb.append((fourCC & 0xFF000000) >> 24); + sb.append((fourCC & 0x00FF0000) >> 16); + sb.append((fourCC & 0x0000FF00) >> 8); + sb.append((fourCC & 0x000000FF)); + sb.append('\''); + return sb.toString(); + } + + public static void enablePreference(PreferenceManager preferenceMgr, + String prefKey, Boolean isEnabled) { + Preference pref = preferenceMgr.findPreference(prefKey); + if (pref != null) { + preferenceMgr.findPreference(prefKey).setEnabled(isEnabled); + } + } + + public static String formatTime(Context context, Date dateToFormat) { + java.text.DateFormat df = android.text.format.DateFormat + .getTimeFormat(context); + return df.format(dateToFormat); + } + + public static String formatTime(Context context, int timeValue) { + Date date = new Date(); + date.setHours(timeValue / 60); + date.setMinutes(timeValue % 60); + return formatTime(context, date); + } + + public static int dateToTimeValue(int hours, int minutes) { + return hours * 60 + minutes; + } + + public static int dateToTimeValue(Date date) { + return dateToTimeValue(date.getHours(), date.getMinutes()); + } + + private static final byte[] HEX_CHAR = new byte[] { '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + /** + * Helper function that dump an array of bytes in hex form + * + * @param buffer + * The bytes array to dump + * @return A string representation of the array of bytes + */ + public static final String dumpBytes(byte[] buffer, int amountToDump) { + if (buffer == null) { + return ""; + } + + StringBuffer sb = new StringBuffer(); + + amountToDump = Math.min(amountToDump, buffer.length); + + for (int i = 0; i < amountToDump; i++) { + sb.append("0x") + .append((char) (HEX_CHAR[(buffer[i] & 0x00F0) >> 4])) + .append((char) (HEX_CHAR[buffer[i] & 0x000F])).append(" "); + } + + return sb.toString(); + } + + public static int unsignedByte(byte b) { + return b & 0xff; + } + + public static int[] byteArrayToIntArray(byte[] byteArray) { + int[] intArray = new int[byteArray.length]; + for (int i = 0; i < intArray.length; ++i) { + intArray[i] = byteArray[i] & 0xff; + } + return intArray; + } +} diff --git a/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java b/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java new file mode 100755 index 0000000..310f56b --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java @@ -0,0 +1,88 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.os.Message; +import android.view.MenuItem; +import android.view.View; + +public class Adk2BaseActivity extends Activity { + + private boolean mWasPolling = false; + + static void maybeDisplayHomeAsUp(Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + activity.getActionBar().setDisplayHomeAsUpEnabled(true); + } + + static boolean maybeHandleHomeMenuItem(MenuItem item, Activity activity) { + switch (item.getItemId()) { + case android.R.id.home: + activity.finish(); + return true; + + default: + return false; + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Adk2BaseActivity.maybeDisplayHomeAsUp(this); + + HomeActivity h = HomeActivity.get(); + if (h != null) { + mWasPolling = h.startPollingSettings(); + } + + } + + @Override + public void onDestroy() { + HomeActivity h = HomeActivity.get(); + if (h != null && !mWasPolling) { + h.stopPollingSettings(); + } + super.onDestroy(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return Adk2BaseActivity.maybeHandleHomeMenuItem(item, this); + } + + public void onClick(View v) { + // TODO Auto-generated method stub + + } + + public boolean handleMessage(Message msg) { + // TODO Auto-generated method stub + return false; + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + // TODO Auto-generated method stub + + } +} diff --git a/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java b/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java new file mode 100755 index 0000000..ff8f57e --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java @@ -0,0 +1,53 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; +import android.view.MenuItem; + +public abstract class Adk2PreferenceActivity extends PreferenceActivity + implements OnSharedPreferenceChangeListener { + + protected PreferenceManager mPreferenceManager; + protected SharedPreferences mPreferences; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Adk2BaseActivity.maybeDisplayHomeAsUp(this); + + mPreferenceManager = getPreferenceManager(); + mPreferences = PreferenceManager.getDefaultSharedPreferences(this); + mPreferences.registerOnSharedPreferenceChangeListener(this); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return Adk2BaseActivity.maybeHandleHomeMenuItem(item, this); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + // TODO Auto-generated method stub + + } + +}
\ No newline at end of file diff --git a/src/com/google/android/apps/adk2/activity/AlarmActivity.java b/src/com/google/android/apps/adk2/activity/AlarmActivity.java new file mode 100644 index 0000000..04bdf17 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/AlarmActivity.java @@ -0,0 +1,95 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.util.Log; + +import com.google.android.apps.adk2.ADK; +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.Utilities; + +public class AlarmActivity extends Adk2PreferenceActivity { + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.alarm_preferences); + + updatePreferencesDisplay(); + + HomeActivity h = HomeActivity.get(); + if (h == null) { + Log.i(ADK.TAG, "Can't find home activity"); + } else { + Log.i(ADK.TAG, "h = " + h.toString()); + } + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_ALARM_ON.equals(key) + || Preferences.PREF_ALARM_TIME.equals(key) + || Preferences.PREF_ALARM_SOUND.equals(key)) + updatePreferencesDisplay(); + } + + void updatePreferencesDisplay() { + boolean alarmOn = mPreferences.getBoolean(Preferences.PREF_ALARM_ON, + true); + + Utilities.enablePreference(mPreferenceManager, + Preferences.PREF_ALARM_TIME, alarmOn); + Utilities.enablePreference(mPreferenceManager, + Preferences.PREF_ALARM_SOUND, alarmOn); + + updateAlarmTime(); + updateAlarmSoundList(); + } + + private void updateAlarmTime() { + int alarmTime = mPreferences.getInt(Preferences.PREF_ALARM_TIME, + Preferences.DEFAULT_ALARM_TIME); + String alarmTimeString = Utilities.formatTime(this, alarmTime); + Preference alarmTimePref = mPreferenceManager + .findPreference(Preferences.PREF_ALARM_TIME); + if (alarmTimePref != null) { + alarmTimePref.setSummary(alarmTimeString); + } + } + + private void updateAlarmSoundList() { + ListPreference alarmSoundPref = (ListPreference) mPreferenceManager + .findPreference(Preferences.PREF_ALARM_SOUND); + if (alarmSoundPref != null) { + HomeActivity h = HomeActivity.get(); + String[] alarmSoundsList = h.getAlarmSounds(); + String defaultAlarmSound = ""; + if (alarmSoundsList.length > 0) { + defaultAlarmSound = alarmSoundsList[0]; + } + String alarmSoundString = mPreferences.getString( + Preferences.PREF_ALARM_SOUND, defaultAlarmSound); + alarmSoundPref.setEntries(alarmSoundsList); + alarmSoundPref.setEntryValues(alarmSoundsList); + alarmSoundPref.setSummary(alarmSoundString); + alarmSoundPref.setValue(alarmSoundString); + } + } +} diff --git a/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java b/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java new file mode 100755 index 0000000..d9649af --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java @@ -0,0 +1,90 @@ +/* + * 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.google.android.apps.adk2.activity; + +import java.util.Set; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; + +import com.google.android.apps.adk2.R; + +public class BTDeviceListActivity extends Adk2BaseActivity implements + OnItemClickListener { + private BluetoothAdapter mBtAdapter; + private ArrayAdapter<String> mPairedDevicesArrayAdapter; + + public static String EXTRA_DEVICE_ADDRESS = "device_address"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.device_list); + + mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, + R.layout.device_name); + + // Find and set up the ListView for paired devices + ListView pairedListView = (ListView) findViewById(R.id.paired_devices); + pairedListView.setAdapter(mPairedDevicesArrayAdapter); + pairedListView.setOnItemClickListener(this); + + // Get the local Bluetooth adapter + mBtAdapter = BluetoothAdapter.getDefaultAdapter(); + + // Get a set of currently paired devices + Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); + + // If there are paired devices, add each one to the ArrayAdapter + if (pairedDevices.size() > 0) { + findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); + for (BluetoothDevice device : pairedDevices) { + mPairedDevicesArrayAdapter.add(device.getName() + "\n" + + device.getAddress()); + } + } else { + String noDevices = getResources().getText(R.string.none_paired) + .toString(); + mPairedDevicesArrayAdapter.add(noDevices); + } + } + + public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) { + mBtAdapter.cancelDiscovery(); + + // Get the device MAC address, which is the last 17 chars in the View + String info = ((TextView) v).getText().toString(); + + if (info.equals(getResources().getText(R.string.none_paired).toString())) + return; // do not proceed if we clicked the "there are no devices" + // message + + String address = info.substring(info.length() - 17); + Intent connectIntent = new Intent(this, HomeActivity.class); + connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + connectIntent.putExtra(EXTRA_DEVICE_ADDRESS, address); + startActivity(connectIntent); + } + +} diff --git a/src/com/google/android/apps/adk2/activity/BrightnessActivity.java b/src/com/google/android/apps/adk2/activity/BrightnessActivity.java new file mode 100644 index 0000000..b19e1fa --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/BrightnessActivity.java @@ -0,0 +1,54 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.os.Bundle; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.widget.SeekBarPreference; + +public class BrightnessActivity extends Adk2PreferenceActivity { + + public static final int MAX_BRIGHTNESS = 255; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.brightness_preferences); + updatePreferencesDisplay(); + } + + private void updatePreferencesDisplay() { + SeekBarPreference brightness = (SeekBarPreference) mPreferenceManager + .findPreference(Preferences.PREF_BRIGHTNESS); + + if (brightness != null) { + brightness.setValue(mPreferences.getInt( + Preferences.PREF_BRIGHTNESS, MAX_BRIGHTNESS)); + brightness.setEnabled(true); + } + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_BRIGHTNESS.equals(key)) + updatePreferencesDisplay(); + + } + +} diff --git a/src/com/google/android/apps/adk2/activity/ClockActivity.java b/src/com/google/android/apps/adk2/activity/ClockActivity.java new file mode 100644 index 0000000..fe75277 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/ClockActivity.java @@ -0,0 +1,83 @@ +/* + * 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.google.android.apps.adk2.activity; + +import java.util.Date; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.Handler; +import android.preference.Preference; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.Utilities; + +public class ClockActivity extends Adk2PreferenceActivity { + + private Handler mHandler = new Handler(); + + private Runnable mUpdateTimeTask; + + final static int kUpdateTime = 500; + int mHours = -1; + int mMinutes = -1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.clock_preferences); + + updatePreferencesDisplay(); + + mUpdateTimeTask = new Runnable() { + public void run() { + updatePreferencesDisplay(); + mHandler.postDelayed(mUpdateTimeTask, kUpdateTime); + } + }; + mHandler.postDelayed(mUpdateTimeTask, kUpdateTime); + } + + @Override + protected void onPause() { + mHandler.removeCallbacks(mUpdateTimeTask); + super.onPause(); + } + + @Override + protected void onResume() { + mHandler.postDelayed(mUpdateTimeTask, kUpdateTime); + super.onResume(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + } + + private void updatePreferencesDisplay() { + Preference clockTimePref = mPreferenceManager + .findPreference(Preferences.PREF_TIME); + if (clockTimePref != null) { + Date d = new Date(); + if (d.getHours() != mHours || d.getMinutes() != mMinutes) { + mHours = d.getHours(); + mMinutes = d.getMinutes(); + clockTimePref.setSummary(Utilities.formatTime(this, d)); + } + } + } +} diff --git a/src/com/google/android/apps/adk2/activity/ColorActivity.java b/src/com/google/android/apps/adk2/activity/ColorActivity.java new file mode 100644 index 0000000..b9dc753 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/ColorActivity.java @@ -0,0 +1,41 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.os.Bundle; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; + +public class ColorActivity extends Adk2PreferenceActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.color_preferences); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_COLOR.equals(key)) + updatePreferencesDisplay(); + } + + private void updatePreferencesDisplay() { + } +} diff --git a/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java b/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java new file mode 100644 index 0000000..9516cea --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java @@ -0,0 +1,161 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.view.View; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.views.Slider; + +public class ColorRGBActivity extends Adk2BaseActivity implements + Slider.SliderPositionListener, OnSharedPreferenceChangeListener { + private View mOriginalColorView; + private View mNewColorView; + private TextView mTextHex; + private TextView mTextR; + private TextView mTextG; + private TextView mTextB; + private Slider mSeekBarR; + private Slider mSeekBarG; + private Slider mSeekBarB; + private Drawable mGreen; + private Drawable mRed; + private Drawable mBlue; + + private int mOriginalColor; + private int mNewColor; + + private final int kColorRange = 255; + + private Slider setupSeekBar(int seekBarId, Drawable color) { + Slider theBar = (Slider) findViewById(seekBarId); + theBar.setPositionListener(this); + theBar.setSliderBackground(color); + return theBar; + } + + private TextView setupTextField(int textFieldId) { + TextView theText = (TextView) findViewById(textFieldId); + return theText; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.color_rgb); + + Resources res = getResources(); + mRed = res.getDrawable(R.drawable.scrubber_horizontal_red_holo_dark); + mGreen = res + .getDrawable(R.drawable.scrubber_horizontal_green_holo_dark); + mBlue = res.getDrawable(R.drawable.scrubber_horizontal_blue_holo_dark); + + mOriginalColorView = findViewById(R.id.original_color); + mNewColorView = findViewById(R.id.new_color); + mTextHex = setupTextField(R.id.color_hex); + mTextR = setupTextField(R.id.color_r); + mTextG = setupTextField(R.id.color_g); + mTextB = setupTextField(R.id.color_b); + mSeekBarR = setupSeekBar(R.id.seek_bar_r, mRed); + mSeekBarG = setupSeekBar(R.id.seek_bar_g, mGreen); + mSeekBarB = setupSeekBar(R.id.seek_bar_b, mBlue); + + mOriginalColor = PreferenceManager.getDefaultSharedPreferences(this) + .getInt(Preferences.PREF_COLOR, Preferences.PREF_DEFAULT_COLOR); + mNewColor = mOriginalColor; + + SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(this); + preferences.registerOnSharedPreferenceChangeListener(this); + + updateDisplay(); + } + + public void onPositionChange(Slider slider, double value) { + switch (slider.getId()) { + case R.id.seek_bar_r: + mNewColor = (mNewColor & 0xff00ffff) + | ((int) (value * kColorRange) << 16); + break; + + case R.id.seek_bar_g: + mNewColor = (mNewColor & 0xffff00ff) + | ((int) (value * kColorRange) << 8); + break; + + case R.id.seek_bar_b: + mNewColor = (mNewColor & 0xffffff00) | (int) (value * kColorRange); + break; + } + + persistPreferences(); + updateDisplay(); + } + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + } + + private void persistPreferences() { + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + editor.putInt(Preferences.PREF_COLOR, mNewColor); + editor.apply(); + } + + private void updateDisplay() { + mOriginalColorView.setBackgroundColor(mOriginalColor | 0xff000000); + mNewColorView.setBackgroundColor(mNewColor | 0xff000000); + + int r, g, b; + r = (mNewColor >> 16) & 0xff; + g = (mNewColor >> 8) & 0xff; + b = mNewColor & 0xff; + + mTextHex.setText(String.format("%06X", mNewColor & 0xffffff)); + mTextR.setText(String.format("%d", r)); + mTextG.setText(Integer.toString(g)); + mTextB.setText(Integer.toString(b)); + + mSeekBarR.setPosition((double) r / (double) kColorRange); + mSeekBarG.setPosition((double) g / (double) kColorRange); + mSeekBarB.setPosition((double) b / (double) kColorRange); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_COLOR.equals(key)) { + mOriginalColor = sharedPreferences.getInt(Preferences.PREF_COLOR, + Preferences.PREF_DEFAULT_COLOR); + mNewColor = mOriginalColor; + updateDisplay(); + } + + } + +} diff --git a/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java b/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java new file mode 100755 index 0000000..ddf079f --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java @@ -0,0 +1,107 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.os.Handler; +import android.os.Handler.Callback; +import android.os.Message; +import android.preference.PreferenceManager; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.views.ColorSensorView; + +public class ColorSensorActivity extends Adk2BaseActivity implements + OnSharedPreferenceChangeListener, OnClickListener, Callback { + + private Handler mColorPollingHandler; + private ColorSensorView mColorSensorView; + private Button mCaptureButton; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(this); + preferences.registerOnSharedPreferenceChangeListener(this); + + setContentView(R.layout.color_sensor); + mColorSensorView = (ColorSensorView) findViewById(R.id.color_sensor_view); + mCaptureButton = (Button) findViewById(R.id.color_sample_button); + mCaptureButton.setOnClickListener(this); + + mColorPollingHandler = new Handler(this); + getColorFromSensor(); + Message msg = mColorPollingHandler.obtainMessage(); + mColorPollingHandler.sendMessageDelayed(msg, 500); + } + + @Override + public void onDestroy() { + mColorPollingHandler = null; + super.onDestroy(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_COLOR_SENSOR.equals(key)) + updatePreferencesDisplay(sharedPreferences); + } + + private void updatePreferencesDisplay(SharedPreferences sharedPreferences) { + mColorSensorView.setSensedColor(sharedPreferences.getInt( + Preferences.PREF_COLOR_SENSOR, 0) | 0xff000000); + getColorFromSensor(); + + } + + private void getColorFromSensor() { + HomeActivity h = HomeActivity.get(); + if (h != null) { + h.getSensors(); + } + } + + @Override + public void onClick(View v) { + SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = preferences.edit(); + int newColor = preferences.getInt(Preferences.PREF_COLOR_SENSOR, + 0xFFFFFF); + editor.putInt(Preferences.PREF_COLOR, newColor); + editor.commit(); + finish(); + } + + + public boolean handleMessage(Message msg) { + getColorFromSensor(); + if (mColorPollingHandler != null) { + Message newMsg = mColorPollingHandler.obtainMessage(); + mColorPollingHandler.sendMessageDelayed(newMsg, 500); + } + return true; + } + +} diff --git a/src/com/google/android/apps/adk2/activity/ConnectActivity.java b/src/com/google/android/apps/adk2/activity/ConnectActivity.java new file mode 100755 index 0000000..acfe7c3 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/ConnectActivity.java @@ -0,0 +1,43 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +import com.google.android.apps.adk2.R; + +public class ConnectActivity extends Activity implements OnClickListener { + private Button mBluetoothButton; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.connect); + mBluetoothButton = (Button) findViewById(R.id.connect_bluetooth_button); + mBluetoothButton.setOnClickListener(this); + } + + public void onClick(View v) { + if (v.getId() == R.id.connect_bluetooth_button) { + startActivity(new Intent(this, BTDeviceListActivity.class)); + } + } + +} diff --git a/src/com/google/android/apps/adk2/activity/DisplayActivity.java b/src/com/google/android/apps/adk2/activity/DisplayActivity.java new file mode 100755 index 0000000..98ba3b6 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/DisplayActivity.java @@ -0,0 +1,63 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.widget.RadioGroup; +import android.widget.RadioGroup.OnCheckedChangeListener; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.Utilities; + +public class DisplayActivity extends Adk2BaseActivity implements + OnCheckedChangeListener { + + RadioGroup mDisplayGroup; + + int mDisplayOption; + + final int kDisplayButtons[] = { R.id.radio_animation, R.id.radio_accell, + R.id.radio_mag, R.id.radio_temperature, R.id.radio_hygro, + R.id.radio_baro, R.id.radio_prox, R.id.radio_color }; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.display); + + mDisplayGroup = (RadioGroup) findViewById(R.id.display_group); + mDisplayGroup.setOnCheckedChangeListener(this); + + mDisplayOption = PreferenceManager.getDefaultSharedPreferences(this) + .getInt(Preferences.PREF_DISPLAY, 0); + updateDisplay(); + } + + public void onCheckedChanged(RadioGroup group, int checkedId) { + mDisplayOption = Utilities.indexOf(kDisplayButtons, checkedId); + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + editor.putInt(Preferences.PREF_DISPLAY, mDisplayOption); + editor.apply(); + } + + void updateDisplay() { + mDisplayGroup.check(kDisplayButtons[mDisplayOption]); + } + +} diff --git a/src/com/google/android/apps/adk2/activity/HomeActivity.java b/src/com/google/android/apps/adk2/activity/HomeActivity.java new file mode 100755 index 0000000..dedad20 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/HomeActivity.java @@ -0,0 +1,968 @@ +/* + * 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.google.android.apps.adk2.activity; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.zip.GZIPInputStream; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Handler.Callback; +import android.os.Message; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.future.usb.UsbAccessory; +import com.android.future.usb.UsbManager; +import com.google.android.apps.adk2.ADK; +import com.google.android.apps.adk2.BTConnection; +import com.google.android.apps.adk2.Connection; +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.UsbConnection; +import com.google.android.apps.adk2.Utilities; + +public class HomeActivity extends Activity implements OnClickListener, + Callback, OnSharedPreferenceChangeListener, Runnable { + + private Handler mDeviceHandler; + private Handler mSettingsPollingHandler; + + private UsbManager mUSBManager; + private SharedPreferences mPreferences; + + private ByteArrayOutputStream mLicenseTextStream; + + private byte[] mSettingsBuffer = null; + private byte[] mSettingsPayload = new byte[8]; + private byte[] mQueryBuffer = new byte[4]; + private byte[] mEmptyPayload = new byte[0]; + + Connection mConnection; + + UsbAccessory mAccessory; + + private boolean mIgnorePrefChanges = false; + private boolean mPollSettings = false; + + private long mIgnoreUpdatesUntil = System.currentTimeMillis(); + + private String mLicenseText = ""; + private ArrayList<String> mSoundFiles; + + static final String TUNES_FOLDER = "/Tunes"; + + static final byte CMD_GET_PROTO_VERSION = 1; // () -> (u8 protocolVersion) + static final byte CMD_GET_SENSORS = 2; // () -> (sensors: + // i32,i32,i32,i32,u16,u16,u16,u16,u16,u16,u16,i16,i16,i16,i16,i16,i16) + static final byte CMD_FILE_LIST = 3; // FIRST: (char name[]) -> (fileinfo or + // single zero byte) OR NONLATER: () + // -> (fileinfo or empty or single + // zero byte) + static final byte CMD_FILE_DELETE = 4; // (char name[0-255)) -> (char + // success) + static final byte CMD_FILE_OPEN = 5; // (char name[0-255]) -> (char success) + static final byte CMD_FILE_WRITE = 6; // (u8 data[]) -> (char success) + static final byte CMD_FILE_CLOSE = 7; // () -> (char success) + static final byte CMD_GET_UNIQ_ID = 8; // () -> (u8 uniq[16]) + static final byte CMD_BT_NAME = 9; // (char name[]) -> () OR () -> (char + // name[]) + static final byte CMD_BT_PIN = 10; // (char PIN[]) -> () OR () -> (char + // PIN[]) + static final byte CMD_TIME = 11; // (timespec) -> (char success)) OR () > + // (timespec) + static final byte CMD_SETTINGS = 12; // () -> + // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8) + // or + // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8) + // > (char success) + static final byte CMD_ALARM_FILE = 13; // () -> (char file[0-255]) OR (char + // file[0-255]) > (char success) + static final byte CMD_GET_LICENSE = 14; // () -> (u8 licensechunk[]) OR () + // if last sent + static final byte CMD_DISPLAY_MODE = 15; // () -> (u8) OR (u8) -> () + static final byte CMD_LOCK = 16; // () -> (u8) OR (u8) -> () + + private static final boolean gLogPackets = false; + + static final int DIALOG_NO_PRESETS_ID = 0; + + private static HomeActivity sHomeActivity = null; + + private static String curBtName = "<UNKNOWN>"; + + public static HomeActivity get() { + return sHomeActivity; + } + + public boolean startPollingSettings() { + boolean wasPolling = mPollSettings; + mPollSettings = true; + if (!wasPolling) { + pollSettings(); + } + return wasPolling; + } + + public void stopPollingSettings() { + mPollSettings = false; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.home); + + mDeviceHandler = new Handler(this); + mSettingsPollingHandler = new Handler(this); + + mPreferences = PreferenceManager.getDefaultSharedPreferences(this); + mPreferences.registerOnSharedPreferenceChangeListener(this); + + mUSBManager = UsbManager.getInstance(this); + + mSoundFiles = new ArrayList<String>(); + + setUpButton(R.id.clock_button, R.drawable.ic_clock, R.string.clock); + setUpButton(R.id.alarm_button, R.drawable.ic_alarm, R.string.alarm); + setUpButton(R.id.volume_button, R.drawable.ic_volume, R.string.volume); + setUpButton(R.id.color_button, R.drawable.ic_color, R.string.color); + setUpButton(R.id.brightness_button, R.drawable.ic_brightness, + R.string.brightness); + setUpButton(R.id.display_button, R.drawable.ic_display, + R.string.display); + setUpButton(R.id.presets_button, R.drawable.ic_presets, + R.string.presets); + updateLockDisplay(); + + connectToAccessory(); + + startLicenseUpload(); + sHomeActivity = this; + + startPollingSettings(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.home_menu, menu); + return true; + } + + @Override + protected Dialog onCreateDialog(int id) { + Dialog dialog = null; + if (id == DIALOG_NO_PRESETS_ID) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("Unsupported feature."); + dialog = builder.create(); + } + return dialog; + } + + private void changeBtName() { + + // This example shows how to add a custom layout to an AlertDialog + LayoutInflater factory = LayoutInflater.from(this); + final View textEntryView = factory.inflate(R.layout.alert_dialog, null); + final EditText e = (EditText) textEntryView + .findViewById(R.id.btname_edit); + + AlertDialog ad = new AlertDialog.Builder(this) + .setIconAttribute(android.R.attr.alertDialogIcon) + .setTitle("Set ADK Bluetooth Name") + .setView(textEntryView) + .setPositiveButton(R.string.set_bt_name_ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + + curBtName = e.getText().toString(); + if (curBtName.equals("")) + curBtName = "ADK 2012"; + + byte b[] = null; + try { + b = curBtName.getBytes("UTF-8"); + } catch (UnsupportedEncodingException e1) { + // well aren't you SOL.... + e1.printStackTrace(); + } + byte b2[] = new byte[b.length + 1]; + for (int i = 0; i < b.length; i++) + b2[i] = b[i]; + b2[b.length] = 0; + + sendCommand(CMD_BT_NAME, CMD_BT_NAME, b2); + } + }) + .setNegativeButton(R.string.set_bt_name_cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int whichButton) { + + // user cancels + } + }).create(); + + e.setText(curBtName); + ad.show(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.license_menu: + showLicenses(); + return true; + + case R.id.disconnect_menu: + disconnect(); + return true; + + case R.id.change_bt_name: + changeBtName(); + return true; + + default: + return false; + } + } + + private void disconnect() { + finish(); + } + + private void showLicenses() { + Intent showLicenseIntent = new Intent(this, LicenseActivity.class); + startActivity(showLicenseIntent); + } + + private void startLicenseUpload() { + Log.i(ADK.TAG, "startLicenseUpload"); + mLicenseTextStream = new ByteArrayOutputStream(); + sendCommand(CMD_GET_LICENSE, 33); + } + + private void pollSettings() { + if (mPollSettings) { + sendCommand(CMD_SETTINGS, CMD_SETTINGS); + sendCommand(CMD_DISPLAY_MODE, CMD_DISPLAY_MODE); + sendCommand(CMD_LOCK, CMD_LOCK); + Message msg = mSettingsPollingHandler.obtainMessage(99); + if (!mSettingsPollingHandler.sendMessageDelayed(msg, 500)) { + Log.e(ADK.TAG, "faled to queue settings message"); + } + } + } + + @Override + public void onPause() { + super.onPause(); + } + + @Override + public void onResume() { + super.onResume(); + pollSettings(); + } + + @Override + public void onDestroy() { + sHomeActivity = null; + if (mConnection != null) { + try { + mConnection.close(); + } catch (IOException e) { + } finally { + mConnection = null; + } + } + super.onDestroy(); + } + + public void onClick(View v) { + switch (v.getId()) { + case R.id.clock_button: + startActivity(new Intent(this, ClockActivity.class)); + break; + + case R.id.alarm_button: + startActivity(new Intent(this, AlarmActivity.class)); + break; + + case R.id.volume_button: + startActivity(new Intent(this, VolumeActivity.class)); + break; + + case R.id.color_button: + startActivity(new Intent(this, ColorActivity.class)); + break; + + case R.id.brightness_button: + startActivity(new Intent(this, BrightnessActivity.class)); + break; + + case R.id.display_button: + startActivity(new Intent(this, DisplayActivity.class)); + break; + + case R.id.presets_button: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) + startActivity(new Intent(this, PresetsActivity.class)); + else + showDialog(DIALOG_NO_PRESETS_ID); + break; + + case R.id.lock_button: + toggleLock(); + break; + } + } + + private void toggleLock() { + boolean isLocked = mPreferences.getBoolean(Preferences.PREF_LOCKED, + false); + boolean newLocked = !isLocked; + SharedPreferences.Editor editor = mPreferences.edit(); + editor.putBoolean(Preferences.PREF_LOCKED, newLocked); + editor.commit(); + } + + private void setUpButton(int buttonID, int iconID, int labelID) { + View button = findViewById(buttonID); + button.setOnClickListener(this); + ((ImageView) button.findViewById(R.id.icon)).setImageResource(iconID); + ((TextView) button.findViewById(R.id.label)).setText(labelID); + } + + public void connectToAccessory() { + // bail out if we're already connected + if (mConnection != null) + return; + + if (getIntent().hasExtra(BTDeviceListActivity.EXTRA_DEVICE_ADDRESS)) { + String address = getIntent().getStringExtra( + BTDeviceListActivity.EXTRA_DEVICE_ADDRESS); + Log.i(ADK.TAG, "want to connect to " + address); + mConnection = new BTConnection(address); + performPostConnectionTasks(); + } else { + // assume only one accessory (currently safe assumption) + UsbAccessory[] accessories = mUSBManager.getAccessoryList(); + UsbAccessory accessory = (accessories == null ? null + : accessories[0]); + if (accessory != null) { + if (mUSBManager.hasPermission(accessory)) { + openAccessory(accessory); + } else { + // synchronized (mUsbReceiver) { + // if (!mPermissionRequestPending) { + // mUsbManager.requestPermission(accessory, + // mPermissionIntent); + // mPermissionRequestPending = true; + // } + // } + } + } else { + // Log.d(TAG, "mAccessory is null"); + } + } + + } + + public void disconnectFromAccessory() { + closeAccessory(); + } + + private void openAccessory(UsbAccessory accessory) { + mConnection = new UsbConnection(this, mUSBManager, accessory); + performPostConnectionTasks(); + } + + private void performPostConnectionTasks() { + sendCommand(CMD_GET_PROTO_VERSION, CMD_GET_PROTO_VERSION); + sendCommand(CMD_SETTINGS, CMD_SETTINGS); + sendCommand(CMD_BT_NAME, CMD_BT_NAME); + sendCommand(CMD_ALARM_FILE, CMD_ALARM_FILE); + listDirectory(TUNES_FOLDER); + + Thread thread = new Thread(null, this, "ADK 2012"); + thread.start(); + } + + public void closeAccessory() { + try { + mConnection.close(); + } catch (IOException e) { + } finally { + mConnection = null; + } + } + + public void run() { + int ret = 0; + byte[] buffer = new byte[16384]; + int bufferUsed = 0; + + while (ret >= 0) { + try { + ret = mConnection.getInputStream().read(buffer, bufferUsed, + buffer.length - bufferUsed); + bufferUsed += ret; + int remainder = process(buffer, bufferUsed); + if (remainder > 0) { + System.arraycopy(buffer, remainder, buffer, 0, bufferUsed + - remainder); + bufferUsed = remainder; + } else { + bufferUsed = 0; + } + } catch (IOException e) { + break; + } + } + Intent connectIntent = new Intent(this, ConnectActivity.class); + connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(connectIntent); + } + + public int process(byte[] buffer, int bufferUsed) { + if (gLogPackets) { + Log.i(ADK.TAG, + "read " + bufferUsed + " bytes: " + + Utilities.dumpBytes(buffer, bufferUsed)); + } + ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer, 0, + bufferUsed); + ProtocolHandler ph = new ProtocolHandler(mDeviceHandler, inputStream); + ph.process(); + return inputStream.available(); + } + + public void listDirectory(String path) { + mSoundFiles.clear(); + byte[] payload = new byte[path.length() + 1]; + for (int i = 0; i < path.length(); ++i) { + payload[i] = (byte) path.charAt(i); + } + payload[path.length()] = 0; + sendCommand(CMD_FILE_LIST, CMD_FILE_LIST, payload); + } + + public void getSensors() { + sendCommand(CMD_GET_SENSORS, CMD_GET_SENSORS); + } + + public byte[] sendCommand(int command, int sequence, byte[] payload, + byte[] buffer) { + int bufferLength = payload.length + 4; + if (buffer == null || buffer.length < bufferLength) { + Log.i(ADK.TAG, "allocating new command buffer of length " + + bufferLength); + buffer = new byte[bufferLength]; + } + + buffer[0] = (byte) command; + buffer[1] = (byte) sequence; + buffer[2] = (byte) (payload.length & 0xff); + buffer[3] = (byte) ((payload.length & 0xff00) >> 8); + if (payload.length > 0) { + System.arraycopy(payload, 0, buffer, 4, payload.length); + } + if (mConnection != null && buffer[1] != -1) { + try { + if (gLogPackets) { + Log.i(ADK.TAG, + "sendCommand: " + + Utilities + .dumpBytes(buffer, buffer.length)); + } + mConnection.getOutputStream().write(buffer); + } catch (IOException e) { + Log.e(ADK.TAG, "accessory write failed", e); + } + } + return buffer; + } + + public void sendCommand(int command, int sequence, byte[] payload) { + sendCommand(command, sequence, payload, null); + } + + private void sendCommand(int command, int sequence) { + sendCommand(command, sequence, mEmptyPayload, mQueryBuffer); + } + + private void handleBtNameCommand(byte[] settingsBytes) { + + if (settingsBytes.length > 1 || settingsBytes[0] == 0) { // it's a name + // reply + + byte[] b = new byte[settingsBytes.length - 1]; + for (int i = 0; i < settingsBytes.length - 1; i++) + b[i] = settingsBytes[i]; + + curBtName = new String(b); + } + } + + private void handleSettingsCommand(byte[] settingsBytes) { + + if (System.currentTimeMillis() < mIgnoreUpdatesUntil) { + return; + } + + if (settingsBytes.length == 8) { + int settings[] = Utilities.byteArrayToIntArray(settingsBytes); + mIgnorePrefChanges = true; + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + + // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8) + int alarmTime = Utilities.dateToTimeValue(settings[0], settings[1]); + editor.putInt(Preferences.PREF_ALARM_TIME, alarmTime); + boolean alarmOn = (settings[2] != 0); + editor.putBoolean(Preferences.PREF_ALARM_ON, alarmOn); + + editor.putInt(Preferences.PREF_BRIGHTNESS, settings[3]); + + int color = settings[4] << 16 | settings[5] << 8 | settings[6]; + editor.putInt(Preferences.PREF_COLOR, color); + + int volume = settings[7]; + editor.putInt(Preferences.PREF_VOLUME, volume); + editor.apply(); + + mIgnorePrefChanges = false; + } + } + + private void handleLicenseTextCommand(byte[] licenseTextBytes) { + if (gLogPackets) { + Log.i(ADK.TAG, "License text chunk"); + Log.i(ADK.TAG, Utilities.dumpBytes(licenseTextBytes, + licenseTextBytes.length)); + } + if (licenseTextBytes.length > 1 && licenseTextBytes[0] != 0) { + mLicenseTextStream.write(licenseTextBytes, 1, + licenseTextBytes.length - 1); + sendCommand(CMD_GET_LICENSE, 33); + } else { + + try { + mLicenseTextStream.close(); + byte[] encodedArray = mLicenseTextStream.toByteArray(); + GZIPInputStream gis = new GZIPInputStream( + new ByteArrayInputStream(encodedArray)); + byte[] decodedBuffer = new byte[128 * 1024]; // TODO: make this + // buffer + // smaller + while (true) { + int length = gis.read(decodedBuffer); + if (length < 1) { + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + editor.putString(Preferences.PREF_LICENSE_TEXT, + mLicenseText); + editor.commit(); + mLicenseText = ""; + break; + } + mLicenseText = mLicenseText + + new String(decodedBuffer, 0, length, "utf-8"); + } + } catch (IOException e) { + Log.i(ADK.TAG, "error = " + e.toString()); + } + } + } + + private void handleFileListCommand(byte[] fileListBytes) { + if (gLogPackets) + Log.i(ADK.TAG, + "handleFileListCommand: " + + Utilities.dumpBytes(fileListBytes, + fileListBytes.length)); + if (fileListBytes.length == 1 && fileListBytes[0] == 0) { + return; + } + if (fileListBytes.length > 6) { + String fileName = new String(fileListBytes, 5, + fileListBytes.length - 6); + if (gLogPackets) + Log.i(ADK.TAG, "got file name '" + fileName + "'"); + mSoundFiles.add(fileName); + } + sendCommand(CMD_FILE_LIST, CMD_FILE_LIST); + + } + + private void handleAlarmFileCommand(byte[] alarmFileNameBytes) { + if (alarmFileNameBytes.length > 1) { + mIgnorePrefChanges = true; + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + String alarmFileName = new String(alarmFileNameBytes, 0, + alarmFileNameBytes.length - 1); + alarmFileName = alarmFileName.replaceFirst("(?i)" + TUNES_FOLDER + + "/", ""); + editor.putString(Preferences.PREF_ALARM_SOUND, alarmFileName); + editor.apply(); + mIgnorePrefChanges = false; + } + } + + private void handleGetSensorsCommand(byte[] sensorBytes) { + if (gLogPackets) + Log.i(ADK.TAG, + "handleGetSensorsCommand: " + + Utilities.dumpBytes(sensorBytes, + sensorBytes.length)); + if (sensorBytes.length > 23) { + int sensorValues[] = Utilities.byteArrayToIntArray(sensorBytes); + int proxNormalized[] = { + sensorValues[20] | (sensorValues[21] << 8), + sensorValues[22] | (sensorValues[23] << 8), + sensorValues[24] | (sensorValues[25] << 8) }; + proxNormalized[2] *= 3; + // find max + int proxMax = 0; + for (int i = 0; i < 3; i++) + if (proxMax < proxNormalized[i]) + proxMax = proxNormalized[i]; + proxMax++; + // normalize to 8-bits + for (int i = 0; i < 3; i++) + proxNormalized[i] = (proxNormalized[i] << 8) / proxMax; + final int exp[] = { 0, 19, 39, 59, 79, 100, 121, 143, 165, 187, + 209, 232, 255, 279, 303, 327, 352, 377, 402, 428, 454, 481, + 508, 536, 564, 592, 621, 650, 680, 710, 741, 772, 804, 836, + 869, 902, 936, 970, 1005, 1040, 1076, 1113, 1150, 1187, + 1226, 1264, 1304, 1344, 1385, 1426, 1468, 1511, 1554, 1598, + 1643, 1688, 1734, 1781, 1829, 1877, 1926, 1976, 2026, 2078, + 2130, 2183, 2237, 2292, 2348, 2404, 2461, 2520, 2579, 2639, + 2700, 2762, 2825, 2889, 2954, 3020, 3088, 3156, 3225, 3295, + 3367, 3439, 3513, 3588, 3664, 3741, 3819, 3899, 3980, 4062, + 4146, 4231, 4317, 4404, 4493, 4583, 4675, 4768, 4863, 4959, + 5057, 5156, 5257, 5359, 5463, 5568, 5676, 5785, 5895, 6008, + 6122, 6238, 6355, 6475, 6597, 6720, 6845, 6973, 7102, 7233, + 7367, 7502, 7640, 7780, 7922, 8066, 8213, 8362, 8513, 8666, + 8822, 8981, 9142, 9305, 9471, 9640, 9811, 9986, 10162, + 10342, 10524, 10710, 10898, 11089, 11283, 11480, 11681, + 11884, 12091, 12301, 12514, 12731, 12951, 13174, 13401, + 13632, 13866, 14104, 14345, 14591, 14840, 15093, 15351, + 15612, 15877, 16147, 16421, 16699, 16981, 17268, 17560, + 17856, 18156, 18462, 18772, 19087, 19407, 19733, 20063, + 20398, 20739, 21085, 21437, 21794, 22157, 22525, 22899, + 23279, 23666, 24058, 24456, 24861, 25272, 25689, 26113, + 26544, 26982, 27426, 27878, 28336, 28802, 29275, 29756, + 30244, 30740, 31243, 31755, 32274, 32802, 33338, 33883, + 34436, 34998, 35568, 36148, 36737, 37335, 37942, 38559, + 39186, 39823, 40469, 41126, 41793, 42471, 43159, 43859, + 44569, 45290, 46023, 46767, 47523, 48291, 49071, 49863, + 50668, 51486, 52316, 53159, 54016, 54886, 55770, 56668, + 57580, 58506, 59447, 60403, 61373, 62359, 63361, 64378, + 65412 }; + for (int i = 0; i < 3; i++) + proxNormalized[i] = (exp[proxNormalized[i]] + 128) >> 8; + + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + int color = (proxNormalized[0] << 16) | (proxNormalized[1] << 8) + | proxNormalized[2]; + editor.putInt(Preferences.PREF_COLOR_SENSOR, color); + editor.commit(); + } + } + + private void handleLockCommand(byte[] lockedBytes) { + if (gLogPackets) + Log.i(ADK.TAG, + "lockBytes: " + + Utilities.dumpBytes(lockedBytes, + lockedBytes.length)); + if (lockedBytes.length > 0 && lockedBytes[0] != 1) { + mIgnorePrefChanges = true; + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(this).edit(); + editor.putBoolean(Preferences.PREF_LOCKED, lockedBytes[0] == 2); + editor.commit(); + mIgnorePrefChanges = false; + } + } + + public boolean handleMessage(Message msg) { + if (msg.getTarget() == mDeviceHandler) { + return handleDeviceMethod(msg); + } else { + pollSettings(); + return true; + } + } + + private boolean handleDeviceMethod(Message msg) { + switch (msg.what) { + case CMD_SETTINGS: + handleSettingsCommand((byte[]) msg.obj); + return true; + case CMD_BT_NAME: + handleBtNameCommand((byte[]) msg.obj); + case CMD_GET_LICENSE: + handleLicenseTextCommand((byte[]) msg.obj); + return true; + case CMD_FILE_LIST: + handleFileListCommand((byte[]) msg.obj); + return true; + case CMD_ALARM_FILE: + handleAlarmFileCommand((byte[]) msg.obj); + return true; + case CMD_GET_SENSORS: + handleGetSensorsCommand((byte[]) msg.obj); + return true; + case CMD_LOCK: + handleLockCommand((byte[]) msg.obj); + return true; + } + return false; + } + + public Object getAccessory() { + return mAccessory; + } + + private void updateLockDisplay() { + boolean isLocked = mPreferences.getBoolean(Preferences.PREF_LOCKED, + false); + setUpButton(R.id.lock_button, isLocked ? R.drawable.ic_lock + : R.drawable.ic_unlock, isLocked ? R.string.locked + : R.string.unlocked); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + + if (Preferences.PREF_LOCKED.equals(key)) { + updateLockDisplay(); + } + + if (mIgnorePrefChanges) { + return; + } + + if (gLogPackets) + Log.d(ADK.TAG, "changed: " + key); + + if (Utilities.indexOf(Preferences.SETTINGS_PREFERENCES, key) != -1) { + if (gLogPackets) + Log.d(ADK.TAG, "updating settings"); + updateSettings(sharedPreferences); + } else if (Preferences.PREF_TIME.equals(key)) { + updateTime(sharedPreferences); + } else if (Preferences.PREF_DISPLAY.equals(key)) { + updateDisplay(sharedPreferences); + } else if (Preferences.PREF_LOCKED.equals(key)) { + updateLocked(sharedPreferences); + } else if (Preferences.PREF_ALARM_SOUND.equals(key)) { + updateAlarmSound(sharedPreferences); + } + } + + private void updateSettings(SharedPreferences sharedPreferences) { + mIgnoreUpdatesUntil = System.currentTimeMillis() + 1000; + int color = sharedPreferences.getInt(Preferences.PREF_COLOR, + Preferences.PREF_DEFAULT_COLOR); + byte[] payload = mSettingsPayload; + int alarmTimeValue = sharedPreferences.getInt( + Preferences.PREF_ALARM_TIME, Preferences.DEFAULT_ALARM_TIME); + payload[0] = (byte) (alarmTimeValue / 60); + payload[1] = (byte) (alarmTimeValue % 60); + boolean alarmOn = sharedPreferences.getBoolean( + Preferences.PREF_ALARM_ON, false); + payload[2] = (byte) (alarmOn ? 1 : 0); + int brightness = sharedPreferences.getInt(Preferences.PREF_BRIGHTNESS, + 255); + payload[3] = (byte) brightness; + payload[4] = (byte) (((color >> 16) & 0xff)); + payload[5] = (byte) (((color >> 8) & 0xff)); + payload[6] = (byte) ((color & 0xff)); + int volume = sharedPreferences.getInt(Preferences.PREF_VOLUME, 128); + payload[7] = (byte) volume; + mSettingsBuffer = sendCommand(CMD_SETTINGS, CMD_SETTINGS, payload, + mSettingsBuffer); + } + + private void updateTime(SharedPreferences sharedPreferences) { + int timeValue = sharedPreferences.getInt(Preferences.PREF_TIME, 0); + byte[] payload = new byte[7]; + payload[0] = 0; + payload[1] = 0; + payload[2] = 0; + payload[3] = 0; + payload[4] = (byte) (timeValue / 60); + payload[5] = (byte) (timeValue % 60); + payload[6] = 0; + sendCommand(CMD_TIME, CMD_TIME, payload); + } + + private void updateDisplay(SharedPreferences sharedPreferences) { + int displayValue = sharedPreferences + .getInt(Preferences.PREF_DISPLAY, 0); + byte[] payload = new byte[1]; + payload[0] = (byte) displayValue; + sendCommand(CMD_DISPLAY_MODE, CMD_DISPLAY_MODE, payload); + } + + private void updateLocked(SharedPreferences sharedPreferences) { + boolean isLocked = sharedPreferences.getBoolean( + Preferences.PREF_LOCKED, false); + Log.i(ADK.TAG, "updating locked " + isLocked); + byte[] payload = new byte[1]; + payload[0] = (byte) (isLocked ? 2 : 0); + sendCommand(CMD_LOCK, CMD_LOCK, payload); + } + + private void updateAlarmSound(SharedPreferences sharedPreferences) { + String alarmSound = TUNES_FOLDER + "/" + + sharedPreferences.getString(Preferences.PREF_ALARM_SOUND, ""); + final int alarmSoundLength = alarmSound.length(); + if (alarmSoundLength > 0) { + byte[] payload = new byte[alarmSoundLength + 1]; + alarmSound.getBytes(0, alarmSoundLength, payload, 0); + payload[alarmSoundLength] = (byte) 0; + sendCommand(CMD_ALARM_FILE, CMD_ALARM_FILE, payload); + } + } + + private static class ProtocolHandler { + InputStream mInputStream; + Handler mHandler; + + public ProtocolHandler(Handler handler, InputStream inputStream) { + mHandler = handler; + mInputStream = inputStream; + } + + int readByte() throws IOException { + int retVal = mInputStream.read(); + if (retVal == -1) { + throw new RuntimeException("End of stream reached."); + } + return retVal; + } + + int readInt16() throws IOException { + int low = readByte(); + int high = readByte(); + if (gLogPackets) { + Log.i(ADK.TAG, "readInt16 low=" + low + " high=" + high); + } + return low | (high << 8); + } + + byte[] readBuffer(int bufferSize) throws IOException { + byte readBuffer[] = new byte[bufferSize]; + int index = 0; + int bytesToRead = bufferSize; + while (bytesToRead > 0) { + int amountRead = mInputStream.read(readBuffer, index, + bytesToRead); + if (amountRead == -1) { + throw new RuntimeException("End of stream reached."); + } + bytesToRead -= amountRead; + index += amountRead; + } + return readBuffer; + } + + public void process() { + mInputStream.mark(0); + try { + while (mInputStream.available() > 0) { + if (gLogPackets) + Log.i(ADK.TAG, "about to read opcode"); + int opCode = readByte(); + if (gLogPackets) + Log.i(ADK.TAG, "opCode = " + opCode); + if (isValidOpCode(opCode)) { + int sequence = readByte(); + if (gLogPackets) + Log.i(ADK.TAG, "sequence = " + sequence); + int replySize = readInt16(); + if (gLogPackets) + Log.i(ADK.TAG, "replySize = " + replySize); + byte[] replyBuffer = readBuffer(replySize); + if (gLogPackets) { + Log.i(ADK.TAG, + "replyBuffer: " + + Utilities.dumpBytes(replyBuffer, + replyBuffer.length)); + } + processReply(opCode & 0x7f, sequence, replyBuffer); + mInputStream.mark(0); + } + } + mInputStream.reset(); + } catch (IOException e) { + Log.i(ADK.TAG, "ProtocolHandler error " + e.toString()); + } + } + + boolean isValidOpCode(int opCodeWithReplyBitSet) { + if ((opCodeWithReplyBitSet & 0x80) != 0) { + int opCode = opCodeWithReplyBitSet & 0x7f; + return ((opCode >= CMD_GET_PROTO_VERSION) && (opCode <= CMD_LOCK)); + } + return false; + } + + private void processReply(int opCode, int sequence, byte[] replyBuffer) { + Message msg = mHandler.obtainMessage(opCode, sequence, 0, + replyBuffer); + mHandler.sendMessage(msg); + } + } + + public String[] getAlarmSounds() { + String[] r = new String[mSoundFiles.size()]; + return mSoundFiles.toArray(r); + } +} diff --git a/src/com/google/android/apps/adk2/activity/LicenseActivity.java b/src/com/google/android/apps/adk2/activity/LicenseActivity.java new file mode 100644 index 0000000..f642f0e --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/LicenseActivity.java @@ -0,0 +1,59 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.widget.TextView; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; + +public class LicenseActivity extends Adk2BaseActivity implements + OnSharedPreferenceChangeListener { + private TextView mLicenseTextView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.licenses); + + mLicenseTextView = (TextView) findViewById(R.id.license_text); + + SharedPreferences preferences = PreferenceManager + .getDefaultSharedPreferences(this); + preferences.registerOnSharedPreferenceChangeListener(this); + updateDisplay(preferences); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + + if (Preferences.PREF_LICENSE_TEXT.equals(key)) { + updateDisplay(sharedPreferences); + } + } + + private void updateDisplay(SharedPreferences sharedPreferences) { + String licenseText = sharedPreferences.getString( + Preferences.PREF_LICENSE_TEXT, ""); + mLicenseTextView.setText(licenseText); + } +} diff --git a/src/com/google/android/apps/adk2/activity/PresetsActivity.java b/src/com/google/android/apps/adk2/activity/PresetsActivity.java new file mode 100755 index 0000000..e5faaac --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/PresetsActivity.java @@ -0,0 +1,260 @@ +/* + * 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.google.android.apps.adk2.activity; + +import java.io.IOException; +import java.util.ArrayList; + +import android.app.Dialog; +import android.app.ListActivity; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.SparseBooleanArray; +import android.view.ActionMode; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.Toast; + +import com.google.android.apps.adk2.Presets; +import com.google.android.apps.adk2.R; + +public class PresetsActivity extends ListActivity { + + Presets mPresets; + boolean mWasPolling; + ArrayAdapter<Presets.Preset> mAdapter; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPresets = new Presets(); + try { + mPresets.load(this); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + Adk2BaseActivity.maybeDisplayHomeAsUp(this); + + setContentView(R.layout.presets); + + mAdapter = new ArrayAdapter<Presets.Preset>(this, + android.R.layout.simple_list_item_multiple_choice, + mPresets.getPresets()); + setListAdapter(mAdapter); + getListView().setMultiChoiceModeListener(new ModeCallback()); + getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); + + mWasPolling = HomeActivity.get().startPollingSettings(); + } + + protected void onDestroy() { + if (!mWasPolling) { + HomeActivity.get().stopPollingSettings(); + } + super.onDestroy(); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + Presets.Preset p = mPresets.getPresets().get(position); + SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this); + p.applyToPreferences(sharedPreferences); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.presets_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (Adk2BaseActivity.maybeHandleHomeMenuItem(item, this)) { + return true; + } + switch (item.getItemId()) { + case R.id.new_preset: + makeNewPreset(); + return true; + + default: + return false; + } + } + + private void makeNewPreset() { + SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(this); + Presets.Preset p = mPresets.makeNewPreset(sharedPreferences); + onContentChanged(); + RenamePresetController rpc = new RenamePresetController(p, true); + rpc.start(); + } + + void deletePreset(Presets.Preset preset) { + mAdapter.remove(preset); + } + + private void savePresets() { + try { + mPresets.save(this); + } catch (IOException e) { + // TODO Error message for save fail + e.printStackTrace(); + } + } + + void deleteSelectedItems() { + ListView lv = getListView(); + SparseBooleanArray checkedPositions = lv.getCheckedItemPositions(); + int count = checkedPositions.size(); + Resources res = getResources(); + String presetsDeleted = res.getQuantityString( + R.plurals.number_of_presets_deleted, count, count); + Toast.makeText(PresetsActivity.this, presetsDeleted, Toast.LENGTH_SHORT) + .show(); + ArrayList<Presets.Preset> presets = mPresets.getPresets(); + for (int i = count - 1; i >= 0; --i) { + int index = checkedPositions.keyAt(i); + if (index != -1) { + Presets.Preset p = presets.get(index); + deletePreset(p); + } + } + savePresets(); + } + + void editSelectedItems() { + ListView lv = getListView(); + SparseBooleanArray checkedPositions = lv.getCheckedItemPositions(); + int firstIndex = checkedPositions.keyAt(0); + if (firstIndex != -1) { + ArrayList<Presets.Preset> presets = mPresets.getPresets(); + Presets.Preset p = presets.get(firstIndex); + RenamePresetController rpc = new RenamePresetController(p, false); + rpc.start(); + } + } + + private class RenamePresetController implements OnClickListener { + Dialog mDialog; + Presets.Preset mPreset; + EditText mNameEdit; + Boolean mDeleteOnCancel; + + public RenamePresetController(Presets.Preset preset, + Boolean deleteOnCancel) { + mPreset = preset; + mDeleteOnCancel = deleteOnCancel; + } + + public void start() { + mDialog = new Dialog(PresetsActivity.this); + mDialog.setContentView(R.layout.preset_name_dialog); + Button cancel = (Button) mDialog + .findViewById(R.id.preset_edit_cancel); + cancel.setOnClickListener(this); + Button rename = (Button) mDialog + .findViewById(R.id.preset_edit_rename); + if (mDeleteOnCancel) { + rename.setText(R.string.create); + } + rename.setOnClickListener(this); + mNameEdit = (EditText) mDialog.findViewById(R.id.preset_name_edit); + mNameEdit.setText(mPreset.getName()); + mNameEdit.selectAll(); + mDialog.setTitle("Preset Name"); + mDialog.show(); + } + + public void onClick(View v) { + if (v.getId() == R.id.preset_edit_rename) { + mPreset.setName(mNameEdit.getText().toString()); + onContentChanged(); + savePresets(); + } else { + if (mDeleteOnCancel) { + deletePreset(mPreset); + } + } + mDialog.dismiss(); + + } + } + + private class ModeCallback implements ListView.MultiChoiceModeListener { + + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.list_select_menu, menu); + mode.setTitle("Select Items"); + return true; + } + + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return true; + } + + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + switch (item.getItemId()) { + case R.id.delete_preset: + deleteSelectedItems(); + mode.finish(); + break; + case R.id.edit_preset: + editSelectedItems(); + mode.finish(); + break; + } + return true; + } + + public void onDestroyActionMode(ActionMode mode) { + } + + public void onItemCheckedStateChanged(ActionMode mode, int position, + long id, boolean checked) { + final int checkedCount = getListView().getCheckedItemCount(); + switch (checkedCount) { + case 0: + mode.setSubtitle(null); + break; + case 1: + mode.setSubtitle("One item selected"); + break; + default: + mode.setSubtitle("" + checkedCount + " items selected"); + break; + } + } + + } +} diff --git a/src/com/google/android/apps/adk2/activity/VolumeActivity.java b/src/com/google/android/apps/adk2/activity/VolumeActivity.java new file mode 100644 index 0000000..096e267 --- /dev/null +++ b/src/com/google/android/apps/adk2/activity/VolumeActivity.java @@ -0,0 +1,48 @@ +/* + * 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.google.android.apps.adk2.activity; + +import android.content.SharedPreferences; +import android.os.Bundle; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.widget.SeekBarPreference; + +public class VolumeActivity extends Adk2PreferenceActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.volume_preferences); + updatePreferencesDisplay(); + } + + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, + String key) { + if (Preferences.PREF_VOLUME.equals(key)) + updatePreferencesDisplay(); + } + + private void updatePreferencesDisplay() { + SeekBarPreference vol = (SeekBarPreference) mPreferenceManager + .findPreference(Preferences.PREF_VOLUME); + if (vol != null) { + vol.setValue(mPreferences.getInt(Preferences.PREF_VOLUME, 0)); + } + } +}
\ No newline at end of file diff --git a/src/com/google/android/apps/adk2/views/ColorSensorView.java b/src/com/google/android/apps/adk2/views/ColorSensorView.java new file mode 100644 index 0000000..c278cfa --- /dev/null +++ b/src/com/google/android/apps/adk2/views/ColorSensorView.java @@ -0,0 +1,70 @@ +/* + * 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.google.android.apps.adk2.views; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.util.AttributeSet; +import android.view.View; + +public class ColorSensorView extends View { + Paint mCircle; + Paint mBorder; + + private final int kSize = 200; + + public ColorSensorView(Context context, AttributeSet attrs) { + super(context, attrs); + initColorSensorView(context); + } + + public ColorSensorView(Context context) { + super(context); + initColorSensorView(context); + } + + public ColorSensorView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + initColorSensorView(context); + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(kSize, kSize); + } + + private void initColorSensorView(Context context) { + mCircle = new Paint(); + mCircle.setARGB(255, 255, 0, 0); + mCircle.setStyle(Style.FILL); + + mBorder = new Paint(); + mBorder.setARGB(255, 255, 255, 255); + mBorder.setStyle(Style.STROKE); + } + + public void setSensedColor(int color) { + mCircle.setColor(color); + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + canvas.drawRect(0, 0, kSize - 1, kSize - 1, mBorder); + canvas.drawCircle(kSize / 2, kSize / 2, kSize / 8, mCircle); + } +} diff --git a/src/com/google/android/apps/adk2/views/Slider.java b/src/com/google/android/apps/adk2/views/Slider.java new file mode 100644 index 0000000..0a9ae98 --- /dev/null +++ b/src/com/google/android/apps/adk2/views/Slider.java @@ -0,0 +1,151 @@ +/* + * 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.google.android.apps.adk2.views; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.Utilities; + +public class Slider extends View { + + public interface SliderPositionListener { + void onPositionChange(Slider slider, double value); + } + + private Drawable mIndicator; + private Drawable mBackground; + private double mPosition; + private SliderPositionListener mListener; + private boolean mVertical; + + public Slider(Context context) { + super(context); + initSliderView(context, false); + } + + public Slider(Context context, AttributeSet attrs) { + super(context, attrs); + initSliderView(context, false); + } + + public void setSliderBackground(Drawable background) { + mBackground = background; + invalidate(); + } + + public void setPositionListener(SliderPositionListener listener) { + mListener = listener; + } + + public void setPosition(double position) { + if (mPosition != position) { + invalidate(); + mPosition = position; + if (mListener != null) { + mListener.onPositionChange(this, mPosition); + } + } + } + + private OnTouchListener mClickListener = new OnTouchListener() { + public boolean onTouch(View v, MotionEvent m) { + Rect r = new Rect(); + getDrawingRect(r); + + double position; + if (mVertical) { + double y = m.getY(); + position = Math.max(0, (r.bottom - y) / r.height()); + } else { + double x = m.getX(); + position = Math.max(0, (x - r.left) / r.width()); + } + position = Math.min(1, position); + setPosition(position); + return true; + } + }; + + protected void initSliderView(Context context, boolean vertical) { + mPosition = 0; + mVertical = vertical; + Resources res = context.getResources(); + if (mVertical) { + mBackground = res + .getDrawable(R.drawable.scrubber_vertical_blue_holo_dark); + } else { + mBackground = res + .getDrawable(R.drawable.scrubber_horizontal_holo_dark); + } + mIndicator = res.getDrawable(R.drawable.scrubber_control_holo_dark); + this.setOnTouchListener(mClickListener); + } + + protected void onDraw(Canvas canvas) { + Rect r = new Rect(); + getDrawingRect(r); + if (mVertical) { + int lineX = r.centerX(); + int bgW = mBackground.getIntrinsicWidth() / 2; + if (bgW == 0) { + bgW = 5; + } + mBackground.setBounds(lineX - bgW, r.top + 10, lineX + bgW, + r.bottom - 10); + mBackground.draw(canvas); + final int kMargin = 48; + int indicatorY = (int) (r.bottom - (r.height() - kMargin) + * mPosition) + - kMargin / 2; + Utilities.centerAround(lineX, indicatorY, mIndicator); + mIndicator.draw(canvas); + } else { + int lineY = r.centerY(); + int bgH = mBackground.getIntrinsicHeight() / 2; + if (bgH == 0) { + bgH = 5; + } + mBackground.setBounds(r.left + 10, lineY - bgH, r.right - 10, lineY + + bgH); + mBackground.draw(canvas); + final int kMargin = 48; + int indicatorX = (int) ((r.width() - kMargin) * mPosition) + r.left + + kMargin / 2; + Utilities.centerAround(indicatorX, lineY, mIndicator); + mIndicator.draw(canvas); + } + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mVertical) { + setMeasuredDimension(mIndicator.getIntrinsicWidth(), + getMeasuredHeight()); + } else { + setMeasuredDimension(getMeasuredWidth(), + mIndicator.getIntrinsicHeight()); + } + } + +} diff --git a/src/com/google/android/apps/adk2/widget/ActivityPreference.java b/src/com/google/android/apps/adk2/widget/ActivityPreference.java new file mode 100644 index 0000000..5eb5fe4 --- /dev/null +++ b/src/com/google/android/apps/adk2/widget/ActivityPreference.java @@ -0,0 +1,57 @@ +/* + * 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.google.android.apps.adk2.widget; + +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.preference.Preference; +import android.util.AttributeSet; +import android.util.Log; + +import com.google.android.apps.adk2.ADK; +import com.google.android.apps.adk2.R; + +public class ActivityPreference extends Preference { + String mActivityClassName; + + public ActivityPreference(Context context) { + this(context, null); + } + + public ActivityPreference(Context context, AttributeSet attrs) { + this(context, attrs, android.R.attr.preferenceStyle); + } + + public ActivityPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActivityPreference, defStyle, 0); + mActivityClassName = a.getString(R.styleable.ActivityPreference_classname); + a.recycle(); + } + + @Override + protected void onClick() { + try { + Class<?> activityClass = Class.forName(mActivityClassName); + Intent openNewIntent = new Intent(getContext(), activityClass); + getContext().startActivity(openNewIntent); + } catch (ClassNotFoundException e) { + Log.e(ADK.TAG, "class not found in ActivityPreference", e); + } + } +} diff --git a/src/com/google/android/apps/adk2/widget/SeekBarPreference.java b/src/com/google/android/apps/adk2/widget/SeekBarPreference.java new file mode 100644 index 0000000..b4c9c02 --- /dev/null +++ b/src/com/google/android/apps/adk2/widget/SeekBarPreference.java @@ -0,0 +1,102 @@ +/* + * 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.google.android.apps.adk2.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.preference.Preference; +import android.util.AttributeSet; +import android.view.View; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; + +import com.google.android.apps.adk2.R; + +public class SeekBarPreference extends Preference implements OnSeekBarChangeListener { + private int mMax; + private int mValue; + private boolean mTrackingTouch; + + public SeekBarPreference(Context context) { + this(context, null); + } + + public SeekBarPreference(Context context, AttributeSet attrs) { + this(context, attrs, android.R.attr.preferenceStyle); + } + + public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference, defStyle, 0); + mMax = a.getInteger(R.styleable.SeekBarPreference_max, 0); + a.recycle(); + + setLayoutResource(R.layout.seekbar_preference); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + + SeekBar seekBar = (SeekBar)view.findViewById(R.id.seekbar); + seekBar.setMax(mMax); + seekBar.setProgress(mValue); + seekBar.setEnabled(isEnabled()); + + seekBar.setOnSeekBarChangeListener(this); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setValue(restoreValue ? getPersistedInt(0) : (Integer)defaultValue); + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getInt(index, 0); + } + + public void setValue(int value) { + if (value > mMax) value = mMax; + if (value < 0) value = 0; + + if (value != mValue) { + mValue = value; + persistInt(value); + if (!mTrackingTouch) + notifyChanged(); + } + } + + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (progress != mValue) { + if (callChangeListener(progress)) { + setValue(progress); + } else { + seekBar.setProgress(progress); + } + } + } + + public void onStartTrackingTouch(SeekBar seekBar) { + mTrackingTouch = true; + } + + public void onStopTrackingTouch(SeekBar seekBar) { + mTrackingTouch = false; + } +} diff --git a/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java b/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java new file mode 100644 index 0000000..bc87c39 --- /dev/null +++ b/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java @@ -0,0 +1,62 @@ +/* + * 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.google.android.apps.adk2.widget; + +import java.util.Date; + +import android.content.Context; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TimePicker; + +import com.google.android.apps.adk2.Preferences; +import com.google.android.apps.adk2.R; +import com.google.android.apps.adk2.Utilities; + +public class TimeDialogPreference extends DialogPreference { + private TimePicker mTimePicker; + + public TimeDialogPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onBindDialogView(View view) { + super.onBindDialogView(view); + mTimePicker = (TimePicker) view.findViewById(R.id.time_picker); + + int time = 0; + if (getKey().equals(Preferences.PREF_ALARM_TIME)) { + time = getPersistedInt(Preferences.DEFAULT_ALARM_TIME); + } else { + Date d = new Date(); + time = Utilities.dateToTimeValue(d); + } + mTimePicker.setCurrentHour(time / 60); + mTimePicker.setCurrentMinute(time % 60); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + if (positiveResult) { + persistInt(Utilities.dateToTimeValue(mTimePicker.getCurrentHour(), + mTimePicker.getCurrentMinute())); + } + } +} |