diff options
author | John Spurlock <jspurlock@google.com> | 2012-07-27 10:54:08 -0400 |
---|---|---|
committer | John Spurlock <jspurlock@google.com> | 2012-07-27 15:49:10 -0400 |
commit | 3e190ede751474c7e1b87b34e36354c0ef9e8af4 (patch) | |
tree | 66e87ba62290a71df1a325ea7746f875b0b1edc3 /apps | |
parent | 3d1fd6f05a58463a8d56f7ba374240a093a061d0 (diff) | |
download | sdk-3e190ede751474c7e1b87b34e36354c0ef9e8af4.zip sdk-3e190ede751474c7e1b87b34e36354c0ef9e8af4.tar.gz sdk-3e190ede751474c7e1b87b34e36354c0ef9e8af4.tar.bz2 |
Notification Studio initial commit.
Demo app for designing/previewing Android notifications on the device itself.
Simple UI for tweaking the various options available when constructing
notifications, including the new expanded builder styles introduced in api 16.
Notification designs can be shared as mockups (images) or code.
Uses latest support lib for compatibility back to api 10.
Change-Id: I3b6c539b36786ea5335f95a9ded4fb50ea5d0a00
Diffstat (limited to 'apps')
45 files changed, 2341 insertions, 0 deletions
diff --git a/apps/NotificationStudio/.classpath b/apps/NotificationStudio/.classpath new file mode 100644 index 0000000..a4763d1 --- /dev/null +++ b/apps/NotificationStudio/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="gen"/> + <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> + <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> + <classpathentry kind="output" path="bin/classes"/> +</classpath> diff --git a/apps/NotificationStudio/.project b/apps/NotificationStudio/.project new file mode 100644 index 0000000..00f0a21 --- /dev/null +++ b/apps/NotificationStudio/.project @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>NotificationStudio</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/apps/NotificationStudio/.settings/org.eclipse.jdt.core.prefs b/apps/NotificationStudio/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f77b31c --- /dev/null +++ b/apps/NotificationStudio/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/apps/NotificationStudio/AndroidManifest.xml b/apps/NotificationStudio/AndroidManifest.xml new file mode 100644 index 0000000..cb849e0 --- /dev/null +++ b/apps/NotificationStudio/AndroidManifest.xml @@ -0,0 +1,38 @@ +<!-- + Copyright 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.notificationstudio" + android:versionCode="5" + android:versionName="0.5" > + + <uses-sdk android:targetSdkVersion="16" android:minSdkVersion="10" /> + + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + + <application android:label="@string/app_name" > + <activity + android:name=".NotificationStudioActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + +</manifest>
\ No newline at end of file diff --git a/apps/NotificationStudio/libs/android-support-v4.jar b/apps/NotificationStudio/libs/android-support-v4.jar Binary files differnew file mode 100644 index 0000000..f92dea2 --- /dev/null +++ b/apps/NotificationStudio/libs/android-support-v4.jar diff --git a/apps/NotificationStudio/project.properties b/apps/NotificationStudio/project.properties new file mode 100644 index 0000000..9b84a6b --- /dev/null +++ b/apps/NotificationStudio/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=android-16 diff --git a/apps/NotificationStudio/res/drawable-hdpi/android_logo.gif b/apps/NotificationStudio/res/drawable-hdpi/android_logo.gif Binary files differnew file mode 100644 index 0000000..6078e86 --- /dev/null +++ b/apps/NotificationStudio/res/drawable-hdpi/android_logo.gif diff --git a/apps/NotificationStudio/res/drawable-hdpi/ic_notification_multiple_mail_holo_dark.png b/apps/NotificationStudio/res/drawable-hdpi/ic_notification_multiple_mail_holo_dark.png Binary files differnew file mode 100644 index 0000000..c4f3648 --- /dev/null +++ b/apps/NotificationStudio/res/drawable-hdpi/ic_notification_multiple_mail_holo_dark.png diff --git a/apps/NotificationStudio/res/drawable-hdpi/romain.jpg b/apps/NotificationStudio/res/drawable-hdpi/romain.jpg Binary files differnew file mode 100644 index 0000000..e932901 --- /dev/null +++ b/apps/NotificationStudio/res/drawable-hdpi/romain.jpg diff --git a/apps/NotificationStudio/res/drawable-nodpi/icon_bg.xml b/apps/NotificationStudio/res/drawable-nodpi/icon_bg.xml new file mode 100644 index 0000000..dcecdd3 --- /dev/null +++ b/apps/NotificationStudio/res/drawable-nodpi/icon_bg.xml @@ -0,0 +1,29 @@ +<!-- + Copyright 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. + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_selected="true"> + <shape android:shape="rectangle"> + <solid android:color="@color/icon_background" /> + <stroke android:width="1px" android:color="@android:color/holo_blue_light" /> + </shape> + </item> + <item> + <shape android:shape="rectangle"> + <solid android:color="@color/icon_background" /> + </shape> + </item> +</selector>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/drawable-nodpi/romainguy_rockaway.jpg b/apps/NotificationStudio/res/drawable-nodpi/romainguy_rockaway.jpg Binary files differnew file mode 100644 index 0000000..68473ba --- /dev/null +++ b/apps/NotificationStudio/res/drawable-nodpi/romainguy_rockaway.jpg diff --git a/apps/NotificationStudio/res/layout-v14/boolean_editor.xml b/apps/NotificationStudio/res/layout-v14/boolean_editor.xml new file mode 100644 index 0000000..ae77468 --- /dev/null +++ b/apps/NotificationStudio/res/layout-v14/boolean_editor.xml @@ -0,0 +1,21 @@ +<!-- + Copyright 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. + --> + + <Switch xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> diff --git a/apps/NotificationStudio/res/layout-v16/studio.xml b/apps/NotificationStudio/res/layout-v16/studio.xml new file mode 100644 index 0000000..083ac79 --- /dev/null +++ b/apps/NotificationStudio/res/layout-v16/studio.xml @@ -0,0 +1,33 @@ +<!-- + Copyright 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. + --> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.android.notificationstudio.MaxHeightScrollView + android:id="@+id/preview_scroller" + android:layout_width="@dimen/notification_panel_width" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="5dp" > + + <include layout="@layout/preview" /> + </com.android.notificationstudio.MaxHeightScrollView> + + <include layout="@layout/editors" /> + +</FrameLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout-w801dp/studio.xml b/apps/NotificationStudio/res/layout-w801dp/studio.xml new file mode 100644 index 0000000..0391f8b --- /dev/null +++ b/apps/NotificationStudio/res/layout-w801dp/studio.xml @@ -0,0 +1,28 @@ +<!-- + Copyright 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <include + android:layout_width="@dimen/notification_panel_width" + android:layout_height="match_parent" + layout="@layout/preview" /> + + <include layout="@layout/editors" /> + +</LinearLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout/boolean_editor.xml b/apps/NotificationStudio/res/layout/boolean_editor.xml new file mode 100644 index 0000000..e482322 --- /dev/null +++ b/apps/NotificationStudio/res/layout/boolean_editor.xml @@ -0,0 +1,20 @@ +<!-- + Copyright 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. + --> + +<View xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> diff --git a/apps/NotificationStudio/res/layout/divider.xml b/apps/NotificationStudio/res/layout/divider.xml new file mode 100644 index 0000000..d2e20f8 --- /dev/null +++ b/apps/NotificationStudio/res/layout/divider.xml @@ -0,0 +1,40 @@ +<!-- + Copyright 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. + --> + +<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/divider_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="@dimen/editor_inset" + android:layout_marginTop="3dp" + android:textAllCaps="true" + android:textColor="@color/divider_text" + android:textSize="@dimen/editor_text_size" /> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:layout_marginLeft="@dimen/editor_inset" + android:layout_marginRight="@dimen/editor_inset" + android:layout_marginTop="3dp" + android:background="@color/divider_text" /> + +</LinearLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout/editable_item.xml b/apps/NotificationStudio/res/layout/editable_item.xml new file mode 100644 index 0000000..816dd0f --- /dev/null +++ b/apps/NotificationStudio/res/layout/editable_item.xml @@ -0,0 +1,111 @@ +<!-- + Copyright 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. + --> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/list_item_text" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="@dimen/editor_inset" > + + <TextView + android:id="@+id/caption" + android:layout_width="@dimen/editor_caption_width" + android:layout_height="wrap_content" + android:paddingBottom="@dimen/caption_padding_bottom" + android:paddingTop="@dimen/caption_padding_top" + android:textSize="@dimen/editor_text_size" /> + + <EditText + android:id="@+id/text_editor" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/caption" + android:imeOptions="actionDone" + android:inputType="text" + android:paddingTop="0dp" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> + + <View + android:layout_width="0px" + android:layout_height="0px" + android:focusable="true" + android:focusableInTouchMode="true" /> + + <ViewStub + android:id="@+id/boolean_editor_stub" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/caption" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> + + <Spinner + android:id="@+id/drop_down_editor" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/caption" + android:focusable="true" + android:focusableInTouchMode="true" + android:visibility="gone" /> + + <HorizontalScrollView + android:id="@+id/icon_editor_scroller" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_toRightOf="@id/caption" + android:scrollbars="none" + android:visibility="gone" > + + <LinearLayout + android:id="@+id/icon_editor_layout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + </LinearLayout> + </HorizontalScrollView> + + <Button + android:id="@+id/date_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/caption" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> + + <Button + android:id="@+id/time_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/date_button" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> + + <Button + android:id="@+id/reset_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBaseline="@id/caption" + android:layout_toRightOf="@id/time_button" + android:text="@string/now" + android:textSize="@dimen/editor_text_size" + android:visibility="gone" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout/editors.xml b/apps/NotificationStudio/res/layout/editors.xml new file mode 100644 index 0000000..7c7e120 --- /dev/null +++ b/apps/NotificationStudio/res/layout/editors.xml @@ -0,0 +1,29 @@ +<!-- + Copyright 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. + --> + +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/editors" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@android:color/black" > + + <LinearLayout + android:id="@+id/items" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" /> + +</ScrollView>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout/preview.xml b/apps/NotificationStudio/res/layout/preview.xml new file mode 100644 index 0000000..3d9c7a0 --- /dev/null +++ b/apps/NotificationStudio/res/layout/preview.xml @@ -0,0 +1,56 @@ +<!-- + Copyright 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. +--> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/preview" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + <FrameLayout + android:id="@+id/ticker" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:visibility="gone" /> + + <ImageView + android:id="@+id/large_icon" + android:layout_width="@android:dimen/notification_large_icon_width" + android:layout_height="@android:dimen/notification_large_icon_height" + android:layout_alignParentLeft="true" + android:layout_below="@id/ticker" + android:scaleType="center" + android:visibility="gone" + tools:ignore="ContentDescription" /> + + <FrameLayout + android:id="@+id/oneU" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/ticker" + android:layout_marginTop="5dp" + android:layout_toRightOf="@id/large_icon" + android:visibility="gone" /> + + <FrameLayout + android:id="@+id/fourU" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_below="@id/oneU" + android:layout_marginTop="5dp" + android:visibility="gone" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/layout/studio.xml b/apps/NotificationStudio/res/layout/studio.xml new file mode 100644 index 0000000..2646a44 --- /dev/null +++ b/apps/NotificationStudio/res/layout/studio.xml @@ -0,0 +1,26 @@ +<!-- + Copyright 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <include layout="@layout/preview" /> + + <include layout="@layout/editors" /> + +</LinearLayout>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/menu/action_bar.xml b/apps/NotificationStudio/res/menu/action_bar.xml new file mode 100644 index 0000000..35c897f --- /dev/null +++ b/apps/NotificationStudio/res/menu/action_bar.xml @@ -0,0 +1,30 @@ +<!-- + Copyright 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. + --> + +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item + android:id="@+id/action_share_code" + android:icon="@android:drawable/ic_menu_share" + android:showAsAction="never" + android:title="@string/share_generated_code"/> + <item + android:id="@+id/action_share_mockup" + android:icon="@android:drawable/ic_menu_share" + android:showAsAction="never" + android:title="@string/share_mockup"/> + +</menu>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values-sw600dp/dimens.xml b/apps/NotificationStudio/res/values-sw600dp/dimens.xml new file mode 100644 index 0000000..22e863f --- /dev/null +++ b/apps/NotificationStudio/res/values-sw600dp/dimens.xml @@ -0,0 +1,24 @@ +<!-- + Copyright 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. + --> + +<resources> + + <dimen name="notification_panel_width">446dp</dimen> + <dimen name="caption_padding_bottom">6dp</dimen> + <dimen name="editor_text_size">16dp</dimen> + <dimen name="editor_caption_width">110dp</dimen> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values-sw720dp/dimens.xml b/apps/NotificationStudio/res/values-sw720dp/dimens.xml new file mode 100644 index 0000000..f896047 --- /dev/null +++ b/apps/NotificationStudio/res/values-sw720dp/dimens.xml @@ -0,0 +1,21 @@ +<!-- + Copyright 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. + --> + +<resources> + + <dimen name="notification_panel_width">448dp</dimen> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values-v11/colors.xml b/apps/NotificationStudio/res/values-v11/colors.xml new file mode 100644 index 0000000..224b09e --- /dev/null +++ b/apps/NotificationStudio/res/values-v11/colors.xml @@ -0,0 +1,21 @@ +<!-- + Copyright 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. +--> + +<resources> + + <color name="divider_text">@android:color/holo_blue_bright</color> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values-v11/dimens.xml b/apps/NotificationStudio/res/values-v11/dimens.xml new file mode 100644 index 0000000..f5fd098 --- /dev/null +++ b/apps/NotificationStudio/res/values-v11/dimens.xml @@ -0,0 +1,21 @@ +<!-- + Copyright 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. +--> + +<resources> + + <dimen name="caption_padding_top">6dp</dimen> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values/colors.xml b/apps/NotificationStudio/res/values/colors.xml new file mode 100644 index 0000000..aabe9bc --- /dev/null +++ b/apps/NotificationStudio/res/values/colors.xml @@ -0,0 +1,23 @@ +<!-- + Copyright 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. +--> + +<resources> + + <color name="gb_background">#dddddd</color> + <color name="divider_text">#dddddd</color> + <color name="icon_background">#3333B5E5</color> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values/dimens.xml b/apps/NotificationStudio/res/values/dimens.xml new file mode 100644 index 0000000..e960ae6 --- /dev/null +++ b/apps/NotificationStudio/res/values/dimens.xml @@ -0,0 +1,33 @@ +<!-- + Copyright 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. + --> + +<resources> + + <dimen name="notification_panel_width">-1dp</dimen> <!-- MATCH_PARENT --> + <dimen name="editor_inset">8dp</dimen> + <dimen name="caption_padding_top">10dp</dimen> + <dimen name="caption_padding_bottom">0dp</dimen> + <dimen name="editor_text_size">12dp</dimen> + <dimen name="editor_caption_width">95dp</dimen> + <dimen name="editor_icon_size_small">40dp</dimen> + <dimen name="editor_icon_size_large">60dp</dimen> + <dimen name="editor_icon_outer_margin">5dp</dimen> + <dimen name="editor_icon_inner_margin">2dp</dimen> + <dimen name="editor_drop_down_padding">5dp</dimen> + <dimen name="editor_datetime_padding_v">0dp</dimen> + <dimen name="editor_datetime_padding_h">15dp</dimen> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/res/values/strings.xml b/apps/NotificationStudio/res/values/strings.xml new file mode 100644 index 0000000..e3990f3 --- /dev/null +++ b/apps/NotificationStudio/res/values/strings.xml @@ -0,0 +1,55 @@ +<!-- + Copyright 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. +--> + +<resources> + + <string name="app_name">Notification Studio</string> + <string name="now">Now</string> + <string name="share_generated_code">Share generated code…</string> + <string name="share_mockup">Share mockup…</string> + <string name="preset">Preset</string> + <string name="small_icon">Small Icon</string> + <string name="content_title">Content Title</string> + <string name="content_text">Content Text</string> + <string name="sub_text">Sub Text</string> + <string name="large_icon">Large Icon</string> + <string name="content_info">Content Info</string> + <string name="number">Number</string> + <string name="when">When</string> + <string name="progress">Progress</string> + <string name="uses_chron">Uses Chron</string> + <string name="style">Style</string> + <string name="picture">Picture</string> + <string name="big_text">Big Text</string> + <string name="lines">Lines</string> + <string name="big_content_title">Big Content Title</string> + <string name="summary_text">Summary Text</string> + <string name="icon">Icon</string> + <string name="text">Text</string> + <string name="properties">Properties</string> + <string name="action_1">Action 1</string> + <string name="action_2">Action 2</string> + <string name="action_3">Action 3</string> + <string name="preset_custom">(custom)</string> + <string name="preset_basic">Basic example</string> + <string name="preset_email">Email example</string> + <string name="preset_photo">Photo example</string> + <string name="style_none">(none)</string> + <string name="style_big_picture">BigPictureStyle</string> + <string name="style_big_text">BigTextStyle</string> + <string name="style_inbox">InboxStyle</string> + +</resources>
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/MaxHeightScrollView.java b/apps/NotificationStudio/src/com/android/notificationstudio/MaxHeightScrollView.java new file mode 100644 index 0000000..1fc0284 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/MaxHeightScrollView.java @@ -0,0 +1,41 @@ +/* + * Copyright 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.android.notificationstudio; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.ScrollView; + +public class MaxHeightScrollView extends ScrollView { + + private int mMaxHeight; + + public MaxHeightScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void setMaxHeight(int maxHeight) { + mMaxHeight = maxHeight; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + setMeasuredDimension(getMeasuredWidth(), Math.min(getMeasuredHeight(), mMaxHeight)); + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/NotificationStudioActivity.java b/apps/NotificationStudio/src/com/android/notificationstudio/NotificationStudioActivity.java new file mode 100644 index 0000000..9c2e811 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/NotificationStudioActivity.java @@ -0,0 +1,249 @@ +/* + * Copyright 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.android.notificationstudio; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.app.Activity; +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnLayoutChangeListener; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; +import android.widget.TextView; + +import com.android.notificationstudio.action.ShareCodeAction; +import com.android.notificationstudio.action.ShareMockupAction; +import com.android.notificationstudio.editor.Editors; +import com.android.notificationstudio.generator.NotificationGenerator; +import com.android.notificationstudio.model.EditableItem; +import com.android.notificationstudio.model.EditableItemConstants; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class NotificationStudioActivity extends Activity implements EditableItemConstants{ + private static final String TAG = NotificationStudioActivity.class.getSimpleName(); + private static final int PREVIEW_NOTIFICATION = 1; + private static final int REFRESH_DELAY = 50; + private static final ExecutorService BACKGROUND = Executors.newSingleThreadExecutor(); + + private boolean mRefreshPending; + + private final Handler mHandler = new Handler(); + private final Runnable mRefreshNotificationInner = new Runnable() { + public void run() { + refreshNotificationInner(); + }}; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().setBackgroundDrawableResource(android.R.color.black); + setContentView(R.layout.studio); + initPreviewScroller(); + + EditableItem.initIfNecessary(this); + + initEditors(); + } + + private void initPreviewScroller() { + + MaxHeightScrollView preview = (MaxHeightScrollView) findViewById(R.id.preview_scroller); + if (preview == null) + return; + final int margin = ((ViewGroup.MarginLayoutParams) preview.getLayoutParams()).bottomMargin; + preview.addOnLayoutChangeListener(new OnLayoutChangeListener(){ + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + // animate preview height changes + if (oldBottom != bottom) { + final View e = findViewById(R.id.editors); + final int y = bottom + margin; + e.animate() + .translationY(y - oldBottom) + .setListener(new AnimatorListenerAdapter() { + public void onAnimationEnd(Animator animation) { + FrameLayout.LayoutParams lp = (LayoutParams) e.getLayoutParams(); + lp.topMargin = y; + e.setTranslationY(0); + e.setLayoutParams(lp); + } + }); + } + }}); + + // limit the max height for preview, leave room for editors + soft keyboard + DisplayMetrics dm = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(dm); + float actualHeight = dm.heightPixels / dm.ydpi; + float pct = actualHeight < 3.5 ? .32f : + actualHeight < 4 ? .35f : + .38f; + preview.setMaxHeight((int)(dm.heightPixels * pct)); + } + + private void initEditors() { + LinearLayout items = (LinearLayout) findViewById(R.id.items); + items.removeAllViews(); + String currentCategory = null; + for (EditableItem item : EditableItem.values()) { + String itemCategory = item.getCategory(this); + if (!itemCategory.equals(currentCategory)) { + View dividerView = getLayoutInflater().inflate(R.layout.divider, null); + ((TextView) dividerView.findViewById(R.id.divider_text)).setText(itemCategory); + items.addView(dividerView); + currentCategory = itemCategory; + } + View editorView = Editors.newEditor(this, items, item); + if (editorView != null) + items.addView(editorView); + } + refreshNotification(); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + // we'll take care of restoring state + } + + public void refreshNotification() { + mRefreshPending = true; + mHandler.postDelayed(mRefreshNotificationInner, REFRESH_DELAY); + } + + private void refreshNotificationInner() { + if (!mRefreshPending) { + return; + } + final Notification notification = NotificationGenerator.build(this); + ViewGroup oneU = (ViewGroup) findViewById(R.id.oneU); + ViewGroup fourU = (ViewGroup) findViewById(R.id.fourU); + View oneUView = refreshRemoteViews(oneU, notification.contentView); + if (Build.VERSION.SDK_INT >= 16) + refreshRemoteViews(fourU, notification.bigContentView); + else if (Build.VERSION.SDK_INT >= 11) { + ImageView largeIcon = (ImageView) findViewById(R.id.large_icon); + largeIcon.setVisibility(notification.largeIcon == null ? View.GONE : View.VISIBLE); + if (notification.largeIcon != null) + largeIcon.setImageBitmap(notification.largeIcon); + } else if (oneUView != null) { + oneUView.setBackgroundColor(getResources().getColor(R.color.gb_background)); + oneUView.setMinimumHeight(100); + } + mRefreshPending = false; + + // this can take a while, run on a background thread + BACKGROUND.submit(new Runnable() { + public void run() { + NotificationManager mgr = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + try { + mgr.notify(PREVIEW_NOTIFICATION, notification); + } catch (Throwable t) { + Log.w(TAG, "Error displaying notification", t); + } + }}); + } + + private View refreshRemoteViews(ViewGroup parent, RemoteViews remoteViews) { + parent.removeAllViews(); + if (remoteViews != null) { + parent.setVisibility(View.VISIBLE); + try { + View v = remoteViews.apply(this, parent); + parent.addView(v); + return v; + } catch (Exception e) { + TextView exceptionView = new TextView(this); + exceptionView.setText(e.getClass().getSimpleName() + ": " + e.getMessage()); + parent.addView(exceptionView); + return exceptionView; + } + } else { + parent.setVisibility(View.GONE); + return null; + } + } + + // action bar setup + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.action_bar, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_share_code: + ShareCodeAction.launch(this, item.getTitle()); + return true; + case R.id.action_share_mockup: + ShareMockupAction.launch(this, item.getTitle()); + return true; + } + return false; + } + + // hides the soft keyboard more aggressively when leaving text editors + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + View v = getCurrentFocus(); + boolean ret = super.dispatchTouchEvent(event); + + if (v instanceof EditText) { + View currentFocus = getCurrentFocus(); + int screenCoords[] = new int[2]; + currentFocus.getLocationOnScreen(screenCoords); + float x = event.getRawX() + currentFocus.getLeft() - screenCoords[0]; + float y = event.getRawY() + currentFocus.getTop() - screenCoords[1]; + + if (event.getAction() == MotionEvent.ACTION_UP + && (x < currentFocus.getLeft() || + x >= currentFocus.getRight() || + y < currentFocus.getTop() || + y > currentFocus.getBottom())) { + InputMethodManager imm = + (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0); + } + } + return ret; + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareCodeAction.java b/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareCodeAction.java new file mode 100644 index 0000000..d7da434 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareCodeAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 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.android.notificationstudio.action; + +import android.content.Context; +import android.content.Intent; + +import com.android.notificationstudio.generator.CodeGenerator; + +public class ShareCodeAction { + + public static void launch(Context context, CharSequence title) { + String shareBody = CodeGenerator.generate(context); + Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); + sharingIntent.setType("text/plain"); + sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Notification Code"); + sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody); + context.startActivity(Intent.createChooser(sharingIntent, title)); + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareMockupAction.java b/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareMockupAction.java new file mode 100644 index 0000000..e377475 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/action/ShareMockupAction.java @@ -0,0 +1,79 @@ +/* + * Copyright 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.android.notificationstudio.action; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.net.Uri; +import android.util.Log; +import android.view.View; +import android.widget.Toast; + +import com.android.notificationstudio.R; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ShareMockupAction { + private static final String TAG = ShareMockupAction.class.getSimpleName(); + + private static final SimpleDateFormat FILE_NAME = + new SimpleDateFormat("'notification.'yyyyMMdd'.'HHmmss'.png'"); + + public static void launch(Activity activity, CharSequence title) { + // take a picture of the current mockup + View v = activity.findViewById(R.id.preview); + int w = v.getMeasuredWidth(); + int h = v.getMeasuredHeight(); + Bitmap mockup = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(mockup); + v.layout(0, 0, w, h); + v.draw(c); + + // write the mockup to a temp file + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + mockup.compress(Bitmap.CompressFormat.PNG, 100, bytes); + File f = new File(activity.getExternalCacheDir(), FILE_NAME.format(new Date())); + FileOutputStream fo = null; + try { + f.createNewFile(); + fo = new FileOutputStream(f); + fo.write(bytes.toByteArray()); + } catch (IOException e) { + String msg = "Error writing mockup file"; + Log.w(TAG, msg, e); + Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show(); + return; + } finally { + if (fo != null) + try { fo.close(); } catch (Exception e) { } + } + + // launch intent to send the mockup image + Intent share = new Intent(Intent.ACTION_SEND); + share.setType("image/png"); + share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f.getAbsoluteFile())); + activity.startActivity(Intent.createChooser(share, title)); + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/BitmapEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/BitmapEditor.java new file mode 100644 index 0000000..04194ac --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/BitmapEditor.java @@ -0,0 +1,36 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.widget.ImageView; + +import com.android.notificationstudio.R; + +public class BitmapEditor extends IconEditor { + + @Override + protected void setImage(ImageView imageView, Object value) { + imageView.setImageBitmap((Bitmap) value); + } + + protected int getIconSize(Resources res) { + return res.getDimensionPixelSize(R.dimen.editor_icon_size_large); + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/BooleanEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/BooleanEditor.java new file mode 100644 index 0000000..6a6a8cf --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/BooleanEditor.java @@ -0,0 +1,49 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.view.View; +import android.view.ViewStub; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.Switch; + +import com.android.notificationstudio.R; +import com.android.notificationstudio.editor.Editors.Editor; +import com.android.notificationstudio.model.EditableItem; + +public class BooleanEditor implements Editor { + + public Runnable bindEditor(View v, final EditableItem item, final Runnable afterChange) { + final ViewStub booleanEditorStub = (ViewStub) v.findViewById(R.id.boolean_editor_stub); + booleanEditorStub.setLayoutResource(R.layout.boolean_editor); + final Switch booleanEditor = (Switch) booleanEditorStub.inflate(); + Runnable updateSwitch = new Runnable() { + public void run() { + booleanEditor.setChecked(item.hasValue() && item.getValueBool()); + }}; + booleanEditor.setVisibility(View.VISIBLE); + updateSwitch.run(); + booleanEditor.setOnCheckedChangeListener(new OnCheckedChangeListener(){ + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + item.setValue(isChecked); + afterChange.run(); + }}); + return updateSwitch; + } + +}
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/DateTimeEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/DateTimeEditor.java new file mode 100644 index 0000000..8089de1 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/DateTimeEditor.java @@ -0,0 +1,139 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.app.Activity; +import android.app.DatePickerDialog; +import android.app.DatePickerDialog.OnDateSetListener; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.FragmentTransaction; +import android.app.TimePickerDialog; +import android.app.TimePickerDialog.OnTimeSetListener; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.TimePicker; + +import com.android.notificationstudio.R; +import com.android.notificationstudio.editor.Editors.Editor; +import com.android.notificationstudio.model.EditableItem; + +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateTimeEditor implements Editor { + private static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat("yyyy/MM/dd"); + private static final SimpleDateFormat HH_MM_SS = new SimpleDateFormat("HH:mm:ss"); + + @SuppressWarnings("deprecation") + public Runnable bindEditor(View v, final EditableItem item, final Runnable afterChange) { + + final Button dateButton = (Button) v.findViewById(R.id.date_button); + final Button timeButton = (Button) v.findViewById(R.id.time_button); + final Button resetButton = (Button) v.findViewById(R.id.reset_button); + + int vPad = v.getResources().getDimensionPixelSize(R.dimen.editor_datetime_padding_v); + int hPad = v.getResources().getDimensionPixelSize(R.dimen.editor_datetime_padding_h); + for (Button b : new Button[] { dateButton, timeButton, resetButton }) { + b.setVisibility(View.VISIBLE); + b.setPadding(hPad, vPad, hPad, vPad); + } + + final Runnable updateButtonText = new Runnable() { + public void run() { + Date d = getDateTime(item); + String dateString = YYYY_MM_DD.format(d); + dateButton.setText(dateString); + String timeString = HH_MM_SS.format(d); + timeButton.setText(timeString); + }}; + updateButtonText.run(); + + // wire up date button + DialogFragment datePickerFragment = new DialogFragment() { + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Date d = getDateTime(item); + OnDateSetListener onDateSet = new OnDateSetListener() { + public void onDateSet(DatePicker view, int year, + int monthOfYear, int dayOfMonth) { + Date d = getDateTime(item); + d.setYear(year - 1900); + d.setMonth(monthOfYear); + d.setDate(dayOfMonth); + item.setValue(d.getTime()); + updateButtonText.run(); + afterChange.run(); + } + }; + return new DatePickerDialog(getActivity(), onDateSet, + d.getYear() + 1900, d.getMonth(), d.getDate()); + } + }; + Activity activity = (Activity) v.getContext(); + launchDialogOnClick(activity, "datePicker", dateButton, datePickerFragment); + + // wire up time button + DialogFragment timePickerFragment = new DialogFragment() { + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Date d = getDateTime(item); + OnTimeSetListener onTimeSet = new OnTimeSetListener() { + public void onTimeSet(TimePicker view, int hourOfDay, + int minute) { + Date d = getDateTime(item); + d.setHours(hourOfDay); + d.setMinutes(minute); + item.setValue(d.getTime()); + updateButtonText.run(); + afterChange.run(); + } + }; + return new TimePickerDialog(getActivity(), + onTimeSet, d.getHours(), d.getMinutes(), true); + } + }; + launchDialogOnClick(activity, "timePicker", timeButton, timePickerFragment); + + // wire up reset button + resetButton.setOnClickListener(new OnClickListener(){ + public void onClick(View v) { + item.setValue(null); + updateButtonText.run(); + afterChange.run(); + }}); + return updateButtonText; + } + + private static Date getDateTime(EditableItem item) { + long value = item.hasValue() ? item.getValueLong() : System.currentTimeMillis(); + return new Date(value); + } + + private static void launchDialogOnClick(final Activity activity, + final String tag, Button button, final DialogFragment fragment) { + button.setOnClickListener(new OnClickListener(){ + public void onClick(View v) { + FragmentTransaction ft = activity.getFragmentManager().beginTransaction(); + fragment.show(ft, tag); + }}); + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/DropDownEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/DropDownEditor.java new file mode 100644 index 0000000..64490fa --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/DropDownEditor.java @@ -0,0 +1,84 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.TextView; + +import com.android.notificationstudio.R; +import com.android.notificationstudio.editor.Editors.Editor; +import com.android.notificationstudio.model.EditableItem; + +public class DropDownEditor implements Editor { + + public Runnable bindEditor(View v, final EditableItem item, final Runnable afterChange) { + final Spinner dropDownEditor = (Spinner) v.findViewById(R.id.drop_down_editor); + dropDownEditor.setVisibility(View.VISIBLE); + Integer[] values = item.getAvailableValuesInteger(); + final float textSize = v.getResources().getDimensionPixelSize(R.dimen.editor_text_size); + final int p = v.getResources().getDimensionPixelSize(R.dimen.editor_drop_down_padding); + final int p2 = p * 2; + final ArrayAdapter<Integer> adapter = + new ArrayAdapter<Integer>(v.getContext(), android.R.layout.simple_spinner_item, values) { + + @Override + public View getDropDownView(int position, View convertView, ViewGroup parent) { + TextView v = (TextView) super.getDropDownView(position, convertView, parent); + v.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + v.setPadding(p2, p2, p2, p2); + v.setText(v.getResources().getString(getItem(position))); + return v; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView v = (TextView) super.getView(position, convertView, parent); + v.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + v.setPadding(p, p, p, p); + v.setText(v.getResources().getString(getItem(position))); + return v; + } + }; + dropDownEditor.setAdapter(adapter); + Runnable updateSelection = new Runnable() { + public void run() { + dropDownEditor.setSelection(adapter.getPosition(item.getValueInt())); + }}; + if (item.hasValue()) + updateSelection.run(); + dropDownEditor.setOnItemSelectedListener(new OnItemSelectedListener(){ + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + Object oldValue = item.getValue(); + Object newValue = adapter.getItem(position); + if (newValue.equals(oldValue)) + return; + item.setValue(newValue); + afterChange.run(); + } + public void onNothingSelected(AdapterView<?> parent) { + // noop + }}); + return updateSelection; + } + +}
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/Editors.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/Editors.java new file mode 100644 index 0000000..b7268f1 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/Editors.java @@ -0,0 +1,100 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.os.Build; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.android.notificationstudio.NotificationStudioActivity; +import com.android.notificationstudio.R; +import com.android.notificationstudio.model.EditableItem; +import com.android.notificationstudio.model.EditableItemConstants; + +import java.util.HashMap; +import java.util.Map; + +public class Editors implements EditableItemConstants { + + public interface Editor { + Runnable bindEditor(View v, EditableItem item, Runnable afterChange); + } + + private static final Map<Integer, Editor> EDITORS = editors(); + private static Runnable sUpdatePreset; + + private static Map<Integer, Editor> editors() { + Map<Integer, Editor> editors = new HashMap<Integer, Editor>(); + editors.put(TYPE_RESOURCE_ID, new IconEditor()); + editors.put(TYPE_TEXT, new TextEditor()); + editors.put(TYPE_INT, new IntEditor()); + if (Build.VERSION.SDK_INT >= 14) // switch 14, progress 14, uses chron 16 + editors.put(TYPE_BOOLEAN, new BooleanEditor()); + editors.put(TYPE_DROP_DOWN, new DropDownEditor()); + editors.put(TYPE_BITMAP, new BitmapEditor()); + if (Build.VERSION.SDK_INT >= 11) // fragments 11, when 11 + editors.put(TYPE_DATETIME, new DateTimeEditor()); + editors.put(TYPE_TEXT_LINES, new LinesEditor()); + return editors; + } + + public static View newEditor(final NotificationStudioActivity activity, + final ViewGroup parent, final EditableItem item) { + final View editorView = activity.getLayoutInflater().inflate(R.layout.editable_item, null); + ((TextView) editorView.findViewById(R.id.caption)).setText(item.getCaption(activity)); + + // bind visibility + editorView.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); + item.setVisibilityListener(new Runnable(){ + public void run() { + editorView.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); + }}); + + // bind type-specific behavior + Editor editor = EDITORS.get(item.getType()); + if (editor == null) + return null; + Runnable updater = editor.bindEditor(editorView, item, new Runnable() { + public void run() { + if (item.equals(EditableItem.PRESET)) { + updateEditors(parent); + } else { + EditableItem.PRESET.setValue(PRESET_CUSTOM); + sUpdatePreset.run(); + } + activity.refreshNotification(); + }}); + + // store the updater as the view tag + editorView.setTag(updater); + if (item.equals(EditableItem.PRESET)) + sUpdatePreset = updater; + + return editorView; + } + + private static void updateEditors(ViewGroup parent) { + for (int i = 0; i < parent.getChildCount(); i++) { + Object childTag = parent.getChildAt(i).getTag(); + if (childTag instanceof Runnable) { + ((Runnable) childTag).run(); + } + } + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/IconEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/IconEditor.java new file mode 100644 index 0000000..71e9005 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/IconEditor.java @@ -0,0 +1,118 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.content.res.Resources; +import android.view.MotionEvent; +import android.view.SoundEffectConstants; +import android.view.View; +import android.view.View.OnTouchListener; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; +import android.widget.LinearLayout; + +import com.android.notificationstudio.R; +import com.android.notificationstudio.editor.Editors.Editor; +import com.android.notificationstudio.model.EditableItem; + +public class IconEditor implements Editor { + + public Runnable bindEditor(View v, final EditableItem item, final Runnable afterChange) { + final LinearLayout iconEditor = (LinearLayout) v.findViewById(R.id.icon_editor_layout); + final HorizontalScrollView scroller = + (HorizontalScrollView) v.findViewById(R.id.icon_editor_scroller); + scroller.setVisibility(View.VISIBLE); + + final Object[] displayValues = getAvailableValuesForDisplay(item); + final Runnable updateSelection = new Runnable() { + public void run() { + for (int i=0;i<iconEditor.getChildCount();i++) { + View imageViewHolder = iconEditor.getChildAt(i); + Object iconResId = imageViewHolder.getTag(); + boolean selected = item.hasValue() && item.getValue().equals(iconResId) || + !item.hasValue() && iconResId == null; + imageViewHolder.setSelected(selected); + if (selected) { + int x = imageViewHolder.getLeft(); + if (x < scroller.getScrollX() || + x > scroller.getScrollX() + scroller.getWidth()) { + scroller.scrollTo(imageViewHolder.getLeft(), 0); + } + } + } + }}; + + int iconSize = getIconSize(v.getResources()); + int outerMargin = v.getResources().getDimensionPixelSize(R.dimen.editor_icon_outer_margin); + int innerMargin = v.getResources().getDimensionPixelSize(R.dimen.editor_icon_inner_margin); + + for (final Object iconResId : displayValues) { + final FrameLayout imageViewHolder = new FrameLayout(v.getContext()); + imageViewHolder.setTag(iconResId); + final ImageView imageView = new ImageView(v.getContext()); + imageView.setScaleType(ScaleType.CENTER); + imageView.setOnTouchListener(new OnTouchListener(){ + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_UP) { + v.playSoundEffect(SoundEffectConstants.CLICK); + item.setValue(iconResId); + updateSelection.run(); + afterChange.run(); + } + return true; + }}); + + imageViewHolder.setBackgroundResource(R.drawable.icon_bg); + if (iconResId != null) + setImage(imageView, iconResId); + + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(iconSize, iconSize); + lp.bottomMargin = lp.topMargin = lp.leftMargin = lp.rightMargin = outerMargin; + imageViewHolder.setLayoutParams(lp); + + FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT); + flp.bottomMargin = flp.topMargin = flp.leftMargin = flp.rightMargin = innerMargin; + imageView.setLayoutParams(flp); + + imageViewHolder.addView(imageView); + iconEditor.addView(imageViewHolder); + } + updateSelection.run(); + return updateSelection; + } + + protected int getIconSize(Resources res) { + return res.getDimensionPixelSize(R.dimen.editor_icon_size_small); + } + + protected void setImage(ImageView imageView, Object value) { + imageView.setImageResource((Integer) value); + } + + private Object[] getAvailableValuesForDisplay(EditableItem item) { + Object[] avail = item.getAvailableValues(); + Object[] rt = new Object[avail.length + 1]; + System.arraycopy(avail, 0, rt, 1, avail.length); + return rt; + } + +}
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/IntEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/IntEditor.java new file mode 100644 index 0000000..393863e --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/IntEditor.java @@ -0,0 +1,32 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.text.InputType; + +public class IntEditor extends TextEditor { + + @Override + protected Object parseValue(String str) { + return str == null ? null : Integer.parseInt(str); + } + + protected int getInputType() { + return InputType.TYPE_CLASS_NUMBER; + } + +}
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/LinesEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/LinesEditor.java new file mode 100644 index 0000000..5173a992 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/LinesEditor.java @@ -0,0 +1,28 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.text.InputType; + +public class LinesEditor extends TextEditor { + + @Override + protected int getInputType() { + return InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE; + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/editor/TextEditor.java b/apps/NotificationStudio/src/com/android/notificationstudio/editor/TextEditor.java new file mode 100644 index 0000000..aa38eec --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/editor/TextEditor.java @@ -0,0 +1,73 @@ +/* + * Copyright 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.android.notificationstudio.editor; + +import android.text.Editable; +import android.text.InputType; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; + +import com.android.notificationstudio.R; +import com.android.notificationstudio.editor.Editors.Editor; +import com.android.notificationstudio.model.EditableItem; + +public class TextEditor implements Editor { + + public Runnable bindEditor(View v, final EditableItem item, final Runnable afterChange) { + final EditText textEditor = (EditText) v.findViewById(R.id.text_editor); + textEditor.setVisibility(View.VISIBLE); + textEditor.setInputType(getInputType()); + Runnable updateEditText = new Runnable() { + public void run() { + textEditor.setText(item.getValue() == null ? "" : item.getValue().toString()); + }}; + if (item.hasValue()) + updateEditText.run(); + textEditor.addTextChangedListener(new TextWatcher() { + public void afterTextChanged(Editable s) { + Object newVal = parseValue(s.length() == 0 ? null : s.toString()); + if (equal(newVal, item.getValue())) + return; + item.setValue(newVal); + afterChange.run(); + } + + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // noop + } + + public void onTextChanged(CharSequence s, int start, int before, int count) { + // noop + } + }); + return updateEditText; + } + + protected int getInputType() { + return InputType.TYPE_CLASS_TEXT; + } + + protected Object parseValue(String str) { + return str; + } + + private static boolean equal(Object a, Object b) { + return a == b || (a != null && a.equals(b)); + } + +}
\ No newline at end of file diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/generator/CodeGenerator.java b/apps/NotificationStudio/src/com/android/notificationstudio/generator/CodeGenerator.java new file mode 100644 index 0000000..81eca83 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/generator/CodeGenerator.java @@ -0,0 +1,139 @@ +/* + * Copyright 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.android.notificationstudio.generator; +import static com.android.notificationstudio.model.EditableItem.ACTION1_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION1_TEXT; +import static com.android.notificationstudio.model.EditableItem.ACTION2_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION2_TEXT; +import static com.android.notificationstudio.model.EditableItem.ACTION3_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION3_TEXT; +import static com.android.notificationstudio.model.EditableItem.BIG_CONTENT_TITLE; +import static com.android.notificationstudio.model.EditableItem.BIG_TEXT; +import static com.android.notificationstudio.model.EditableItem.CONTENT_INFO; +import static com.android.notificationstudio.model.EditableItem.CONTENT_TEXT; +import static com.android.notificationstudio.model.EditableItem.CONTENT_TITLE; +import static com.android.notificationstudio.model.EditableItem.LARGE_ICON; +import static com.android.notificationstudio.model.EditableItem.LINES; +import static com.android.notificationstudio.model.EditableItem.NUMBER; +import static com.android.notificationstudio.model.EditableItem.PICTURE; +import static com.android.notificationstudio.model.EditableItem.PROGRESS; +import static com.android.notificationstudio.model.EditableItem.SMALL_ICON; +import static com.android.notificationstudio.model.EditableItem.STYLE; +import static com.android.notificationstudio.model.EditableItem.SUB_TEXT; +import static com.android.notificationstudio.model.EditableItem.SUMMARY_TEXT; +import static com.android.notificationstudio.model.EditableItem.USES_CHRON; +import static com.android.notificationstudio.model.EditableItem.WHEN; + +import android.content.Context; + +import com.android.notificationstudio.model.EditableItem; +import com.android.notificationstudio.model.EditableItemConstants; + +public class CodeGenerator implements EditableItemConstants { + + private static final String INDENT = "\n "; + private static final String STYLE_INDENT = INDENT + " "; + + public static String generate(Context context) { + + StringBuilder sb = new StringBuilder("new Notification.Builder(context)"); + + if (SMALL_ICON.hasValue()) + sb.append(INDENT + ".setSmallIcon(" + getResourceVar(context, SMALL_ICON) + ")"); + if (CONTENT_TITLE.hasValue()) + sb.append(INDENT + ".setContentTitle(" + quote(CONTENT_TITLE) + ")"); + if (CONTENT_TEXT.hasValue()) + sb.append(INDENT + ".setContentText(" + quote(CONTENT_TEXT) + ")"); + if (SUB_TEXT.hasValue()) + sb.append(INDENT + ".setSubText(" + quote(SUB_TEXT) + ")"); + if (LARGE_ICON.hasValue()) + sb.append(INDENT + ".setLargeIcon(largeIconBitmap)"); + if (CONTENT_INFO.hasValue()) + sb.append(INDENT + ".setContentInfo(" + quote(CONTENT_INFO) + ")"); + if (NUMBER.hasValue()) + sb.append(INDENT + ".setNumber(" + NUMBER.getValueInt() + ")"); + if (WHEN.hasValue()) + sb.append(INDENT + ".setWhen(" + WHEN.getValueLong() + ")"); + if (PROGRESS.hasValue() && PROGRESS.getValueBool()) + sb.append(INDENT + ".setProgress(0, 0, true)"); + if (USES_CHRON.hasValue()) + sb.append(INDENT + ".setUsesChronometer(" + USES_CHRON.getValueBool() + ")"); + if (ACTION1_ICON.hasValue()) + generateAction(sb, ACTION1_ICON, ACTION1_TEXT, "action1PendingIntent"); + if (ACTION2_ICON.hasValue()) + generateAction(sb, ACTION2_ICON, ACTION2_TEXT, "action2PendingIntent"); + if (ACTION3_ICON.hasValue()) + generateAction(sb, ACTION3_ICON, ACTION3_TEXT, "action3PendingIntent"); + + if (STYLE.hasValue()) + generateStyle(sb); + + sb.append(INDENT + ".build();"); + return sb.toString(); + } + + private static void generateStyle(StringBuilder sb) { + Integer styleValue = STYLE.getValueInt(); + if (STYLE_BIG_PICTURE.equals(styleValue)) { + sb.append(INDENT + ".setStyle(new Notification.BigPictureStyle()"); + if (PICTURE.hasValue()) + sb.append(STYLE_INDENT + ".bigPicture(pictureBitmap)"); + } + if (STYLE_BIG_TEXT.equals(styleValue)) { + sb.append(INDENT + ".setStyle(new Notification.BigTextStyle()"); + if (BIG_TEXT.hasValue()) + sb.append(STYLE_INDENT + ".bigText(" + quote(BIG_TEXT) + ")"); + } + if (STYLE_INBOX.equals(styleValue)) { + sb.append(INDENT + ".setStyle(new Notification.InboxStyle()"); + if (LINES.hasValue()) { + for (String line : LINES.getValueString().split("\\n")) { + sb.append(STYLE_INDENT + ".addLine(" + quote(line) + ")"); + } + } + } + if (BIG_CONTENT_TITLE.hasValue()) + sb.append(STYLE_INDENT + ".setBigContentTitle(" + quote(BIG_CONTENT_TITLE) + ")"); + if (SUMMARY_TEXT.hasValue()) + sb.append(STYLE_INDENT + ".setSummaryText(" + quote(SUMMARY_TEXT) + ")"); + + sb.append(")"); + } + + private static void generateAction(StringBuilder sb, + EditableItem icon, EditableItem text, String intentName) { + sb.append(INDENT + + ".addAction(" + icon.getValueInt() + ", " + quote(text) + ", " + intentName + ")"); + } + + private static String quote(EditableItem text) { + return quote(text.getValueString()); + } + + private static String quote(String text) { + return text != null ? "\"" + text.replace("\"", "\\\"") + "\"" : "null"; + } + + private static String getResourceVar(Context context, EditableItem item) { + int resId = item.getValueInt(); + String packageName = context.getResources().getResourcePackageName(resId); + String type = context.getResources().getResourceTypeName(resId); + String entryName = context.getResources().getResourceEntryName(resId); + return packageName + ".R." + type + "." + entryName; + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/generator/NotificationGenerator.java b/apps/NotificationStudio/src/com/android/notificationstudio/generator/NotificationGenerator.java new file mode 100644 index 0000000..64b4ece --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/generator/NotificationGenerator.java @@ -0,0 +1,131 @@ +/* + * Copyright 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.android.notificationstudio.generator; +import static com.android.notificationstudio.model.EditableItem.ACTION1_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION1_TEXT; +import static com.android.notificationstudio.model.EditableItem.ACTION2_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION2_TEXT; +import static com.android.notificationstudio.model.EditableItem.ACTION3_ICON; +import static com.android.notificationstudio.model.EditableItem.ACTION3_TEXT; +import static com.android.notificationstudio.model.EditableItem.BIG_CONTENT_TITLE; +import static com.android.notificationstudio.model.EditableItem.BIG_TEXT; +import static com.android.notificationstudio.model.EditableItem.CONTENT_INFO; +import static com.android.notificationstudio.model.EditableItem.CONTENT_TEXT; +import static com.android.notificationstudio.model.EditableItem.CONTENT_TITLE; +import static com.android.notificationstudio.model.EditableItem.LARGE_ICON; +import static com.android.notificationstudio.model.EditableItem.LINES; +import static com.android.notificationstudio.model.EditableItem.NUMBER; +import static com.android.notificationstudio.model.EditableItem.PICTURE; +import static com.android.notificationstudio.model.EditableItem.PROGRESS; +import static com.android.notificationstudio.model.EditableItem.SMALL_ICON; +import static com.android.notificationstudio.model.EditableItem.STYLE; +import static com.android.notificationstudio.model.EditableItem.SUB_TEXT; +import static com.android.notificationstudio.model.EditableItem.SUMMARY_TEXT; +import static com.android.notificationstudio.model.EditableItem.USES_CHRON; +import static com.android.notificationstudio.model.EditableItem.WHEN; + +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationCompat.BigPictureStyle; +import android.support.v4.app.NotificationCompat.BigTextStyle; +import android.support.v4.app.NotificationCompat.InboxStyle; + +import com.android.notificationstudio.model.EditableItemConstants; + +public class NotificationGenerator implements EditableItemConstants { + + public static Notification build(Context context) { + + PendingIntent noop = PendingIntent.getActivity(context, 0, new Intent(), 0); + + NotificationCompat.Builder builder = new NotificationCompat.Builder(context); + if (SMALL_ICON.hasValue()) + builder.setSmallIcon(SMALL_ICON.getValueInt()); + if (CONTENT_TITLE.hasValue()) + builder.setContentTitle(CONTENT_TITLE.getValueString()); + if (CONTENT_TEXT.hasValue()) + builder.setContentText(CONTENT_TEXT.getValueString()); + if (SUB_TEXT.hasValue()) + builder.setSubText(SUB_TEXT.getValueString()); + if (LARGE_ICON.hasValue()) + builder.setLargeIcon(LARGE_ICON.getValueBitmap()); + if (CONTENT_INFO.hasValue()) + builder.setContentInfo(CONTENT_INFO.getValueString()); + if (NUMBER.hasValue()) + builder.setNumber(NUMBER.getValueInt()); + if (WHEN.hasValue()) + builder.setWhen(WHEN.getValueLong()); + if (PROGRESS.hasValue() && PROGRESS.getValueBool()) + builder.setProgress(0, 0, true); + if (USES_CHRON.hasValue()) + builder.setUsesChronometer(USES_CHRON.getValueBool()); + if (ACTION1_ICON.hasValue()) + builder.addAction(ACTION1_ICON.getValueInt(), ACTION1_TEXT.getValueString(), noop); + if (ACTION2_ICON.hasValue()) + builder.addAction(ACTION2_ICON.getValueInt(), ACTION2_TEXT.getValueString(), noop); + if (ACTION3_ICON.hasValue()) + builder.addAction(ACTION3_ICON.getValueInt(), ACTION3_TEXT.getValueString(), noop); + + if (STYLE.hasValue()) + generateStyle(builder); + + // for older OSes + builder.setContentIntent(noop); + + return builder.build(); + } + + private static void generateStyle(NotificationCompat.Builder builder) { + Integer styleValue = STYLE.getValueInt(); + + if (STYLE_BIG_PICTURE.equals(styleValue)) { + BigPictureStyle bigPicture = new NotificationCompat.BigPictureStyle(); + if (PICTURE.hasValue()) + bigPicture.bigPicture(PICTURE.getValueBitmap()); + if (BIG_CONTENT_TITLE.hasValue()) + bigPicture.setBigContentTitle(BIG_CONTENT_TITLE.getValueString()); + if (SUMMARY_TEXT.hasValue()) + bigPicture.setSummaryText(SUMMARY_TEXT.getValueString()); + builder.setStyle(bigPicture); + } else if (STYLE_BIG_TEXT.equals(styleValue)) { + BigTextStyle bigText = new NotificationCompat.BigTextStyle(); + if (BIG_TEXT.hasValue()) + bigText.bigText(BIG_TEXT.getValueString()); + if (BIG_CONTENT_TITLE.hasValue()) + bigText.setBigContentTitle(BIG_CONTENT_TITLE.getValueString()); + if (SUMMARY_TEXT.hasValue()) + bigText.setSummaryText(SUMMARY_TEXT.getValueString()); + builder.setStyle(bigText); + } else if (STYLE_INBOX.equals(styleValue)) { + InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); + if (LINES.hasValue()) { + for (String line : LINES.getValueString().split("\\n")) { + inboxStyle.addLine(line); + } + } + if (BIG_CONTENT_TITLE.hasValue()) + inboxStyle.setBigContentTitle(BIG_CONTENT_TITLE.getValueString()); + if (SUMMARY_TEXT.hasValue()) + inboxStyle.setSummaryText(SUMMARY_TEXT.getValueString()); + builder.setStyle(inboxStyle); + } + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItem.java b/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItem.java new file mode 100644 index 0000000..54e03e0 --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItem.java @@ -0,0 +1,216 @@ +/* + * Copyright 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.android.notificationstudio.model; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import com.android.notificationstudio.R; + +public enum EditableItem implements EditableItemConstants { + + PRESET(R.string.preset, TYPE_DROP_DOWN, CATEGORY_MAIN, + PRESET_BASIC, PRESET_EMAIL, PRESET_PHOTO, PRESET_CUSTOM), + SMALL_ICON(R.string.small_icon, TYPE_RESOURCE_ID, CATEGORY_MAIN, + SMALL_ICONS), + CONTENT_TITLE(R.string.content_title, TYPE_TEXT, CATEGORY_MAIN), + CONTENT_TEXT(R.string.content_text, TYPE_TEXT, CATEGORY_MAIN), + SUB_TEXT(R.string.sub_text, TYPE_TEXT, CATEGORY_MAIN), + LARGE_ICON(R.string.large_icon, TYPE_BITMAP, CATEGORY_MAIN), + CONTENT_INFO(R.string.content_info, TYPE_TEXT, CATEGORY_MAIN), + NUMBER(R.string.number, TYPE_INT, CATEGORY_MAIN), + WHEN(R.string.when, TYPE_DATETIME, CATEGORY_MAIN), + PROGRESS(R.string.progress, TYPE_BOOLEAN, CATEGORY_MAIN), + USES_CHRON(R.string.uses_chron, TYPE_BOOLEAN, CATEGORY_MAIN), + STYLE(R.string.style, TYPE_DROP_DOWN, CATEGORY_STYLE, + STYLE_NONE, STYLE_BIG_PICTURE, STYLE_BIG_TEXT, STYLE_INBOX), + PICTURE(R.string.picture, TYPE_BITMAP, CATEGORY_STYLE), + BIG_TEXT(R.string.big_text, TYPE_TEXT, CATEGORY_STYLE), + LINES(R.string.lines, TYPE_TEXT_LINES, CATEGORY_STYLE), + BIG_CONTENT_TITLE(R.string.big_content_title, TYPE_TEXT, CATEGORY_STYLE), + SUMMARY_TEXT(R.string.summary_text, TYPE_TEXT, CATEGORY_STYLE), + ACTION1_ICON(R.string.icon, TYPE_RESOURCE_ID, CATEGORY_ACTION1, + ACTION_ICONS), + ACTION1_TEXT(R.string.text, TYPE_TEXT, CATEGORY_ACTION1), + ACTION2_ICON(R.string.icon, TYPE_RESOURCE_ID, CATEGORY_ACTION2, + ACTION_ICONS), + ACTION2_TEXT(R.string.text, TYPE_TEXT, CATEGORY_ACTION2), + ACTION3_ICON(R.string.icon, TYPE_RESOURCE_ID, CATEGORY_ACTION3, + ACTION_ICONS), + ACTION3_TEXT(R.string.text, TYPE_TEXT, CATEGORY_ACTION3), + ; + + private final int mCaptionId; + private final int mType; + private final int mCategoryId; + + private Object[] mAvailableValues; + private Object mValue; + private boolean mVisible = true; + private Runnable mVisibilityListener; + + private EditableItem(int captionId, int type, int categoryId, Object... availableValues) { + mCaptionId = captionId; + mType = type; + mCategoryId = categoryId; + mAvailableValues = availableValues; + } + + // init + public static void initIfNecessary(Context context) { + if (PRESET.hasValue()) + return; + loadBitmaps(context, LARGE_ICON, LARGE_ICONS); + loadBitmaps(context, PICTURE, PICTURES); + PRESET.setValue(PRESET_BASIC); + } + + private static void loadBitmaps(Context context, EditableItem item, int[] bitmapResIds) { + Object[] largeIconBitmaps = new Object[bitmapResIds.length]; + Resources res = context.getResources(); + for (int i = 0; i < bitmapResIds.length; i++) + largeIconBitmaps[i] = BitmapFactory.decodeResource(res, bitmapResIds[i]); + item.setAvailableValues(largeIconBitmaps); + } + + // visibility + public boolean isVisible() { + return mVisible; + } + + public void setVisible(boolean visible) { + if (mVisible == visible) + return; + mVisible = visible; + if (mVisibilityListener != null) + mVisibilityListener.run(); + } + + public void setVisibilityListener(Runnable listener) { + mVisibilityListener = listener; + } + + // value + + public boolean hasValue() { + return mValue != null; + } + + public void setValue(Object value) { + if (mValue == value) + return; + mValue = value; + if (this == STYLE) + applyStyle(); + if (this == PRESET && !PRESET_CUSTOM.equals(value)) + applyPreset(); + } + + private void applyStyle() { + PICTURE.setVisible(STYLE_BIG_PICTURE.equals(mValue)); + BIG_TEXT.setVisible(STYLE_BIG_TEXT.equals(mValue)); + LINES.setVisible(STYLE_INBOX.equals(mValue)); + BIG_CONTENT_TITLE.setVisible(!STYLE_NONE.equals(mValue)); + SUMMARY_TEXT.setVisible(!STYLE_NONE.equals(mValue)); + } + + private void applyPreset() { + for (EditableItem item : values()) + if (item != PRESET) + item.setValue(null); + STYLE.setValue(STYLE_NONE); + if (PRESET_BASIC.equals(mValue)) { + SMALL_ICON.setValue(android.R.drawable.stat_notify_chat); + CONTENT_TITLE.setValue("Basic title"); + CONTENT_TEXT.setValue("Basic text"); + } else if (PRESET_EMAIL.equals(mValue)) { + SMALL_ICON.setValue(R.drawable.ic_notification_multiple_mail_holo_dark); + LARGE_ICON.setValue(LARGE_ICON.getAvailableValues()[3]); + CONTENT_TITLE.setValue("3 new messages"); + CONTENT_TEXT.setValue("Alice, Bob, Chuck"); + STYLE.setValue(STYLE_INBOX); + LINES.setValue("Alice: Re: Something\n" + + "Bob: Did you get the memo?\n" + + "Chuck: Limited time offer!"); + } else if (PRESET_PHOTO.equals(mValue)) { + SMALL_ICON.setValue(android.R.drawable.ic_menu_camera); + LARGE_ICON.setValue(LARGE_ICON.getAvailableValues()[2]); + CONTENT_TITLE.setValue("Sunset on the rocks"); + CONTENT_TEXT.setValue("800x534 | 405.1K"); + SUMMARY_TEXT.setValue(CONTENT_TEXT.getValueString()); + STYLE.setValue(STYLE_BIG_PICTURE); + PICTURE.setValue(PICTURE.getAvailableValues()[0]); + ACTION1_ICON.setValue(android.R.drawable.ic_menu_share); + ACTION1_TEXT.setValue("Share"); + } + } + + public Object getValue() { + return mValue; + } + + public String getValueString() { + return (String) mValue; + } + + public int getValueInt() { + return (Integer) mValue; + } + + public long getValueLong() { + return (Long) mValue; + } + + public boolean getValueBool() { + return (Boolean) mValue; + } + + public Bitmap getValueBitmap() { + return (Bitmap) mValue; + } + + // available values + + public Object[] getAvailableValues() { + return mAvailableValues; + } + + public Integer[] getAvailableValuesInteger() { + Integer[] integers = new Integer[mAvailableValues.length]; + System.arraycopy(mAvailableValues, 0, integers, 0, integers.length); + return integers; + } + + public <T> void setAvailableValues(T... values) { + mAvailableValues = values; + } + + public String getCaption(Context context) { + return context.getString(mCaptionId); + } + + public String getCategory(Context context) { + return context.getString(mCategoryId); + } + + public int getType() { + return mType; + } + +} diff --git a/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItemConstants.java b/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItemConstants.java new file mode 100644 index 0000000..d4defdf --- /dev/null +++ b/apps/NotificationStudio/src/com/android/notificationstudio/model/EditableItemConstants.java @@ -0,0 +1,74 @@ +/* + * Copyright 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.android.notificationstudio.model; + +import com.android.notificationstudio.R; + +public interface EditableItemConstants { + + public static final int TYPE_TEXT = 0; + public static final int TYPE_DROP_DOWN = 1; + public static final int TYPE_RESOURCE_ID = 2; + public static final int TYPE_BITMAP = 3; + public static final int TYPE_INT = 4; + public static final int TYPE_DATETIME = 5; + public static final int TYPE_BOOLEAN = 6; + public static final int TYPE_TEXT_LINES = 7; + + public static final int CATEGORY_MAIN = R.string.properties; + public static final int CATEGORY_STYLE = R.string.style; + public static final int CATEGORY_ACTION1 = R.string.action_1; + public static final int CATEGORY_ACTION2 = R.string.action_2; + public static final int CATEGORY_ACTION3 = R.string.action_3; + + public static final Integer PRESET_CUSTOM = R.string.preset_custom; + public static final Integer PRESET_BASIC = R.string.preset_basic; + public static final Integer PRESET_EMAIL = R.string.preset_email; + public static final Integer PRESET_PHOTO = R.string.preset_photo; + + public static final Integer STYLE_NONE = R.string.style_none; + public static final Integer STYLE_BIG_PICTURE = R.string.style_big_picture; + public static final Integer STYLE_BIG_TEXT = R.string.style_big_text; + public static final Integer STYLE_INBOX = R.string.style_inbox; + + public static final Object[] SMALL_ICONS = new Object[] { + android.R.drawable.stat_sys_warning, + android.R.drawable.stat_sys_download_done, + android.R.drawable.stat_notify_chat, + android.R.drawable.stat_notify_sync, + android.R.drawable.stat_notify_more, + android.R.drawable.stat_notify_sdcard, + android.R.drawable.stat_sys_data_bluetooth, + android.R.drawable.stat_notify_voicemail, + android.R.drawable.stat_sys_speakerphone, + android.R.drawable.ic_menu_camera, + android.R.drawable.ic_menu_share, + R.drawable.ic_notification_multiple_mail_holo_dark + }; + + public static final Object[] ACTION_ICONS = SMALL_ICONS; + + public static final int[] LARGE_ICONS = new int[]{ + R.drawable.romainguy_rockaway, + R.drawable.android_logo, + R.drawable.romain, + R.drawable.ic_notification_multiple_mail_holo_dark + }; + + public static final int[] PICTURES = LARGE_ICONS; + +} |