am 83d785eb: (-s ours) am 7cbd511d: am 866f576b: (-s ours) Import revised translations. DO NOT MERGE
* commit '83d785eb53d3648f82c6f299639740d0b6d16be5':
Import revised translations. DO NOT MERGE
diff --git a/Android.mk b/Android.mk
index ff1b7e2..1c9dcc4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -5,7 +5,11 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := com.android.phone.common com.android.vcard android-common
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ com.android.phone.common \
+ com.android.vcard \
+ android-common \
+ guava
LOCAL_PACKAGE_NAME := Contacts
LOCAL_CERTIFICATE := shared
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 52562e0..458553e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -185,16 +185,6 @@
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
-
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.dir/person" />
- <data android:mimeType="vnd.android.cursor.dir/contact" />
- <data android:mimeType="vnd.android.cursor.item/person" />
- <data android:mimeType="vnd.android.cursor.item/contact" />
- <data android:mimeType="vnd.android.cursor.item/raw_contact" />
- </intent-filter>
</activity>
<!-- The actual list of contacts -->
@@ -291,6 +281,7 @@
<data android:mimeType="vnd.android.cursor.dir/phone" />
<data android:mimeType="vnd.android.cursor.dir/postal-address_v2" />
<data android:mimeType="vnd.android.cursor.dir/postal-address" />
+ <data android:mimeType="vnd.android.cursor.dir/email_v2" />
</intent-filter>
<intent-filter>
@@ -335,7 +326,7 @@
<activity
android:name=".activities.ShowOrCreateActivity"
- android:theme="@style/FullyTranslucent">
+ android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="com.android.contacts.action.SHOW_OR_CREATE_CONTACT" />
@@ -348,13 +339,12 @@
<!-- Used to show QuickContact window over a translucent activity, which is a
temporary hack until we add better framework support. -->
<activity
- android:name=".quickcontact.QuickContactActivity"
- android:theme="@style/FullyTranslucent.QuickContact"
+ android:name=".quickcontact.QuickContactWindow"
+ android:theme="@style/Theme.QuickContact"
android:launchMode="singleTop"
android:excludeFromRecents="true"
android:taskAffinity="android.task.quickcontact"
- android:windowSoftInputMode="stateUnchanged"
- >
+ android:windowSoftInputMode="stateUnchanged">
<intent-filter>
<action android:name="com.android.contacts.action.QUICK_CONTACT" />
@@ -442,6 +432,11 @@
<intent-filter android:label="@string/viewContactDesription">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.dir/person" />
+ <data android:mimeType="vnd.android.cursor.dir/contact" />
+ <data android:mimeType="vnd.android.cursor.item/person" />
+ <data android:mimeType="vnd.android.cursor.item/contact" />
+ <data android:mimeType="vnd.android.cursor.item/raw_contact" />
</intent-filter>
</activity>
@@ -550,7 +545,7 @@
<!-- vCard related -->
<activity android:name=".vcard.ImportVCardActivity"
- android:configChanges="orientation"
+ android:configChanges="orientation|screenSize|keyboardHidden"
android:theme="@style/BackgroundOnly">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
diff --git a/res/drawable-xlarge-hdpi/panel_message.9.png b/res/drawable-hdpi/panel_message.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/panel_message.9.png
rename to res/drawable-hdpi/panel_message.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/panel_message.9.png b/res/drawable-mdpi/panel_message.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/panel_message.9.png
rename to res/drawable-mdpi/panel_message.9.png
Binary files differ
diff --git a/res/drawable/quickactions_arrow_left_holo_light.xml b/res/drawable/quickactions_arrow_left_holo_light.xml
new file mode 100644
index 0000000..c1e18bd
--- /dev/null
+++ b/res/drawable/quickactions_arrow_left_holo_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_first="true" android:drawable="@drawable/quickactions_arrowdown_left_holo_light" />
+ <item android:state_last="true" android:drawable="@drawable/quickactions_arrowup_left_holo_light" />
+ <!-- TODO: provide callout-less state -->
+ <item android:drawable="@drawable/quickactions_arrowup_left_holo_light" />
+</selector>
diff --git a/res/drawable/quickactions_arrow_middle_holo_light.xml b/res/drawable/quickactions_arrow_middle_holo_light.xml
new file mode 100644
index 0000000..f88b513
--- /dev/null
+++ b/res/drawable/quickactions_arrow_middle_holo_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_first="true" android:drawable="@drawable/quickactions_arrowdown_middle_holo_light" />
+ <item android:state_last="true" android:drawable="@drawable/quickactions_arrowup_middle_holo_light" />
+ <!-- TODO: provide callout-less state -->
+ <item android:drawable="@drawable/quickactions_arrowup_middle_holo_light" />
+</selector>
diff --git a/res/drawable/quickactions_arrow_right_holo_light.xml b/res/drawable/quickactions_arrow_right_holo_light.xml
new file mode 100644
index 0000000..3e309fe
--- /dev/null
+++ b/res/drawable/quickactions_arrow_right_holo_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_first="true" android:drawable="@drawable/quickactions_arrowdown_right_holo_light" />
+ <item android:state_last="true" android:drawable="@drawable/quickactions_arrowup_right_holo_light" />
+ <!-- TODO: provide callout-less state -->
+ <item android:drawable="@drawable/quickactions_arrowup_right_holo_light" />
+</selector>
diff --git a/res/layout-long/twelve_key_dialer.xml b/res/layout-long/twelve_key_dialer.xml
index bd90df4..2580625 100644
--- a/res/layout-long/twelve_key_dialer.xml
+++ b/res/layout-long/twelve_key_dialer.xml
@@ -14,11 +14,14 @@
limitations under the License.
-->
+<!-- TODO (stopship) We don't want to specify a background color here. For now we just
+keep it because otherwise the dialer needs some imagination to use (white on white) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
+ android:background="@android:color/black"
>
<!-- Text field above the keypad where the digits are displayed.
diff --git a/res/layout-xlarge/aggregation_suggestions_item.xml b/res/layout-xlarge/aggregation_suggestions_item.xml
index f12c608..5ea8347 100644
--- a/res/layout-xlarge/aggregation_suggestions_item.xml
+++ b/res/layout-xlarge/aggregation_suggestions_item.xml
@@ -24,6 +24,8 @@
android:orientation="horizontal"
android:paddingLeft="5dip"
android:paddingRight="15dip"
+ android:background="?android:attr/selectableItemBackground"
+ android:focusable="true"
>
<ImageView
android:id="@+id/aggregation_suggestion_photo"
diff --git a/res/layout-xlarge/list_section.xml b/res/layout-xlarge/list_section.xml
deleted file mode 100644
index c684a0f..0000000
--- a/res/layout-xlarge/list_section.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Layout used for list section separators. -->
-<RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="37dip"
- android:background="@drawable/section_header_holo"
- >
- <TextView
- android:id="@+id/header_text"
- android:layout_width="56dip"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_alignParentLeft="true"
- android:textStyle="bold"
- android:textColor="@color/section_header_text_color"
- android:textSize="14sp"
- android:gravity="center"
- />
-</RelativeLayout>
diff --git a/res/layout/aggregation_suggestions_item.xml b/res/layout/aggregation_suggestions_item.xml
index f2477cb..9ed1bf3 100644
--- a/res/layout/aggregation_suggestions_item.xml
+++ b/res/layout/aggregation_suggestions_item.xml
@@ -24,6 +24,8 @@
android:orientation="horizontal"
android:paddingLeft="5dip"
android:paddingRight="15dip"
+ android:background="?android:attr/selectableItemBackground"
+ android:focusable="true"
>
<ImageView
diff --git a/res/layout/contact_browser.xml b/res/layout/contact_browser.xml
index 0b4bb63..8affd46 100644
--- a/res/layout/contact_browser.xml
+++ b/res/layout/contact_browser.xml
@@ -18,4 +18,25 @@
android:id="@+id/list_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/main_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment
+ android:id="@+id/list_fragment"
+ class="com.android.contacts.list.DefaultContactBrowseListFragment"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ />
+ </FrameLayout>
+ <FrameLayout
+ android:id="@+id/contacts_unavailable_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone">
+ <FrameLayout
+ android:id="@+id/contacts_unavailable_container"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent" />
+ </FrameLayout>
</FrameLayout>
diff --git a/res/layout/contact_editor_activity.xml b/res/layout/contact_editor_activity.xml
index 630e82c..8c13629 100644
--- a/res/layout/contact_editor_activity.xml
+++ b/res/layout/contact_editor_activity.xml
@@ -22,21 +22,4 @@
android:id="@+id/contact_editor_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="50dip"
- android:orientation="horizontal"
- android:gravity="center_horizontal">
-
- <Button
- android:id="@+id/done"
- android:layout_width="150dip"
- android:layout_height="match_parent"
- android:text="@string/menu_done" />
- <Button
- android:id="@+id/revert"
- android:layout_width="150dip"
- android:layout_height="match_parent"
- android:text="@string/menu_doNotSave" />
- </LinearLayout>
</FrameLayout>
diff --git a/res/layout/item_kind_section.xml b/res/layout/item_kind_section.xml
index fdb55c9..c0e42a0 100644
--- a/res/layout/item_kind_section.xml
+++ b/res/layout/item_kind_section.xml
@@ -53,18 +53,23 @@
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
- <ImageButton
- android:id="@+id/kind_plus"
+ <FrameLayout
+ android:id="@+id/kind_plus_container"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:duplicateParentState="true"
- android:background="?android:attr/selectableItemBackground"
- android:src="@drawable/ic_menu_add_field_holo_light"
- android:paddingLeft="@dimen/editor_round_button_padding_left"
- android:paddingRight="@dimen/editor_round_button_padding_right"
- android:paddingTop="@dimen/editor_round_button_padding_top"
- android:paddingBottom="@dimen/editor_round_button_padding_bottom"
- android:contentDescription="@string/description_plus_button" />
+ android:layout_height="@dimen/editor_min_line_item_height">
+ <ImageButton
+ android:id="@+id/kind_plus"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:duplicateParentState="true"
+ android:background="?android:attr/selectableItemBackground"
+ android:src="@drawable/ic_menu_add_field_holo_light"
+ android:paddingLeft="@dimen/editor_round_button_padding_left"
+ android:paddingRight="@dimen/editor_round_button_padding_right"
+ android:paddingTop="@dimen/editor_round_button_padding_top"
+ android:paddingBottom="@dimen/editor_round_button_padding_bottom"
+ android:contentDescription="@string/description_plus_button" />
+ </FrameLayout>
</LinearLayout>
diff --git a/res/layout/list_section.xml b/res/layout/list_section.xml
index e920673..5265f88 100644
--- a/res/layout/list_section.xml
+++ b/res/layout/list_section.xml
@@ -18,8 +18,7 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="25dip"
- android:background="@drawable/section_header"
+ android:layout_height="@dimen/list_section_height"
>
<TextView
android:id="@+id/header_text"
diff --git a/res/layout/quickcontact.xml b/res/layout/quickcontact.xml
index a74424c..e2b291c 100644
--- a/res/layout/quickcontact.xml
+++ b/res/layout/quickcontact.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,13 +13,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-<view
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- class="com.android.contacts.quickcontact.QuickContactRootLayout"
- android:id="@+id/root"
- android:layout_width="match_parent"
+ android:id="@android:id/content"
+ android:layout_width="@dimen/quick_contact_width"
android:layout_height="wrap_content"
+ android:visibility="invisible"
android:orientation="vertical">
<FrameLayout
@@ -133,4 +133,4 @@
android:text="@string/quickcontact_clear_defaults_button" />
</LinearLayout>
</FrameLayout>
-</view>
+</LinearLayout>
diff --git a/res/layout/quickcontact_activity.xml b/res/layout/quickcontact_activity.xml
new file mode 100644
index 0000000..aced4a8
--- /dev/null
+++ b/res/layout/quickcontact_activity.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<view
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ class="com.android.contacts.quickcontact.FloatingChildLayout"
+ android:id="@+id/floating_layout"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:descendantFocusability="afterDescendants">
+
+ <include layout="@layout/quickcontact" />
+
+</view>
diff --git a/res/layout/quickcontact_default_item.xml b/res/layout/quickcontact_default_item.xml
index 25b6910..3a918f0 100755
--- a/res/layout/quickcontact_default_item.xml
+++ b/res/layout/quickcontact_default_item.xml
@@ -28,13 +28,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
- android:textAppearance="?android:attr/textAppearanceMediumInverse" />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-4dip"
- android:textAppearance="?android:attr/textAppearanceSmallInverse" />
+ android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
diff --git a/res/layout/quickcontact_resolve_item.xml b/res/layout/quickcontact_resolve_item.xml
index 55de80e..2805722 100755
--- a/res/layout/quickcontact_resolve_item.xml
+++ b/res/layout/quickcontact_resolve_item.xml
@@ -28,13 +28,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
- android:textAppearance="?android:attr/textAppearanceMediumInverse" />
+ android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@android:id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="-4dip"
- android:textAppearance="?android:attr/textAppearanceSmallInverse" />
+ android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
diff --git a/res/layout/twelve_key_dialer.xml b/res/layout/twelve_key_dialer.xml
index d4c9d8f..2cae9ae 100644
--- a/res/layout/twelve_key_dialer.xml
+++ b/res/layout/twelve_key_dialer.xml
@@ -14,11 +14,14 @@
limitations under the License.
-->
+<!-- TODO (stopship) We don't want to specify a background color here. For now we just
+keep it because otherwise the dialer needs some imagination to use (white on white) -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
+ android:background="@android:color/black"
>
<!-- Text field above the keypad where the digits are displayed.
diff --git a/res/menu/list.xml b/res/menu/list.xml
index 2b3f453..56d92f8 100644
--- a/res/menu/list.xml
+++ b/res/menu/list.xml
@@ -27,9 +27,9 @@
android:alphabeticShortcut="n" />
<item
- android:id="@+id/menu_display_groups"
- android:icon="@*android:drawable/ic_menu_allfriends"
- android:title="@string/menu_displayGroup" />
+ android:id="@+id/menu_settings"
+ android:icon="@drawable/ic_menu_settings_holo_light"
+ android:title="@string/menu_settings" />
<item
android:id="@+id/menu_accounts"
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index dcca0f1..c0e2581 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"سجل المكالمات فارغ."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"محو سجل المكالمات"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"هل أنت متأكد من أنك تريد محو سجل المكالمات؟"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"جارٍ محو سجل المكالمات"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"البريد الصوتي"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 6f62119..9061389 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Списъкът на обажданията е празен."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Изчистване на списъка с обажданията"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Наистина ли искате да изчистите списъка на обажданията?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Списъкът с обажданията се изчиства"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Гласова поща"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 31de36e..685f2a1 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"El registre de trucades és buit."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Esborrament del registre de trucades"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Esteu segur que voleu esborrar el registre de trucades?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Esborrant el registre de trucada"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Correu de veu"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index b4ec252..c353045 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Záznam hovorů je prázdný."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Vymazat hovory"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Opravdu chcete vymazat hovory?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Vymazání hovorů"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Hlasová schránka"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 92d2477..18a1214 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Opkaldslisten er tom."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Ryd opkaldsliste"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Er du sikker på, at du vil rydde opkaldslisten?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Rydder opkaldsliste"</string>
<string name="imei" msgid="3045126336951684285">"IMEI-nummer"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 1f8cec6..54c6490 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Anrufliste ist leer"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Anrufprotokoll löschen"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Möchten Sie das Anrufprotokoll wirklich löschen?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Anrufprotokoll wird gelöscht."</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Mailbox"</string>
@@ -231,7 +232,7 @@
<string name="fail_reason_io_error" msgid="5922864781066136340">"E/A-Fehler"</string>
<string name="fail_reason_low_memory_during_import" msgid="7514918659342886381">"Zu wenig Speicherplatz (Datei ist eventuell zu groß)"</string>
<string name="fail_reason_vcard_parse_error" msgid="1201233722762680214">"Die vCard konnte aus einem unbekannten Grund nicht geparst werden."</string>
- <string name="fail_reason_not_supported" msgid="294499264620201243">"Das Format wird nicht unterstützt."</string>
+ <string name="fail_reason_not_supported" msgid="294499264620201243">"Format wird nicht unterstützt."</string>
<string name="vcard_import_failed" msgid="7718330063493653085">"vCard kann nicht importiert werden."</string>
<string name="import_failure_no_vcard_file" product="nosdcard" msgid="6339234836196984924">"Im Speicher wurde keine vCard-Datei gefunden."</string>
<string name="import_failure_no_vcard_file" product="default" msgid="1730986357514922756">"Auf der SD-Karte wurde keine vCard-Datei gefunden."</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index ce14e4d..9ca7e41 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Το αρχείο καταγραφής κλήσεων είναι κενό."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Εκκαθάριση αρχείου καταγραφής κλήσεων"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Είστε βέβαιοι ότι θέλετε να γίνει εκκαθάριση του αρχείου καταγραφής κλήσεων;"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Εκκαθάριση αρχείου καταγρ. κλήσεων"</string>
<string name="imei" msgid="3045126336951684285">"Αριθμός ΙΜΕΙ"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Αυτόματος τηλεφωνητής"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 551be6d..5004706 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Call log is empty."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Clear call log"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Are you sure that you want to clear the call log?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Clearing call log"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 1dfa06c..9938ce4 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"El registro de llamadas está vacío."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Borrar registro de llamadas"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"¿Estás seguro de que deseas borrar el registro de llamadas?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Borrando el registro de llamadas"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Correo de voz"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index c9dcac8..49e12d8 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"El registro de llamadas está vacío."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Borrar registro de llamadas"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"¿Estás seguro de que quieres borrar el registro de llamadas?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Borrando registro de llamadas"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Buzón de voz"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 627d3eb..ee2a356 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"گزارش تماس خالی است."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"پاک کردن گزارش تماس"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"آیا مطمئن هستید که می خواهید گزارش تماس را پاک کنید؟"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"پاک کردن گزارش تماس"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"پست صوتی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 6a9586c..1d8fb8d 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Puheluloki on tyhjä."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Tyhjennä puheluloki"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Haluatko varmasti tyhjentää puhelulokin?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Tyhjennetään puhelulokia"</string>
<string name="imei" msgid="3045126336951684285">"IMEI-koodi"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Vastaaja"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 707119a..2473b4c 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Aucun appel."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Effacer le journal d\'appels"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Voulez-vous vraiment effacer le journal d\'appels ?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Suppression du journal d\'appels"</string>
<string name="imei" msgid="3045126336951684285">"Code IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Messagerie vocale"</string>
@@ -161,12 +162,12 @@
<string name="simContacts_title" msgid="27341688347689769">"Contacts de carte SIM"</string>
<string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Vous n\'avez aucun contact à afficher. Si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes."</string>
<string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Vous n\'avez aucun contact à afficher."</string>
- <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:560 in java.io.StringReader@2666e815) -->
- <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:567 in java.io.StringReader@2e0ece65) -->
+ <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:560 in java.io.StringReader@658fb1f7) -->
+ <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:567 in java.io.StringReader@3ced0338) -->
<string name="noContactsHelpTextWithSync" product="tablet" msgid="2364665535969139880">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", puis sur :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts vers la tablette ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier les paramètres de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SIM ou SD."\n</li></string>
<string name="noContactsHelpTextWithSync" product="default" msgid="3017521127042216243">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" et sélectionnez :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts sur le téléphone ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier le paramètre de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SIM ou SD."\n</li></string>
- <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:565 in java.io.StringReader@4e106082) -->
- <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:571 in java.io.StringReader@15301ed8) -->
+ <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:565 in java.io.StringReader@6c6e70c7) -->
+ <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /b read: font (position:END_TAG </font>@1:571 in java.io.StringReader@46ae506e) -->
<string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="6222739731808897565">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>", puis sur :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts vers la tablette ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier les paramètres de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SD."\n</li></string>
<string name="noContactsNoSimHelpTextWithSync" product="default" msgid="9040060730467973050">"Vous n\'avez aucun contact à afficher (si vous venez d\'ajouter un compte, la synchronisation des contacts peut prendre quelques minutes)."\n\n"Pour ajouter des contacts, appuyez sur "<font fgcolor="#ffffffff"><b>"Menu"</b></font>" et sélectionnez :"\n" "\n<li><font fgcolor="#ffffffff"><b>"Comptes"</b></font>" pour ajouter ou configurer un compte dont vous pourrez synchroniser les contacts sur le téléphone ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Options d\'affichage"</b></font>" pour modifier le paramètre de visibilité des contacts ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Nouveau contact"</b></font>" pour créer un contact ;"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Exporter"</b></font>" pour importer des contacts depuis votre carte SD."\n</li></string>
<string name="noFavoritesHelpText" msgid="3744655776704833277">"Vous ne disposez d\'aucun favoris."\n\n"Pour ajouter un contact à la liste de favoris :"\n\n" "<li>"Appuyez sur l\'onglet "<b>"Contacts"</b>"."\n</li>" "\n<li>"Appuyez sur le contact à ajouter à vos favoris."\n</li>" "\n<li>"Appuyez sur l\'étoile en regard du nom du contact."\n</li></string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 3f06446..7c24f3a 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Zapisnik poziva je prazan"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Izbriši zapisnik poziva"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Jeste li sigurni da želite izbrisati zapisnik poziva?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Brisanje zapisnika poziva"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Govorna pošta"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index abe737f..76903dc 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"A híváslista üres."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Híváslista törlése"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Biztosan törli a híváslistát?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Hívási napló törölve"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Hangposta"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index c031cac..08302b4 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Log panggilan kosong."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Hapus log panggilan"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Apakah Anda yakin ingin menghapus log panggilan?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Membersihkan log panggilan"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Kotak Pesan"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 8568daf..6f494d1 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Il registro chiamate è vuoto."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Cancella registro chiamate"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Cancellare il registro chiamate?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Cancellazione registro chiamate"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Segreteria"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index a8fc33e..eeaa9f1 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"יומן השיחות ריק."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"נקה את יומן השיחות"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"האם אתה בטוח שברצונך לנקות את יומן השיחות?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"ניקוי יומן שיחות"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"דואר קולי"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 4f2354a..b684255 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"通話履歴なし"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"通話履歴を消去"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"通話履歴を消去してもよろしいですか?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"通話履歴の消去中"</string>
<string name="imei" msgid="3045126336951684285">"IMEI(端末識別番号)"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"ボイスメール"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index ee93888..e2fc708 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"통화기록이 없습니다."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"통화 기록 지우기"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"통화 기록을 삭제하시겠습니까?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"통화기록 지우기"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"음성사서함"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 7eb3506..034e12e 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Skambučių žurnalas tuščias."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Išvalyti skambučių žurnalą"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Ar tikrai norite išvalyti skambučių žurnalą?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Valomas skambučių žurnalas"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Balso paštas"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 31f4cee..abf7f50 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Zvanu žurnāls ir tukšs."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Notīrīt zvanu žurnālu"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Vai tiešām vēlaties notīrīt zvanu žurnālu?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Zvanu žurnāla tīrīšana"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Balss pasts"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index dcf8a0a..7b2c783 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Anropsloggen er tom."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Tøm samtalelogg"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Er du sikker på at du vil tømme samtaleloggen?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Tømming av anropslogg"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Telefonsvarer"</string>
@@ -161,12 +162,12 @@
<string name="simContacts_title" msgid="27341688347689769">"Kontakter på SIM-kort"</string>
<string name="noContactsHelpTextWithSyncForCreateShortcut" msgid="801504710275614594">"Du har ingen kontakter å vise. (Hvis du nettopp har lagt til en konto, kan det ta noen minutter å synkronisere kontaktene.)"</string>
<string name="noContactsHelpTextForCreateShortcut" msgid="3081286388667108335">"Du har ingen kontakter å vise."</string>
- <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:292 in java.io.StringReader@1aa8c488) -->
- <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:293 in java.io.StringReader@3dfeca64) -->
+ <!-- syntax error in translation for noContactsHelpText (6450346791169710787) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:292 in java.io.StringReader@22998b08) -->
+ <!-- syntax error in translation for noContactsHelpText (7633826236417884130) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:293 in java.io.StringReader@e76cbf7) -->
<string name="noContactsHelpTextWithSync" product="tablet" msgid="2364665535969139880">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>", og trykk deretter på:"\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer"</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til nettbrettet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt fra grunnen av"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/Eksporter"</b></font>" for å importere kontakter fra SIM- eller SD-kort"\n</li></string>
<string name="noContactsHelpTextWithSync" product="default" msgid="3017521127042216243">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer "</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til telefonen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importér/Eksportér"</b></font>" for å importere kontakter fra SIM- eller SD-kort"\n</li></string>
- <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@22998b08) -->
- <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@e76cbf7) -->
+ <!-- syntax error in translation for noContactsNoSimHelpText (6031363021287849874) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@1948cc8c) -->
+ <!-- syntax error in translation for noContactsNoSimHelpText (467658807711582876) org.xmlpull.v1.XmlPullParserException: expected: /li read: font (position:END_TAG </font>@1:297 in java.io.StringReader@7a6d084b) -->
<string name="noContactsNoSimHelpTextWithSync" product="tablet" msgid="6222739731808897565">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>", og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer"</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til nettbrettet"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt fra grunnen av"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importer/eksporter"</b></font>" for å importere kontakter fra SD-kortet"\n</li></string>
<string name="noContactsNoSimHelpTextWithSync" product="default" msgid="9040060730467973050">"Du har ingen kontakter å vise. (Hvis du nylig la til en konto, kan det ta noen minutter å synkronisere kontaktene.)"\n\n"Slik legger du til kontakter: Trykk på "<font fgcolor="#ffffffff"><b>"Meny"</b></font>" og trykk deretter på: "\n" "\n<li><font fgcolor="#ffffffff"><b>"Kontoer "</b></font>" for å legge til eller konfigurere en konto med kontakter som kan synkroniseres til telefonen"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Visningsalternativer"</b></font>" for å endre hvilke kontakter som vises"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Ny kontakt"</b></font>" for å opprette en ny kontakt"\n</li>" "\n<li><font fgcolor="#ffffffff"><b>"Importér/eksportér"</b></font>" for å importere kontakter fra SD-kortet"\n</li></string>
<string name="noFavoritesHelpText" msgid="3744655776704833277">"Du har ingen favoritter."\n\n"Slik legger du til en kontakt i favorittlisten:"\n\n" "<li>"Trykk på fanen "<b>"Kontakter"</b>" "\n</li>" "\n<li>"Trykk på kontakten du vil legge til i favoritter"\n</li>" "\n<li>"Trykk på stjernen ved siden av kontaktnavnet"\n</li></string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index cc70f61..021dd61 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Gesprekken is leeg"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Oproeplogboek wissen"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Weet u zeker dat u het oproeplogboek wilt wissen?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Oproeplogboek wissen"</string>
<string name="imei" msgid="3045126336951684285">"IMEI-nummer"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 98cc2e8..991b556 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Rejestr połączeń jest pusty."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Wyczyść rejestr połączeń"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Czy na pewno chcesz wyczyścić rejestr połączeń?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Czyszczenie dziennika połączeń"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"Numer MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Poczta głosowa"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 556e529..3527d6a 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"O registo de chamadas está vazio."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Limpar registo de chamadas"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Tem a certeza de que pretende limpar o registo de chamadas?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Limpar registo de chamadas"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Correio de voz"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 6a573f7..e138aaa 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"O registro de chamadas está vazio."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Limpar registro de chamadas"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Tem certeza de que deseja limpar o registro de chamadas?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Limpando registro de chamadas"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Correio de voz"</string>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 7892abb..cdc8d90 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -153,6 +153,8 @@
<string name="recentCalls_empty" msgid="247053222448663107">"La glista da cloms e vida"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Stizzar il protocol da cloms"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Vulais Vus propi stizzar il protocol da cloms?"</string>
+ <!-- no translation found for clearCallLogProgress_title (6870412675015656948) -->
+ <skip />
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Mailbox"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index b52a70c..a831658 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Jurnalul de apeluri este gol."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Ştergeţi jurnalul de apeluri"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Sigur doriţi ştergerea jurnalului de apeluri?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Se goleşte jurnalul de apeluri"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Mesagerie vocală"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 4dade70..653942c 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Список вызовов пуст."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Очистить список вызовов"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Действительно очистить список вызовов?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Очистка списка вызовов"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Голосовая почта"</string>
@@ -233,7 +234,7 @@
<string name="fail_reason_vcard_parse_error" msgid="1201233722762680214">"Не удалось обработать vCard по неизвестной причине."</string>
<string name="fail_reason_not_supported" msgid="294499264620201243">"Формат не поддерживается."</string>
<string name="vcard_import_failed" msgid="7718330063493653085">"Не удалось импортировать vCard"</string>
- <string name="import_failure_no_vcard_file" product="nosdcard" msgid="6339234836196984924">"На накопителе отсутствуют файлы vCard"</string>
+ <string name="import_failure_no_vcard_file" product="nosdcard" msgid="6339234836196984924">"На накопителе нет vCard-файлов"</string>
<string name="import_failure_no_vcard_file" product="default" msgid="1730986357514922756">"На SD-карте не найдены файлы VCard"</string>
<string name="fail_reason_failed_to_collect_vcard_meta_info" msgid="4154492282316067754">"Не удалось собрать метаинформацию файлов VCard."</string>
<string name="fail_reason_failed_to_read_files" msgid="3659521123567134029">"Не удалось импортировать один или несколько файлов (%s)."</string>
@@ -259,7 +260,7 @@
<string name="exporting_contact_failed_title" msgid="585823094820602526">"Не удалось экспортировать данные контакта."</string>
<string name="exporting_contact_failed_message" msgid="4151348002470298092">"Не удалось экспортировать данные контакта."\n"Причина: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\""</string>
<string name="fail_reason_no_exportable_contact" msgid="4919714086648344495">"Нет контактов, которые можно экспортировать."</string>
- <string name="fail_reason_too_many_vcard" product="nosdcard" msgid="3745507837635270265">"Слишком много файлов vCard на накопителе"</string>
+ <string name="fail_reason_too_many_vcard" product="nosdcard" msgid="3745507837635270265">"Слишком много vCard-файлов на накопителе"</string>
<string name="fail_reason_too_many_vcard" product="default" msgid="7084146295639672658">"Слишком много файлов VCard на SD-карте."</string>
<string name="fail_reason_too_long_filename" msgid="1915716071321839166">"Название файла слишком длинное (<xliff:g id="FILENAME">%s</xliff:g>)."</string>
<string name="exporting_vcard_finished_title" msgid="4259736138838583213">"Экспорт <xliff:g id="FILENAME">%s</xliff:g> завершен"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 6a78891..ab3eb74 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Záznam hovorov je prázdny."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Vymazať záznam hovorov"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Naozaj chcete odstrániť denník hovorov?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Vymazávanie denníka hovorov"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Hlasová schránka"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 0bb51c4..2c4c983 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Dnevnik klicev je prazen."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Počisti dnevnik klicev"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Ali ste prepričani, da želite počistiti dnevnik klicev?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Brisanje dnevnika klicev"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Glasovna pošta"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 614548e..bddf143 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Евиденција позива је празна."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Обриши евиденцију позива"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Желите ли заиста да обришете евиденцију позива?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Брисање евиденције позива"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Говорна пошта"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index dbe0f1b..f0b0605 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Samtalshistoriken är tom."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Rensa samtalshistorik"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Vill du rensa samtalshistoriken?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Rensar samtalshistorik"</string>
<string name="imei" msgid="3045126336951684285">"IMEI-kod"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Röstbrevlåda"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index d545369..c5cbe5c 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"บันทึกการโทรว่างเปล่า"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"ล้างบันทึกการโทร"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"คุณแน่ใจหรือไม่ว่าต้องการล้างบันทึกการโทรทั้งหมด"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"การล้างบันทึกการโทร"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"ข้อความเสียง"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index d8321ce..274c5e0 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Walang laman ang log ng tawag."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"I-clear ang log ng tawag"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Sigurado ka bang gusto mong i-clear ang log ng tawag?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Kini-clear ang log ng tawag"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Voicemail"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 3857046..366edf7 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Çağrı kaydı boş."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Çağrı kaydını temizle"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Çağrı kaydını silmek istediğinizden emin misiniz?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Çağrı kaydı temizleniyor"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Sesli Mesaj"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 35576b4..419b70f 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Журн. викл. порожній."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Очист. журнал викл."</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Дійсно очистити журнал викликів?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Очищення журналу викликів"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Голос. пошта"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 4c78800..30691ff 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"Nhật ký cuộc gọi trống."</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"Xoá nhật ký cuộc gọi"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"Bạn có chắc chắn muốn xoá nhật ký cuộc gọi không?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"Đang xóa nhật ký cuộc gọi"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"Thư thoại"</string>
diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml
index d29eba2..d18b789 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-xlarge/dimens.xml
@@ -23,4 +23,5 @@
<dimen name="action_bar_search_max_width">300dip</dimen>
<dimen name="action_bar_search_spacing">12dip</dimen>
<dimen name="shortcut_icon_size">64dip</dimen>
+ <dimen name="list_section_height">37dip</dimen>
</resources>
diff --git a/res/values-xlarge/donottranslate_config.xml b/res/values-xlarge/donottranslate_config.xml
new file mode 100644
index 0000000..fcb7da9
--- /dev/null
+++ b/res/values-xlarge/donottranslate_config.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+ <bool name="config_use_two_panes">true</bool>
+</resources>
diff --git a/res/values-xlarge/styles.xml b/res/values-xlarge/styles.xml
index e601590..6f6b334 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-xlarge/styles.xml
@@ -57,9 +57,6 @@
<item name="list_item_header_text_size">14sp</item>
</style>
- <style name="ContactsPreferencesTheme" parent="@android:Theme.Holo.Light">
- </style>
-
<style name="CustomContactListFilterTheme" parent="@android:Theme.Holo.Light.Dialog">
</style>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index a4aef23..0a53881 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"通话记录为空。"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"清除通话记录"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"确定要清除通话记录吗?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"正在清除通话记录"</string>
<string name="imei" msgid="3045126336951684285">"移动通信国际识别码"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"语音信箱"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 3cfddeb..4e97538 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -149,6 +149,7 @@
<string name="recentCalls_empty" msgid="247053222448663107">"無通話記錄。"</string>
<string name="clearCallLogConfirmation_title" msgid="718072843006222703">"清除通話記錄"</string>
<string name="clearCallLogConfirmation" msgid="7625927669136267636">"確定要清除通話記錄嗎?"</string>
+ <string name="clearCallLogProgress_title" msgid="6870412675015656948">"正在清除通話記錄"</string>
<string name="imei" msgid="3045126336951684285">"IMEI"</string>
<string name="meid" msgid="6210568493746275750">"MEID"</string>
<string name="voicemail" msgid="3851469869202611441">"語音留言"</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 47150b4..2255cd8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -75,4 +75,7 @@
<!-- Size of the shortcut icon. 0dip means: use the system default -->
<dimen name="shortcut_icon_size">0dip</dimen>
+
+ <!-- Height of list sections (A, B, C) that show the first character of the contacts -->
+ <dimen name="list_section_height">25dip</dimen>
</resources>
diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml
index f5efa13..e310953 100644
--- a/res/values/donottranslate_config.xml
+++ b/res/values/donottranslate_config.xml
@@ -99,4 +99,8 @@
<!-- If true, phonetic name is included in the contact editor by default -->
<bool name="config_editor_include_phonetic_name">false</bool>
+
+ <!-- If true, Contacts uses two panes: List and Detail. If false, Details are
+ shown in their own screens. This flag must be in sync with the layout definitions. -->
+ <bool name="config_use_two_panes">false</bool>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ff69899..c16a135 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -388,6 +388,9 @@
<!-- Confirmation dialog for clearing the call log -->
<string name="clearCallLogConfirmation">Are you sure you want to clear the call log?</string>
+ <!-- Title of the "Clearing call log" progress-dialog [CHAR LIMIT=35] -->
+ <string name="clearCallLogProgress_title">Clearing call log</string>
+
<!-- The title of a dialog that displays the IMEI of the phone -->
<string name="imei">IMEI</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index db50204..c4a588f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -14,18 +14,18 @@
limitations under the License.
-->
<resources>
- <style name="DialtactsTheme" parent="@android:Theme">
+ <style name="DialtactsTheme" parent="android:Theme.Holo.Light">
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <style name="CallDetailActivityTheme" parent="android:Theme.NoTitleBar">
+ <style name="CallDetailActivityTheme" parent="android:Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
</style>
- <style name="ContactDetailActivityTheme" parent="android:Theme.NoTitleBar">
+ <style name="ContactDetailActivityTheme" parent="android:Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
</style>
- <style name="ContactEditorActivityTheme" parent="android:Theme.NoTitleBar">
+ <style name="ContactEditorActivityTheme" parent="android:Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
</style>
@@ -38,38 +38,19 @@
<item name="android:windowIsFloating">true</item>
</style>
- <style name="FullyTranslucent" parent="android:Theme.Translucent.NoTitleBar">
- <item name="android:windowContentOverlay">@null</item>
+ <style name="Theme">
</style>
- <style name="FullyTranslucent.QuickContact">
- <!-- This is a hack because we want to be able to animate away the
- QuickContact window, and we close its containing activity at the
- same time. So put in a dummy animation so this guy sticks around
- while the fast track window is animating. -->
- <item name="android:windowAnimationStyle">@style/DummyAnimation</item>
- </style>
-
- <style name="QuickContact" parent="@android:Theme.Holo.Light">
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowFrame">@null</item>
+ <style name="Theme.QuickContact" parent="@android:style/Theme.Holo.Light">
<item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowIsFloating">true</item>
+ <item name="android:colorBackgroundCacheHint">@null</item>
+ <item name="android:windowFrame">@null</item>
<item name="android:windowContentOverlay">@null</item>
- <!-- TODO: create our own animation style in framework -->
- <!--
- <item name="android:windowAnimationStyle">@*android:style/Animation.ZoomButtons</item>
- -->
- </style>
-
- <style name="QuickContactAboveAnimation">
- <item name="android:windowEnterAnimation">@anim/quickcontact_above_enter</item>
- <item name="android:windowExitAnimation">@anim/quickcontact_above_exit</item>
- </style>
-
- <style name="QuickContactBelowAnimation">
- <item name="android:windowEnterAnimation">@anim/quickcontact_below_enter</item>
- <item name="android:windowExitAnimation">@anim/quickcontact_below_exit</item>
+ <item name="android:windowAnimationStyle">@null</item>
+ <item name="android:windowIsFloating">false</item>
+ <item name="android:backgroundDimEnabled">false</item>
+ <item name="android:windowIsTranslucent">true</item>
+ <item name="android:windowNoTitle">true</item>
</style>
<style name="ContactsSearchAnimation">
@@ -110,7 +91,7 @@
<style name="ContactBrowserTheme" parent="@android:Theme">
<item name="list_item_height">?android:attr/listPreferredItemHeight</item>
<item name="activated_background">@drawable/list_item_activated_background</item>
- <item name="section_header_background">@drawable/section_header</item>
+ <item name="section_header_background">@drawable/list_title_holo</item>
<item name="list_section_header_height">32dip</item>
<item name="list_item_divider">@drawable/list_item_divider</item>
<item name="list_item_padding_top">4dip</item>
@@ -152,7 +133,7 @@
<style name="JoinContactActivityTheme" parent="ContactPickerTheme" >
</style>
- <style name="ContactsPreferencesTheme" parent="@android:Theme">
+ <style name="ContactsPreferencesTheme" parent="@android:Theme.Holo.Light">
</style>
<style name="CustomContactListFilterTheme" parent="@android:Theme">
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 0e75a7f..76cbc7d 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -16,6 +16,11 @@
package com.android.contacts;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.MatchType;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
import android.content.Context;
import android.content.Intent;
import android.location.CountryDetector;
@@ -114,9 +119,19 @@
if (dataParts1.length != dataParts2.length) {
return false;
}
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
for (int i = 0; i < dataParts1.length; i++) {
- if (!PhoneNumberUtils.compare(context, dataParts1[i], dataParts2[i])) {
- return false;
+ try {
+ PhoneNumber phoneNumber1 = util.parse(dataParts1[i], "ZZ" /* Unknown */);
+ PhoneNumber phoneNumber2 = util.parse(dataParts2[i], "ZZ" /* Unknown */);
+ MatchType matchType = util.isNumberMatch(phoneNumber1, phoneNumber2);
+ if (matchType != MatchType.SHORT_NSN_MATCH) {
+ return false;
+ }
+ } catch (NumberParseException e) {
+ if (!TextUtils.equals(dataParts1[i], dataParts2[i])) {
+ return false;
+ }
}
}
diff --git a/src/com/android/contacts/DialtactsActivity.java b/src/com/android/contacts/DialtactsActivity.java
index dc69194..5ad57e4 100644
--- a/src/com/android/contacts/DialtactsActivity.java
+++ b/src/com/android/contacts/DialtactsActivity.java
@@ -151,7 +151,7 @@
}
private void setupContactsTab() {
- Intent intent = new Intent(UI.LIST_DEFAULT);
+ Intent intent = new Intent(UI.LIST_ALL_CONTACTS_ACTION);
intent.setClass(this, ContactBrowserActivity.class);
mTabHost.addTab(mTabHost.newTabSpec("contacts")
diff --git a/src/com/android/contacts/RecentCallsListActivity.java b/src/com/android/contacts/RecentCallsListActivity.java
index 0a3c178..fb4ee10 100644
--- a/src/com/android/contacts/RecentCallsListActivity.java
+++ b/src/com/android/contacts/RecentCallsListActivity.java
@@ -23,8 +23,10 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
+import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
@@ -39,6 +41,7 @@
import android.database.sqlite.SQLiteFullException;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -1040,21 +1043,42 @@
protected Dialog onCreateDialog(int id, Bundle args) {
switch (id) {
case DIALOG_CONFIRM_DELETE_ALL:
+ final ContentResolver resolver = getContentResolver();
+ final OnClickListener okListener = new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final ProgressDialog progressDialog = ProgressDialog.show(
+ RecentCallsListActivity.this,
+ getString(R.string.clearCallLogProgress_title),
+ "", true, false);
+ final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ resolver.delete(Calls.CONTENT_URI, null, null);
+ return null;
+ }
+ @Override
+ protected void onPostExecute(Void result) {
+ progressDialog.dismiss();
+ // TODO The change notification should do this automatically, but
+ // it isn't working right now. Remove this when the change
+ // notification is working properly.
+ startQuery();
+ }
+ };
+ // TODO: Once we have the API, we should configure this ProgressDialog
+ // to only show up after a certain time (e.g. 150ms)
+ progressDialog.show();
+ task.execute();
+ }
+ };
return new AlertDialog.Builder(this)
.setTitle(R.string.clearCallLogConfirmation_title)
.setIconAttribute(android.R.attr.alertDialogIcon)
.setMessage(R.string.clearCallLogConfirmation)
.setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(android.R.string.ok, new OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- getContentResolver().delete(Calls.CONTENT_URI, null, null);
- // TODO The change notification should do this automatically, but it
- // isn't working right now. Remove this when the change notification
- // is working properly.
- startQuery();
- }
- })
- .setCancelable(false)
+ .setPositiveButton(android.R.string.ok, okListener)
+ .setCancelable(true)
.create();
}
return null;
diff --git a/src/com/android/contacts/TypePrecedence.java b/src/com/android/contacts/TypePrecedence.java
index 2adf3b5..e89c5aa 100644
--- a/src/com/android/contacts/TypePrecedence.java
+++ b/src/com/android/contacts/TypePrecedence.java
@@ -42,6 +42,7 @@
//TODO These may need to be tweaked.
private static final int[] TYPE_PRECEDENCE_PHONES = {
Phone.TYPE_CUSTOM,
+ Phone.TYPE_MAIN,
Phone.TYPE_MOBILE,
Phone.TYPE_HOME,
Phone.TYPE_WORK,
diff --git a/src/com/android/contacts/activities/ContactBrowserActivity.java b/src/com/android/contacts/activities/ContactBrowserActivity.java
index e888bc0..066b862 100644
--- a/src/com/android/contacts/activities/ContactBrowserActivity.java
+++ b/src/com/android/contacts/activities/ContactBrowserActivity.java
@@ -105,7 +105,13 @@
private boolean mSearchMode;
private ContactBrowseListFragment mListFragment;
+
+ /**
+ * Whether we have a right-side contact pane for displaying contact info while browsing.
+ * Generally means "this is a tablet".
+ */
private boolean mContactContentDisplayed;
+
private ContactDetailFragment mDetailFragment;
private DetailFragmentListener mDetailFragmentListener = new DetailFragmentListener();
@@ -125,7 +131,6 @@
private boolean mOptionsMenuContactsAvailable;
private boolean mOptionsMenuGroupActionsEnabled;
- private boolean mOptionsMenuCustomFilterChangeable;
public ContactBrowserActivity() {
mIntentResolver = new ContactsIntentResolver(this);
@@ -234,7 +239,6 @@
}
mOptionsMenuContactsAvailable = false;
- mOptionsMenuCustomFilterChangeable = false;
mOptionsMenuGroupActionsEnabled = false;
mProviderStatus = -1;
@@ -635,7 +639,7 @@
final MenuItem addContact = menu.findItem(R.id.menu_add);
addContact.setActionView(mAddContactImageView);
return true;
- } else if (mRequest.getActionCode() == ContactsRequest.ACTION_DEFAULT ||
+ } else if (mRequest.getActionCode() == ContactsRequest.ACTION_ALL_CONTACTS ||
mRequest.getActionCode() == ContactsRequest.ACTION_STREQUENT) {
inflater.inflate(R.menu.list, menu);
return true;
@@ -663,10 +667,6 @@
return true;
}
- if (mOptionsMenuCustomFilterChangeable != isCustomFilterChangeable()) {
- return true;
- }
-
if (mListFragment != null && mListFragment.isOptionsMenuChanged()) {
return true;
}
@@ -686,13 +686,8 @@
}
MenuItem settings = menu.findItem(R.id.menu_settings);
- settings.setVisible(!ContactsPreferenceActivity.isEmpty(this));
-
- mOptionsMenuCustomFilterChangeable = isCustomFilterChangeable();
-
- MenuItem displayGroups = menu.findItem(R.id.menu_display_groups);
- if (displayGroups != null) {
- displayGroups.setVisible(mOptionsMenuCustomFilterChangeable);
+ if (settings != null) {
+ settings.setVisible(!ContactsPreferenceActivity.isEmpty(this));
}
mOptionsMenuGroupActionsEnabled = areGroupActionsEnabled();
@@ -723,10 +718,6 @@
return groupActionsEnabled;
}
- public boolean isCustomFilterChangeable() {
- return mRequest != null && mRequest.getActionCode() == ContactsRequest.ACTION_DEFAULT;
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -853,7 +844,7 @@
case SUBACTIVITY_EDIT_CONTACT:
case SUBACTIVITY_NEW_CONTACT: {
- if (resultCode == RESULT_OK) {
+ if (resultCode == RESULT_OK && mContactContentDisplayed) {
mRequest.setActionCode(ContactsRequest.ACTION_VIEW_CONTACT);
mListFragment.reloadDataAndSetSelectedUri(data.getData());
}
@@ -910,8 +901,7 @@
default: {
// Bring up the search UI if the user starts typing
final int unicodeChar = event.getUnicodeChar();
-
- if (unicodeChar != 0) {
+ if (unicodeChar != 0 && !Character.isWhitespace(unicodeChar)) {
String query = new String(new int[]{ unicodeChar }, 0, 1);
if (mHasActionBar) {
if (!mActionBarAdapter.isSearchMode()) {
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 56e8353..0036256 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -22,6 +22,7 @@
import com.android.contacts.R;
import com.android.contacts.detail.ContactDetailFragment;
import com.android.contacts.interactions.ContactDeletionInteraction;
+import com.android.contacts.util.PhoneCapabilityTester;
import android.accounts.Account;
import android.content.ActivityNotFoundException;
@@ -44,6 +45,23 @@
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
+ if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
+ // This activity must not be shown. We have to select the contact in the
+ // ContactBrowserActivity instead ==> Create a forward intent and finish
+ final Intent originalIntent = getIntent();
+ Intent intent = new Intent();
+ intent.setAction(originalIntent.getAction());
+ intent.setDataAndType(originalIntent.getData(), originalIntent.getType());
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_FORWARD_RESULT
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+ intent.setClass(this, ContactBrowserActivity.class);
+ startActivity(intent);
+ finish();
+ return;
+ }
+
setContentView(R.layout.contact_detail_activity);
mFragment = (ContactDetailFragment) getFragmentManager().findFragmentById(
diff --git a/src/com/android/contacts/activities/ContactEditorActivity.java b/src/com/android/contacts/activities/ContactEditorActivity.java
index 35f7413..cedde4e 100644
--- a/src/com/android/contacts/activities/ContactEditorActivity.java
+++ b/src/com/android/contacts/activities/ContactEditorActivity.java
@@ -53,8 +53,6 @@
public static final String ACTION_SAVE_COMPLETED = "saveCompleted";
private ContactEditorFragment mFragment;
- private Button mDoneButton;
- private Button mRevertButton;
private DialogManager mDialogManager = new DialogManager(this);
@@ -90,22 +88,6 @@
mFragment.setListener(mFragmentListener);
Uri uri = Intent.ACTION_EDIT.equals(action) ? getIntent().getData() : null;
mFragment.load(action, uri, getIntent().getExtras());
-
- // Depending on the use-case, this activity has Done and Revert buttons or not.
- mDoneButton = (Button) findViewById(R.id.done);
- mRevertButton = (Button) findViewById(R.id.revert);
- if (mDoneButton != null) mDoneButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mFragment.save(SaveMode.CLOSE);
- }
- });
- if (mRevertButton != null) mRevertButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- finish();
- }
- });
}
@Override
diff --git a/src/com/android/contacts/activities/ContactSelectionActivity.java b/src/com/android/contacts/activities/ContactSelectionActivity.java
index 4efc43f..c255ba1 100644
--- a/src/com/android/contacts/activities/ContactSelectionActivity.java
+++ b/src/com/android/contacts/activities/ContactSelectionActivity.java
@@ -23,7 +23,9 @@
import com.android.contacts.list.ContactsIntentResolver;
import com.android.contacts.list.ContactsRequest;
import com.android.contacts.list.DirectoryListLoader;
+import com.android.contacts.list.EmailAddressPickerFragment;
import com.android.contacts.list.OnContactPickerActionListener;
+import com.android.contacts.list.OnEmailAddressPickerActionListener;
import com.android.contacts.list.OnPhoneNumberPickerActionListener;
import com.android.contacts.list.OnPostalAddressPickerActionListener;
import com.android.contacts.list.PhoneNumberPickerFragment;
@@ -171,6 +173,11 @@
break;
}
+ case ContactsRequest.ACTION_PICK_EMAIL: {
+ setTitle(R.string.contactPickerActivityTitle);
+ break;
+ }
+
case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: {
setTitle(R.string.callShortcutActivityTitle);
break;
@@ -236,6 +243,11 @@
break;
}
+ case ContactsRequest.ACTION_PICK_EMAIL: {
+ mListFragment = new EmailAddressPickerFragment();
+ break;
+ }
+
case ContactsRequest.ACTION_CREATE_SHORTCUT_CALL: {
PhoneNumberPickerFragment fragment = new PhoneNumberPickerFragment();
fragment.setShortcutAction(Intent.ACTION_CALL);
@@ -284,6 +296,9 @@
} else if (mListFragment instanceof PostalAddressPickerFragment) {
((PostalAddressPickerFragment) mListFragment).setOnPostalAddressPickerActionListener(
new PostalAddressPickerActionListener());
+ } else if (mListFragment instanceof EmailAddressPickerFragment) {
+ ((EmailAddressPickerFragment) mListFragment).setOnEmailAddressPickerActionListener(
+ new EmailAddressPickerActionListener());
} else {
throw new IllegalStateException("Unsupported list fragment type: " + mListFragment);
}
@@ -334,6 +349,14 @@
}
}
+ private final class EmailAddressPickerActionListener implements
+ OnEmailAddressPickerActionListener {
+ @Override
+ public void onPickEmailAddressAction(Uri dataUri) {
+ returnPickerResult(dataUri);
+ }
+ }
+
public void startActivityAndForwardResult(final Intent intent) {
intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
diff --git a/src/com/android/contacts/activities/ContactsFrontDoor.java b/src/com/android/contacts/activities/ContactsFrontDoor.java
index 3677cce..1f8a491 100644
--- a/src/com/android/contacts/activities/ContactsFrontDoor.java
+++ b/src/com/android/contacts/activities/ContactsFrontDoor.java
@@ -39,12 +39,12 @@
| Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(EXTRA_FRONT_DOOR, true);
- if (PhoneCapabilityTester.isPhone(this)) {
- // Default to the normal dialtacts layout
- intent.setClass(this, DialtactsActivity.class);
- } else {
+ if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
// No tabs, just a contact list
intent.setClass(this, ContactBrowserActivity.class);
+ } else {
+ // Default to the normal dialtacts layout
+ intent.setClass(this, DialtactsActivity.class);
}
startActivity(intent);
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 42b3293..91e7f9e 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -27,9 +27,9 @@
import com.android.contacts.TypePrecedence;
import com.android.contacts.editor.SelectAccountDialogFragment;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.DataKind;
import com.android.contacts.util.Constants;
import com.android.contacts.util.DataStatus;
import com.android.contacts.util.DateUtils;
@@ -1262,7 +1262,7 @@
@Override
public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
- if (!((ContactLoader)loader).getLookupUri().equals(mLookupUri)) {
+ if (!mLookupUri.equals(data.getUri())) {
return;
}
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index d733e68..d87aea4 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -16,8 +16,8 @@
package com.android.contacts.editor;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import android.provider.ContactsContract.Data;
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 906dbad..f021deb 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -20,9 +20,9 @@
import com.android.contacts.datepicker.DatePicker;
import com.android.contacts.datepicker.DatePickerDialog;
import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditField;
import com.android.contacts.model.AccountType.EventEditType;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.util.DateUtils;
diff --git a/src/com/android/contacts/editor/ExternalRawContactEditorView.java b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
index aaa1e44..01286ff 100644
--- a/src/com/android/contacts/editor/ExternalRawContactEditorView.java
+++ b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
@@ -20,7 +20,7 @@
import com.android.contacts.R;
import com.android.contacts.editor.ExternalRawContactEditorView.Listener;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index 8845aa3..d242a1b 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -19,7 +19,7 @@
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
import com.android.contacts.interactions.GroupCreationDialogFragment;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index aaeafac..bc76ba8 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -18,7 +18,7 @@
import com.android.contacts.R;
import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index a6815a7..96f234b 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -18,8 +18,8 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditType;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
diff --git a/src/com/android/contacts/editor/PhoneticNameEditorView.java b/src/com/android/contacts/editor/PhoneticNameEditorView.java
index d3aa00d..70e50a7 100644
--- a/src/com/android/contacts/editor/PhoneticNameEditorView.java
+++ b/src/com/android/contacts/editor/PhoneticNameEditorView.java
@@ -16,7 +16,7 @@
package com.android.contacts.editor;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 89633fd..6942912 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -17,8 +17,8 @@
package com.android.contacts.editor;
import com.android.contacts.R;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import android.content.Context;
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 633b343..4813f29 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -19,8 +19,8 @@
import com.android.contacts.GroupMetaDataLoader;
import com.android.contacts.R;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditType;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityModifier;
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index cf97c6c..e7277f9 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -16,7 +16,7 @@
package com.android.contacts.editor;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index 031ab18..3187eaa 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -18,8 +18,8 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditField;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.util.ThemeUtils;
diff --git a/src/com/android/contacts/editor/ViewIdGenerator.java b/src/com/android/contacts/editor/ViewIdGenerator.java
index 93bb002..c3cd08b 100644
--- a/src/com/android/contacts/editor/ViewIdGenerator.java
+++ b/src/com/android/contacts/editor/ViewIdGenerator.java
@@ -16,8 +16,8 @@
package com.android.contacts.editor;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import android.os.Bundle;
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 08f8d00..f195c2f 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -206,8 +206,13 @@
final Uri contactUri = Contacts.getLookupUri(contactId, lookupKey);
showDialog(mMessageId, contactUri);
+
+ // We don't want onLoadFinished() calls any more, which may come when the database is
+ // updating.
+ getLoaderManager().destroyLoader(R.id.dialog_delete_contact_loader_id);
}
+ @Override
public void onLoaderReset(Loader<Cursor> loader) {
}
@@ -235,7 +240,6 @@
public void onDismiss(DialogInterface dialog) {
mActive = false;
mDialog = null;
- getLoaderManager().destroyLoader(R.id.dialog_delete_contact_loader_id);
}
@Override
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 277fa56..399b0ea 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -16,14 +16,19 @@
package com.android.contacts.interactions;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.MatchType;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
import com.android.contacts.Collapser;
import com.android.contacts.Collapser.Collapsible;
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.StringInflater;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.DataKind;
import android.app.Activity;
import android.app.AlertDialog;
@@ -46,7 +51,7 @@
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -112,8 +117,16 @@
}
public boolean shouldCollapseWith(PhoneItem phoneItem) {
- if (PhoneNumberUtils.compareStrictly(phoneNumber, phoneItem.phoneNumber)) {
- return true;
+ try {
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ PhoneNumber phoneNumber1 = util.parse(phoneNumber, "ZZ" /* Unknown */);
+ PhoneNumber phoneNumber2 = util.parse(phoneItem.phoneNumber, "ZZ" /* Unknown */);
+ MatchType matchType = util.isNumberMatch(phoneNumber1, phoneNumber2);
+ if (matchType == MatchType.SHORT_NSN_MATCH) {
+ return true;
+ }
+ } catch (NumberParseException e) {
+ return TextUtils.equals(phoneNumber, phoneItem.phoneNumber);
}
return false;
}
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index be920db..1ecfff1 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -583,7 +583,7 @@
public void viewContact(Uri contactUri) {
setSelectedContactUri(contactUri, false, false, true, false);
- if (mListener != null) { mListener.onViewContactAction(contactUri); }
+ if (mListener != null) mListener.onViewContactAction(contactUri);
}
public void editContact(Uri contactUri) {
diff --git a/src/com/android/contacts/list/ContactsIntentResolver.java b/src/com/android/contacts/list/ContactsIntentResolver.java
index afe29df..3ef68d8 100644
--- a/src/com/android/contacts/list/ContactsIntentResolver.java
+++ b/src/com/android/contacts/list/ContactsIntentResolver.java
@@ -27,6 +27,7 @@
import android.provider.Contacts.ContactMethods;
import android.provider.Contacts.People;
import android.provider.Contacts.Phones;
+import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.Contacts;
@@ -95,6 +96,8 @@
} else if (ContactMethods.CONTENT_POSTAL_TYPE.equals(resolvedType)) {
request.setActionCode(ContactsRequest.ACTION_PICK_POSTAL);
request.setLegacyCompatibilityMode(true);
+ } else if (Email.CONTENT_TYPE.equals(resolvedType)) {
+ request.setActionCode(ContactsRequest.ACTION_PICK_EMAIL);
}
} else if (Intent.ACTION_CREATE_SHORTCUT.equals(action)) {
String component = intent.getComponent().getClassName();
diff --git a/src/com/android/contacts/list/ContactsRequest.java b/src/com/android/contacts/list/ContactsRequest.java
index aefa451..e20d189 100644
--- a/src/com/android/contacts/list/ContactsRequest.java
+++ b/src/com/android/contacts/list/ContactsRequest.java
@@ -62,6 +62,9 @@
/** Show all postal addresses and pick them when clicking */
public static final int ACTION_PICK_POSTAL = 100;
+ /** Show all postal addresses and pick them when clicking */
+ public static final int ACTION_PICK_EMAIL = 105;
+
/** Show all contacts and create a shortcut for the picked contact */
public static final int ACTION_CREATE_SHORTCUT_CONTACT = 110;
diff --git a/src/com/android/contacts/list/EmailAddressListAdapter.java b/src/com/android/contacts/list/EmailAddressListAdapter.java
new file mode 100644
index 0000000..96c69f9
--- /dev/null
+++ b/src/com/android/contacts/list/EmailAddressListAdapter.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.list;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.database.Cursor;
+import android.net.Uri;
+import android.net.Uri.Builder;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.ContactCounts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.text.TextUtils;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A cursor adapter for the {@link Email#CONTENT_TYPE} content type.
+ */
+public class EmailAddressListAdapter extends ContactEntryListAdapter {
+
+ static final String[] EMAILS_PROJECTION = new String[] {
+ Email._ID, // 0
+ Email.TYPE, // 1
+ Email.LABEL, // 2
+ Email.DATA, // 3
+ Email.DISPLAY_NAME_PRIMARY, // 4
+ Email.DISPLAY_NAME_ALTERNATIVE, // 5
+ Email.PHOTO_ID, // 6
+ };
+
+ protected static final int EMAIL_ID_COLUMN_INDEX = 0;
+ protected static final int EMAIL_TYPE_COLUMN_INDEX = 1;
+ protected static final int EMAIL_LABEL_COLUMN_INDEX = 2;
+ protected static final int EMAIL_ADDRESS_COLUMN_INDEX = 3;
+ protected static final int EMAIL_PRIMARY_DISPLAY_NAME_COLUMN_INDEX = 4;
+ protected static final int EMAIL_ALTERNATIVE_DISPLAY_NAME_COLUMN_INDEX = 5;
+ protected static final int EMAIL_PHOTO_ID_COLUMN_INDEX = 6;
+
+ private CharSequence mUnknownNameText;
+ private int mDisplayNameColumnIndex;
+ private int mAlternativeDisplayNameColumnIndex;
+
+ public EmailAddressListAdapter(Context context) {
+ super(context);
+
+ mUnknownNameText = context.getText(android.R.string.unknownName);
+ }
+
+ @Override
+ public void configureLoader(CursorLoader loader, long directoryId) {
+ final Builder builder;
+ if (isSearchMode()) {
+ builder = Email.CONTENT_FILTER_URI.buildUpon();
+ String query = getQueryString();
+ builder.appendPath(TextUtils.isEmpty(query) ? "" : query);
+ } else {
+ builder = Email.CONTENT_URI.buildUpon();
+ }
+ builder.appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
+ String.valueOf(directoryId));
+ applyDataRestriction(builder);
+ loader.setUri(builder.build());
+ loader.setProjection(EMAILS_PROJECTION);
+
+ if (getSortOrder() == ContactsContract.Preferences.SORT_ORDER_PRIMARY) {
+ loader.setSortOrder(Email.SORT_KEY_PRIMARY);
+ } else {
+ loader.setSortOrder(Email.SORT_KEY_ALTERNATIVE);
+ }
+ }
+
+ protected static Builder buildSectionIndexerUri(Uri uri) {
+ return uri.buildUpon()
+ .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true");
+ }
+
+ @Override
+ public String getContactDisplayName(int position) {
+ return ((Cursor)getItem(position)).getString(mDisplayNameColumnIndex);
+ }
+
+ @Override
+ public void setContactNameDisplayOrder(int displayOrder) {
+ super.setContactNameDisplayOrder(displayOrder);
+ if (getContactNameDisplayOrder() == ContactsContract.Preferences.DISPLAY_ORDER_PRIMARY) {
+ mDisplayNameColumnIndex = EMAIL_PRIMARY_DISPLAY_NAME_COLUMN_INDEX;
+ mAlternativeDisplayNameColumnIndex = EMAIL_ALTERNATIVE_DISPLAY_NAME_COLUMN_INDEX;
+ } else {
+ mDisplayNameColumnIndex = EMAIL_ALTERNATIVE_DISPLAY_NAME_COLUMN_INDEX;
+ mAlternativeDisplayNameColumnIndex = EMAIL_PRIMARY_DISPLAY_NAME_COLUMN_INDEX;
+ }
+ }
+
+ /**
+ * Builds a {@link Data#CONTENT_URI} for the current cursor
+ * position.
+ */
+ public Uri getDataUri(int position) {
+ long id = ((Cursor)getItem(position)).getLong(EMAIL_ID_COLUMN_INDEX);
+ return ContentUris.withAppendedId(Data.CONTENT_URI, id);
+ }
+
+ @Override
+ protected View newView(Context context, int partition, Cursor cursor, int position,
+ ViewGroup parent) {
+ final ContactListItemView view = new ContactListItemView(context, null);
+ view.setUnknownNameText(mUnknownNameText);
+ view.setTextWithHighlightingFactory(getTextWithHighlightingFactory());
+ view.setQuickContactEnabled(isQuickContactEnabled());
+ return view;
+ }
+
+ @Override
+ protected void bindView(View itemView, int partition, Cursor cursor, int position) {
+ ContactListItemView view = (ContactListItemView)itemView;
+ bindSectionHeaderAndDivider(view, position);
+ bindName(view, cursor);
+ bindPhoto(view, cursor);
+ bindEmailAddress(view, cursor);
+ }
+
+ protected void bindEmailAddress(ContactListItemView view, Cursor cursor) {
+ CharSequence label = null;
+ if (!cursor.isNull(EMAIL_TYPE_COLUMN_INDEX)) {
+ final int type = cursor.getInt(EMAIL_TYPE_COLUMN_INDEX);
+ final String customLabel = cursor.getString(EMAIL_LABEL_COLUMN_INDEX);
+
+ // TODO cache
+ label = Email.getTypeLabel(getContext().getResources(), type, customLabel);
+ }
+ view.setLabel(label);
+ view.showData(cursor, EMAIL_ADDRESS_COLUMN_INDEX);
+ }
+
+ protected void bindSectionHeaderAndDivider(final ContactListItemView view, int position) {
+ final int section = getSectionForPosition(position);
+ if (getPositionForSection(section) == position) {
+ String title = (String)getSections()[section];
+ view.setSectionHeader(title);
+ } else {
+ view.setDividerVisible(false);
+ view.setSectionHeader(null);
+ }
+
+ // move the divider for the last item in a section
+ if (getPositionForSection(section + 1) - 1 == position) {
+ view.setDividerVisible(false);
+ } else {
+ view.setDividerVisible(true);
+ }
+ }
+
+ protected void bindName(final ContactListItemView view, Cursor cursor) {
+ view.showDisplayName(cursor, mDisplayNameColumnIndex, isNameHighlightingEnabled(),
+ mAlternativeDisplayNameColumnIndex);
+// view.showPhoneticName(cursor, PHONE_PHONETIC_NAME_COLUMN_INDEX);
+ }
+
+ protected void bindPhoto(final ContactListItemView view, Cursor cursor) {
+ long photoId = 0;
+ if (!cursor.isNull(EMAIL_PHOTO_ID_COLUMN_INDEX)) {
+ photoId = cursor.getLong(EMAIL_PHOTO_ID_COLUMN_INDEX);
+ }
+
+ getPhotoLoader().loadPhoto(view.getPhotoView(), photoId);
+ }
+//
+// protected void bindSearchSnippet(final ContactListItemView view, Cursor cursor) {
+// view.showSnippet(cursor, SUMMARY_SNIPPET_MIMETYPE_COLUMN_INDEX,
+// SUMMARY_SNIPPET_DATA1_COLUMN_INDEX, SUMMARY_SNIPPET_DATA4_COLUMN_INDEX);
+// }
+
+}
diff --git a/src/com/android/contacts/list/EmailAddressPickerFragment.java b/src/com/android/contacts/list/EmailAddressPickerFragment.java
new file mode 100644
index 0000000..168e135
--- /dev/null
+++ b/src/com/android/contacts/list/EmailAddressPickerFragment.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.list;
+
+import com.android.contacts.R;
+
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Fragment containing an email list for picking.
+ */
+public class EmailAddressPickerFragment extends ContactEntryListFragment<ContactEntryListAdapter> {
+ private OnEmailAddressPickerActionListener mListener;
+
+ public EmailAddressPickerFragment() {
+ setQuickContactEnabled(false);
+ setPhotoLoaderEnabled(true);
+ setSectionHeaderDisplayEnabled(true);
+ setDirectorySearchMode(DirectoryListLoader.SEARCH_MODE_DATA_SHORTCUT);
+ }
+
+ public void setOnEmailAddressPickerActionListener(OnEmailAddressPickerActionListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ protected void onItemClick(int position, long id) {
+ EmailAddressListAdapter adapter = (EmailAddressListAdapter)getAdapter();
+ pickEmailAddress(adapter.getDataUri(position));
+ }
+
+ @Override
+ protected ContactEntryListAdapter createListAdapter() {
+ EmailAddressListAdapter adapter = new EmailAddressListAdapter(getActivity());
+ adapter.setSectionHeaderDisplayEnabled(true);
+ adapter.setDisplayPhotos(true);
+ return adapter;
+ }
+
+ @Override
+ protected View inflateView(LayoutInflater inflater, ViewGroup container) {
+ return inflater.inflate(R.layout.contacts_list_content, null);
+ }
+
+ private void pickEmailAddress(Uri uri) {
+ mListener.onPickEmailAddressAction(uri);
+ }
+}
diff --git a/src/com/android/contacts/list/OnEmailAddressPickerActionListener.java b/src/com/android/contacts/list/OnEmailAddressPickerActionListener.java
new file mode 100644
index 0000000..e785323
--- /dev/null
+++ b/src/com/android/contacts/list/OnEmailAddressPickerActionListener.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.list;
+
+import android.net.Uri;
+
+/**
+ * Action callbacks that can be sent by a email address picker.
+ */
+public interface OnEmailAddressPickerActionListener {
+
+ /**
+ * Returns the selected phone number to the requester.
+ */
+ void onPickEmailAddressAction(Uri dataUri);
+}
diff --git a/src/com/android/contacts/list/PostalAddressListAdapter.java b/src/com/android/contacts/list/PostalAddressListAdapter.java
index e622ec6..8b3c75d 100644
--- a/src/com/android/contacts/list/PostalAddressListAdapter.java
+++ b/src/com/android/contacts/list/PostalAddressListAdapter.java
@@ -131,7 +131,7 @@
final String customLabel = cursor.getString(POSTAL_LABEL_COLUMN_INDEX);
// TODO cache
- label = StructuredPostal.getTypeLabel(getContext().getResources(), type, label);
+ label = StructuredPostal.getTypeLabel(getContext().getResources(), type, customLabel);
}
view.setLabel(label);
view.showData(cursor, POSTAL_ADDRESS_COLUMN_INDEX);
diff --git a/src/com/android/contacts/list/PostalAddressPickerFragment.java b/src/com/android/contacts/list/PostalAddressPickerFragment.java
index f14b718..5f7ca56 100644
--- a/src/com/android/contacts/list/PostalAddressPickerFragment.java
+++ b/src/com/android/contacts/list/PostalAddressPickerFragment.java
@@ -73,7 +73,7 @@
return inflater.inflate(R.layout.contacts_list_content, null);
}
- public void pickPostalAddress(Uri uri) {
+ private void pickPostalAddress(Uri uri) {
mListener.onPickPostalAddressAction(uri);
}
}
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index aef5c06..5dda38e 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -30,15 +30,12 @@
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import android.view.View;
import android.widget.EditText;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
-import java.util.List;
/**
* Internal structure that represents constraints and styles for a specific data
@@ -160,87 +157,6 @@
}
/**
- * Description of a specific data type, usually marked by a unique
- * {@link Data#MIMETYPE}. Includes details about how to view and edit
- * {@link Data} rows of this kind, including the possible {@link EditType}
- * labels and editable {@link EditField}.
- */
- public static class DataKind {
-
- public static final String PSEUDO_MIME_TYPE_DISPLAY_NAME = "#displayName";
- public static final String PSEUDO_MIME_TYPE_PHONETIC_NAME = "#phoneticName";
- public static final String PSEUDO_COLUMN_PHONETIC_NAME = "#phoneticName";
-
- public String resPackageName;
- public String mimeType;
- public int titleRes;
- public int iconRes;
- public int iconAltRes;
- public int weight;
- public boolean editable;
-
- /**
- * If this is true (default), the user can add and remove values.
- * If false, the editor will always show a single field (which might be empty).
- */
- public boolean isList;
-
- public StringInflater actionHeader;
- public StringInflater actionAltHeader;
- public StringInflater actionBody;
-
- public boolean actionBodySocial = false;
-
- public String typeColumn;
-
- /**
- * Maximum number of values allowed in the list. -1 represents infinity.
- * If {@link DataKind#isList} is false, this value is ignored.
- */
- public int typeOverallMax;
-
- public List<EditType> typeList;
- public List<EditField> fieldList;
-
- public ContentValues defaultValues;
-
- public Class<? extends View> editorClass;
-
- /**
- * If this is a date field, this specifies the format of the date when saving. The
- * date includes year, month and day. If this is not a date field or the date field is not
- * editable, this value should be ignored.
- */
- public SimpleDateFormat dateFormatWithoutYear;
-
- /**
- * If this is a date field, this specifies the format of the date when saving. The
- * date includes month and day. If this is not a date field, the field is not editable or
- * dates without year are not supported, this value should be ignored.
- */
- public SimpleDateFormat dateFormatWithYear;
-
- public DataKind() {
- }
-
- public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable) {
- this(mimeType, titleRes, iconRes, weight, editable, null);
- }
-
- public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable,
- Class<? extends View> editorClass) {
- this.mimeType = mimeType;
- this.titleRes = titleRes;
- this.iconRes = iconRes;
- this.weight = weight;
- this.editable = editable;
- this.isList = true;
- this.typeOverallMax = -1;
- this.editorClass = editorClass;
- }
- }
-
- /**
* Description of a specific "type" or "label" of a {@link DataKind} row,
* such as {@link Phone#TYPE_WORK}. Includes constraints on total number of
* rows a {@link Contacts} may have of this type, and details on how
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index 06bb9bd..58195a1 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -16,7 +16,6 @@
package com.android.contacts.model;
-import com.android.contacts.model.AccountType.DataKind;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
diff --git a/src/com/android/contacts/model/DataKind.java b/src/com/android/contacts/model/DataKind.java
new file mode 100644
index 0000000..837dafe
--- /dev/null
+++ b/src/com/android/contacts/model/DataKind.java
@@ -0,0 +1,93 @@
+package com.android.contacts.model;
+
+import com.android.contacts.model.AccountType.EditField;
+import com.android.contacts.model.AccountType.EditType;
+import com.android.contacts.model.AccountType.StringInflater;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract.Data;
+import android.view.View;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+/**
+ * Description of a specific data type, usually marked by a unique
+ * {@link Data#MIMETYPE}. Includes details about how to view and edit
+ * {@link Data} rows of this kind, including the possible {@link EditType}
+ * labels and editable {@link EditField}.
+ */
+public class DataKind {
+
+ public static final String PSEUDO_MIME_TYPE_DISPLAY_NAME = "#displayName";
+ public static final String PSEUDO_MIME_TYPE_PHONETIC_NAME = "#phoneticName";
+ public static final String PSEUDO_COLUMN_PHONETIC_NAME = "#phoneticName";
+
+ public String resPackageName;
+ public String mimeType;
+ public int titleRes;
+ public int iconRes;
+ public int iconAltRes;
+ public int weight;
+ public boolean editable;
+
+ /**
+ * If this is true (default), the user can add and remove values.
+ * If false, the editor will always show a single field (which might be empty).
+ */
+ public boolean isList;
+
+ public StringInflater actionHeader;
+ public StringInflater actionAltHeader;
+ public StringInflater actionBody;
+
+ public boolean actionBodySocial = false;
+
+ public String typeColumn;
+
+ /**
+ * Maximum number of values allowed in the list. -1 represents infinity.
+ * If {@link DataKind#isList} is false, this value is ignored.
+ */
+ public int typeOverallMax;
+
+ public List<EditType> typeList;
+ public List<EditField> fieldList;
+
+ public ContentValues defaultValues;
+
+ public Class<? extends View> editorClass;
+
+ /**
+ * If this is a date field, this specifies the format of the date when saving. The
+ * date includes year, month and day. If this is not a date field or the date field is not
+ * editable, this value should be ignored.
+ */
+ public SimpleDateFormat dateFormatWithoutYear;
+
+ /**
+ * If this is a date field, this specifies the format of the date when saving. The
+ * date includes month and day. If this is not a date field, the field is not editable or
+ * dates without year are not supported, this value should be ignored.
+ */
+ public SimpleDateFormat dateFormatWithYear;
+
+ public DataKind() {
+ }
+
+ public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable) {
+ this(mimeType, titleRes, iconRes, weight, editable, null);
+ }
+
+ public DataKind(String mimeType, int titleRes, int iconRes, int weight, boolean editable,
+ Class<? extends View> editorClass) {
+ this.mimeType = mimeType;
+ this.titleRes = titleRes;
+ this.iconRes = iconRes;
+ this.weight = weight;
+ this.editable = editable;
+ this.isList = true;
+ this.typeOverallMax = -1;
+ this.editorClass = editorClass;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/contacts/model/EntityModifier.java b/src/com/android/contacts/model/EntityModifier.java
index 1e014ef..3d40f11 100644
--- a/src/com/android/contacts/model/EntityModifier.java
+++ b/src/com/android/contacts/model/EntityModifier.java
@@ -17,7 +17,6 @@
package com.android.contacts.model;
import com.android.contacts.ContactsUtils;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditField;
import com.android.contacts.model.AccountType.EditType;
import com.android.contacts.model.EntityDelta.ValuesDelta;
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index af25691..7983a65 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -63,9 +63,10 @@
kind.typeColumn = Phone.TYPE;
kind.typeList = Lists.newArrayList();
- kind.typeList.add(buildPhoneType(Phone.TYPE_HOME));
kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE));
kind.typeList.add(buildPhoneType(Phone.TYPE_WORK));
+ kind.typeList.add(buildPhoneType(Phone.TYPE_HOME));
+ kind.typeList.add(buildPhoneType(Phone.TYPE_MAIN));
kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_WORK).setSecondary(true));
kind.typeList.add(buildPhoneType(Phone.TYPE_FAX_HOME).setSecondary(true));
kind.typeList.add(buildPhoneType(Phone.TYPE_PAGER).setSecondary(true));
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index bd59856..787d482 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -2,7 +2,7 @@
import com.android.contacts.ContactsUtils;
import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DataKind;
+import com.android.contacts.model.DataKind;
import com.android.contacts.util.Constants;
import com.android.contacts.util.PhoneCapabilityTester;
diff --git a/src/com/android/contacts/quickcontact/FloatingChildLayout.java b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
new file mode 100644
index 0000000..ddba609
--- /dev/null
+++ b/src/com/android/contacts/quickcontact/FloatingChildLayout.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.quickcontact;
+
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.Animation.AnimationListener;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.PopupWindow;
+
+/**
+ * Layout containing single child {@link View} which it attempts to center
+ * around {@link #setChildTargetScreen(Rect)}.
+ * <p>
+ * Updates drawable state to be {@link android.R.attr#state_first} when child is
+ * above target, and {@link android.R.attr#state_last} when child is below
+ * target. Also updates {@link Drawable#setLevel(int)} on child
+ * {@link View#getBackground()} to reflect horizontal center of target.
+ * <p>
+ * The reason for this approach is because target {@link Rect} is in screen
+ * coordinates disregarding decor insets; otherwise something like
+ * {@link PopupWindow} might work better.
+ */
+public class FloatingChildLayout extends FrameLayout {
+ private static final String TAG = "FloatingChild";
+
+ public FloatingChildLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private View mChild;
+
+ private Rect mTargetScreen = new Rect();
+
+ private int mCalloutState = 0;
+ private int mCalloutLeft;
+
+ @Override
+ protected void onFinishInflate() {
+ mChild = findViewById(android.R.id.content);
+ mChild.setDuplicateParentStateEnabled(true);
+ }
+
+ public View getChild() {
+ return mChild;
+ }
+
+ /**
+ * Set {@link Rect} in screen coordinates that {@link #getChild()} should be
+ * centered around.
+ */
+ public void setChildTargetScreen(Rect targetScreen) {
+ mTargetScreen = targetScreen;
+ requestLayout();
+ }
+
+ /**
+ * Return {@link #mTargetScreen} in local window coordinates, taking any
+ * decor insets into account.
+ */
+ private Rect getTargetInWindow() {
+ final Rect windowScreen = new Rect();
+ getWindowVisibleDisplayFrame(windowScreen);
+
+ final Rect target = new Rect(mTargetScreen);
+ target.offset(-windowScreen.left, -windowScreen.top);
+ return target;
+ }
+
+ private void updateCallout(int calloutState, int calloutLeft) {
+ if (mCalloutState != calloutState) {
+ mCalloutState = calloutState;
+ mChild.refreshDrawableState();
+ }
+
+ final Drawable background = mChild.getBackground();
+ if (background != null && mCalloutLeft != calloutLeft) {
+ mCalloutLeft = calloutLeft;
+ background.setLevel(calloutLeft);
+ }
+ }
+
+ @Override
+ protected int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+ mergeDrawableStates(drawableState, new int[] { mCalloutState });
+ return drawableState;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+
+ final View child = mChild;
+ final Rect target = getTargetInWindow();
+
+ final int childWidth = child.getMeasuredWidth();
+ final int childHeight = child.getMeasuredHeight();
+
+ // default is no callout, left-aligned, and vertically centered
+ int calloutState = 0;
+ int childLeft = target.left;
+ int childTop = target.centerY() - (childHeight / 2);
+
+ // when target is wide, horizontally center instead of left-align
+ if (target.width() > childWidth / 2) {
+ childLeft = target.centerX() - (childWidth / 2);
+ }
+
+ final int areaAboveTarget = target.top;
+ final int areaBelowTarget = getHeight() - target.bottom;
+
+ if (areaAboveTarget >= childHeight) {
+ // enough room above target, place above and callout down
+ calloutState = android.R.attr.state_first;
+ childTop = target.top - childHeight;
+
+ } else if (areaBelowTarget >= childHeight) {
+ // enough room below target, place below and callout up
+ calloutState = android.R.attr.state_last;
+ childTop = target.bottom;
+ }
+
+ // when child is outside bounds, nudge back inside
+ childLeft = clampDimension(childLeft, childWidth, getWidth());
+ childTop = clampDimension(childTop, childHeight, getHeight());
+
+ final int calloutLeft = target.centerX() - childLeft;
+ updateCallout(calloutState, calloutLeft);
+ layoutChild(child, childLeft, childTop);
+
+ }
+
+ private static int clampDimension(int value, int size, int max) {
+ // when larger than bounds, just center
+ if (size > max) {
+ return (max - size) / 2;
+ }
+
+ // clamp to lower bound
+ value = Math.max(value, 0);
+ // clamp to higher bound
+ value = Math.min(value, max - size);
+
+ return value;
+ }
+
+ private static void layoutChild(View child, int left, int top) {
+ child.layout(left, top, left + child.getMeasuredWidth(), top + child.getMeasuredHeight());
+ }
+
+ /**
+ * Begin animating {@link #getChild()} visible.
+ */
+ public void showChild() {
+ final boolean calloutAbove = mCalloutState == android.R.attr.state_first;
+ final Animation anim = AnimationUtils.loadAnimation(getContext(),
+ calloutAbove ? R.anim.quickcontact_above_enter : R.anim.quickcontact_below_enter);
+ mChild.startAnimation(anim);
+ mChild.setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * Begin animating {@link #getChild()} invisible.
+ */
+ public void hideChild(final Runnable onAnimationEnd) {
+ final boolean calloutAbove = mCalloutState == android.R.attr.state_first;
+ final Animation anim = AnimationUtils.loadAnimation(getContext(),
+ calloutAbove ? R.anim.quickcontact_above_exit : R.anim.quickcontact_below_exit);
+
+ if (onAnimationEnd != null) {
+ anim.setAnimationListener(new AnimationListener() {
+ /** {@inheritDoc} */
+ public void onAnimationStart(Animation animation) {
+ // ignored
+ }
+
+ /** {@inheritDoc} */
+ public void onAnimationRepeat(Animation animation) {
+ // ignored
+ }
+
+ /** {@inheritDoc} */
+ public void onAnimationEnd(Animation animation) {
+ onAnimationEnd.run();
+ }
+ });
+ }
+
+ mChild.startAnimation(anim);
+ mChild.setVisibility(View.INVISIBLE);
+ }
+
+ private View.OnTouchListener mOutsideTouchListener;
+
+ public void setOnOutsideTouchListener(View.OnTouchListener listener) {
+ mOutsideTouchListener = listener;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // at this point, touch wasn't handled by child view; assume outside
+ if (mOutsideTouchListener != null) {
+ return mOutsideTouchListener.onTouch(this, event);
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
deleted file mode 100644
index 5032386..0000000
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.quickcontact;
-
-import com.android.contacts.ContactsActivity;
-
-import android.content.ContentUris;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract.QuickContact;
-import android.provider.ContactsContract.RawContacts;
-import android.util.Log;
-
-/**
- * Stub translucent activity that just shows {@link QuickContactWindow} floating
- * above the caller. This temporary hack should eventually be replaced with
- * direct framework support.
- */
-public final class QuickContactActivity extends ContactsActivity
- implements QuickContactWindow.OnDismissListener {
- private static final String TAG = "QuickContactActivity";
-
- static final boolean LOGV = false;
- static final boolean FORCE_CREATE = true;
-
- private QuickContactWindow mQuickContact;
-
- @Override
- protected void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- if (LOGV) Log.d(TAG, "onCreate");
-
- this.onNewIntent(getIntent());
- }
-
- @Override
- public void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- if (LOGV) Log.d(TAG, "onNewIntent");
-
- if (QuickContactWindow.TRACE_LAUNCH) {
- android.os.Debug.startMethodTracing(QuickContactWindow.TRACE_TAG);
- }
-
- if (mQuickContact == null || FORCE_CREATE) {
- if (LOGV) Log.d(TAG, "Preparing window");
- mQuickContact = new QuickContactWindow(this, this);
- }
-
- // Use our local window token for now
- Uri lookupUri = intent.getData();
- // Check to see whether it comes from the old version.
- if (android.provider.Contacts.AUTHORITY.equals(lookupUri.getAuthority())) {
- final long rawContactId = ContentUris.parseId(lookupUri);
- lookupUri = RawContacts.getContactLookupUri(getContentResolver(),
- ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
- }
- final Bundle extras = intent.getExtras();
-
- // Read requested parameters for displaying
- final Rect target = intent.getSourceBounds();
- final int mode = extras.getInt(QuickContact.EXTRA_MODE, QuickContact.MODE_MEDIUM);
- final String[] excludeMimes = extras.getStringArray(QuickContact.EXTRA_EXCLUDE_MIMES);
-
- mQuickContact.show(lookupUri, target, mode, excludeMimes);
- }
-
- /** {@inheritDoc} */
- @Override
- public void onBackPressed() {
- if (LOGV) Log.w(TAG, "Unexpected back captured by stub activity");
- finish();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- if (LOGV) Log.d(TAG, "onPause");
-
- // Dismiss any dialog when pausing
- mQuickContact.dismiss();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (LOGV) Log.d(TAG, "onDestroy");
- }
-
- /** {@inheritDoc} */
- @Override
- public void onDismiss(QuickContactWindow dialog) {
- if (LOGV) Log.d(TAG, "onDismiss");
-
- if (isTaskRoot() && !FORCE_CREATE) {
- // Instead of stopping, simply push this to the back of the stack.
- // This is only done when running at the top of the stack;
- // otherwise, we have been launched by someone else so need to
- // allow the user to go back to the caller.
- moveTaskToBack(false);
- } else {
- finish();
- }
- }
-}
diff --git a/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
index 9118480..15311f9 100644
--- a/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
+++ b/src/com/android/contacts/quickcontact/QuickContactBackgroundDrawable.java
@@ -26,37 +26,43 @@
import android.graphics.drawable.Drawable;
/**
- * Drawable that draws three pictures for the QuickContact-Background. ColorFilter is ignored
+ * Background {@link Drawable} for {@link QuickContactWindow} that draws arrow
+ * centered around requested position.
*/
public class QuickContactBackgroundDrawable extends Drawable {
private Drawable mLeftDrawable;
private Drawable mMiddleDrawable;
private Drawable mRightDrawable;
- private int mRequestedX = Integer.MIN_VALUE;
- private boolean mBoundsSet = false;
- private int mAlpha = -1;
+
private int mBottomOverride = Integer.MIN_VALUE;
+ public QuickContactBackgroundDrawable(Resources res) {
+ mLeftDrawable = res.getDrawable(R.drawable.quickactions_arrow_left_holo_light);
+ mMiddleDrawable = res.getDrawable(R.drawable.quickactions_arrow_middle_holo_light);
+ mRightDrawable = res.getDrawable(R.drawable.quickactions_arrow_right_holo_light);
+ }
+
@Override
public void setAlpha(int alpha) {
- mAlpha = alpha;
- setChildAlpha();
+ mLeftDrawable.setAlpha(alpha);
+ mMiddleDrawable.setAlpha(alpha);
+ mRightDrawable.setAlpha(alpha);
}
/**
- * Overrides the bottom bounds. This is used for the animation when the QuickContact
- * expands/collapses options
+ * Overrides the bottom bounds. This is used for the animation when the
+ * QuickContact expands/collapses options
*/
public void setBottomOverride(int value) {
mBottomOverride = value;
- setChildBounds();
+ onBoundsChange(getBounds());
invalidateSelf();
}
public void clearBottomOverride() {
mBottomOverride = Integer.MIN_VALUE;
+ onBoundsChange(getBounds());
invalidateSelf();
- setChildBounds();
}
public float getBottomOverride() {
@@ -64,7 +70,29 @@
}
@Override
+ public boolean isStateful() {
+ return true;
+ }
+
+ @Override
+ protected boolean onStateChange(int[] state) {
+ super.onStateChange(state);
+ mLeftDrawable.setState(state);
+ mMiddleDrawable.setState(state);
+ mRightDrawable.setState(state);
+ return true;
+ }
+
+ @Override
+ protected boolean onLevelChange(int level) {
+ return true;
+ }
+
+ @Override
public void setColorFilter(ColorFilter cf) {
+ mLeftDrawable.setColorFilter(cf);
+ mMiddleDrawable.setColorFilter(cf);
+ mRightDrawable.setColorFilter(cf);
}
@Override
@@ -72,54 +100,22 @@
return PixelFormat.TRANSLUCENT;
}
- public void configure(Resources resources, boolean arrowUp, int requestedX) {
- mLeftDrawable = resources.getDrawable(arrowUp
- ? R.drawable.quickactions_arrowup_left_holo_light
- : R.drawable.quickactions_arrowdown_left_holo_light);
- mMiddleDrawable = resources.getDrawable(arrowUp
- ? R.drawable.quickactions_arrowup_middle_holo_light
- : R.drawable.quickactions_arrowdown_middle_holo_light);
- mRightDrawable = resources.getDrawable(arrowUp
- ? R.drawable.quickactions_arrowup_right_holo_light
- : R.drawable.quickactions_arrowdown_right_holo_light);
-
- mRequestedX = requestedX;
-
- setChildAlpha();
- setChildBounds();
- }
-
@Override
protected void onBoundsChange(Rect bounds) {
- mBoundsSet = true;
- setChildBounds();
- }
+ final int requestedX = getLevel();
- private void setChildAlpha() {
- if (mAlpha == -1) return;
-
- if (mLeftDrawable != null) mLeftDrawable.setAlpha(mAlpha);
- if (mMiddleDrawable != null) mMiddleDrawable.setAlpha(mAlpha);
- if (mRightDrawable != null) mRightDrawable.setAlpha(mAlpha);
- }
-
- private void setChildBounds() {
- if (mRequestedX == Integer.MIN_VALUE) return;
- if (!mBoundsSet) return;
-
- final Rect bounds = getBounds();
- int middleLeft = mRequestedX - mMiddleDrawable.getIntrinsicWidth() / 2;
- int middleRight = mRequestedX + mMiddleDrawable.getIntrinsicWidth() / 2;
+ int middleLeft = requestedX - mMiddleDrawable.getIntrinsicWidth() / 2;
+ int middleRight = requestedX + mMiddleDrawable.getIntrinsicWidth() / 2;
// ensure left drawable is not smaller than its Intrinsic Width
- final int leftExtra = (middleLeft - bounds.left) - mLeftDrawable.getIntrinsicWidth();
+ final int leftExtra = (middleLeft - bounds.left) - mLeftDrawable.getIntrinsicWidth();
if (leftExtra < 0) {
middleLeft -= leftExtra;
middleRight -= leftExtra;
}
// ensure right drawable is not smaller than its Intrinsic Width
- final int rightExtra = (bounds.right - middleRight) - mRightDrawable.getIntrinsicWidth();
+ final int rightExtra = (bounds.right - middleRight) - mRightDrawable.getIntrinsicWidth();
if (rightExtra < 0) {
middleLeft += rightExtra;
middleRight += rightExtra;
diff --git a/src/com/android/contacts/quickcontact/QuickContactRootLayout.java b/src/com/android/contacts/quickcontact/QuickContactRootLayout.java
deleted file mode 100644
index 007783a..0000000
--- a/src/com/android/contacts/quickcontact/QuickContactRootLayout.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.quickcontact;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.widget.LinearLayout;
-
-/**
- * Custom layout for Quick Contact. It intercepts the BACK key and
- * close QC even when the soft keyboard is open.
- */
-public class QuickContactRootLayout extends LinearLayout {
- private Listener mListener;
-
- public QuickContactRootLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void setListener(Listener value) {
- mListener = value;
- }
-
- /**
- * Intercepts the BACK key event and dismisses QuickContact window.
- */
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- if (mListener != null) mListener.onBackPressed();
- return true;
- }
- return super.dispatchKeyEventPreIme(event);
- }
-
- public interface Listener {
- void onBackPressed();
- }
-}
diff --git a/src/com/android/contacts/quickcontact/QuickContactWindow.java b/src/com/android/contacts/quickcontact/QuickContactWindow.java
index 147e364..5f4bcc9 100644
--- a/src/com/android/contacts/quickcontact/QuickContactWindow.java
+++ b/src/com/android/contacts/quickcontact/QuickContactWindow.java
@@ -20,18 +20,20 @@
import com.android.contacts.ContactPresenceIconUtil;
import com.android.contacts.ContactSaveService;
import com.android.contacts.R;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.DataKind;
import com.android.contacts.util.Constants;
import com.android.contacts.util.DataStatus;
import com.android.contacts.util.NotifyingAsyncQueryHandler;
-import com.android.internal.policy.PolicyManager;
import com.google.android.collect.Lists;
+import com.google.common.base.Preconditions;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -41,6 +43,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -54,30 +57,16 @@
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
-import android.util.Log;
-import android.view.ActionMode;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewStub;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.FrameLayout;
-import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -88,72 +77,44 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
- * Window that shows QuickContact dialog for a specific {@link Contacts#_ID}.
+ * Mostly translucent {@link Activity} that shows QuickContact dialog. It loads
+ * data asynchronously, and then shows a popup with details centered around
+ * {@link Intent#getSourceBounds()}.
*/
-public class QuickContactWindow implements Window.Callback,
+public class QuickContactWindow extends Activity implements
NotifyingAsyncQueryHandler.AsyncQueryListener, View.OnClickListener,
- AbsListView.OnItemClickListener, KeyEvent.Callback, OnGlobalLayoutListener,
- QuickContactRootLayout.Listener {
+ AbsListView.OnItemClickListener {
+ private static final String TAG = "QuickContact";
- private static final String TAG = "QuickContactWindow";
+ private static final boolean TRACE_LAUNCH = false;
+ private static final String TRACE_TAG = "quickcontact";
- /**
- * Interface used to allow the person showing a {@link QuickContactWindow} to
- * know when the window has been dismissed.
- */
- public interface OnDismissListener {
- public void onDismiss(QuickContactWindow dialog);
- }
-
- private final static int ANIMATION_FADE_IN_TIME = 100;
- private final static int ANIMATION_FADE_OUT_TIME = 100;
- private final static int ANIMATION_EXPAND_TIME = 100;
- private final static int ANIMATION_COLLAPSE_TIME = 100;
-
- /**
- * If the anchor is wider than (quick contact width * this constant) then
- * center quick contact. Otherwise, left-align.
- */
- private static final double MIN_RELATIVE_ANCHOR_WIDTH_TO_CENTER = 0.5;
-
- private final Context mContext;
- private final LayoutInflater mInflater;
- private final WindowManager mWindowManager;
- private Window mWindow;
- private View mDecor;
- private final Rect mRect = new Rect();
-
- private boolean mDismissed = false;
- private boolean mQuerying = false;
- private boolean mShowing = false;
+ private static final int ANIMATION_FADE_IN_TIME = 100;
+ private static final int ANIMATION_FADE_OUT_TIME = 100;
+ private static final int ANIMATION_EXPAND_TIME = 100;
+ private static final int ANIMATION_COLLAPSE_TIME = 100;
private NotifyingAsyncQueryHandler mHandler;
- private OnDismissListener mDismissListener;
private Uri mLookupUri;
- private Rect mAnchor;
-
- private int mScreenWidth;
- private int mUseableScreenHeight;
- private int mRequestedY;
+ private int mMode;
+ private String[] mExcludeMimes;
private boolean mHasValidSocial = false;
- private int mMode;
- private QuickContactRootLayout mRootView;
+ private FloatingChildLayout mFloatingLayout;
private QuickContactBackgroundDrawable mBackground;
- private View mHeader;
- private HorizontalScrollView mTrackScroll;
- private ViewGroup mTrack;
+ private View mHeader;
+ private ViewGroup mTrack;
private FrameLayout mFooter;
private LinearLayout mFooterDisambig;
private LinearLayout mFooterClearDefaults;
+
private ListView mResolveList;
private CheckableImageView mLastAction;
private CheckBox mSetPrimaryCheckBox;
@@ -165,9 +126,6 @@
*/
private HashMap<String, Action> mDefaultsMap = new HashMap<String, Action>();
- private int mWindowRecycled = 0;
- private int mActionRecycled = 0;
-
/**
* Set of {@link Action} that are associated with the aggregate currently
* displayed by this dialog, represented as a map from {@link String}
@@ -176,14 +134,6 @@
private ActionMultiMap mActions = new ActionMultiMap();
/**
- * Pool of unused {@link CheckableImageView} that have previously been
- * inflated, and are ready to be recycled through {@link #obtainView()}.
- */
- private LinkedList<CheckableImageView> mActionPool = new LinkedList<CheckableImageView>();
-
- private String[] mExcludeMimes;
-
- /**
* {@link #PRECEDING_MIMETYPES} and {@link #FOLLOWING_MIMETYPES} are used to sort MIME-types.
*
* <p>The MIME-types in {@link #PRECEDING_MIMETYPES} appear in the front of the dialog,
@@ -221,82 +171,48 @@
});
private static final int TOKEN_DATA = 1;
- static final boolean TRACE_LAUNCH = false;
- static final String TRACE_TAG = "quickcontact";
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
- /**
- * Prepare a dialog to show in the given {@link Context}.
- */
- public QuickContactWindow(Context context) {
- mContext = new ContextThemeWrapper(context, R.style.QuickContact);
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ setContentView(R.layout.quickcontact_activity);
- mWindow = PolicyManager.makeNewWindow(mContext);
- mWindow.setCallback(this);
- mWindow.setWindowManager(mWindowManager, null, null);
- mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED);
+ mBackground = new QuickContactBackgroundDrawable(getResources());
- mWindow.setContentView(R.layout.quickcontact);
+ mFloatingLayout = findTypedViewById(R.id.floating_layout);
+ mFloatingLayout.getChild().setBackgroundDrawable(mBackground);
+ mFloatingLayout.setOnOutsideTouchListener(mOnOutsideTouchListener);
- mRootView = (QuickContactRootLayout)mWindow.findViewById(R.id.root);
- mRootView.setListener(this);
- mRootView.setFocusable(true);
- mRootView.setFocusableInTouchMode(true);
- mRootView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
+ mTrack = findTypedViewById(R.id.quickcontact);
+ mFooter = findTypedViewById(R.id.footer);
+ mFooterDisambig = findTypedViewById(R.id.footer_disambig);
+ mFooterClearDefaults = findTypedViewById(R.id.footer_clear_defaults);
+ mResolveList = findTypedViewById(android.R.id.list);
+ mSetPrimaryCheckBox = findTypedViewById(android.R.id.checkbox);
- mBackground = new QuickContactBackgroundDrawable();
- mRootView.setBackgroundDrawable(mBackground);
+ mDefaultsListView = findTypedViewById(R.id.defaults_list);
- mScreenWidth = mWindowManager.getDefaultDisplay().getWidth();
- // Status bar height
- final int screenMarginBottom = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.screen_margin_bottom);
- mUseableScreenHeight = mWindowManager.getDefaultDisplay().getHeight() - screenMarginBottom;
+ mClearDefaultsButton = findTypedViewById(R.id.clear_defaults_button);
+ mClearDefaultsButton.setOnClickListener(mOnClearDefaultsClickListener);
- mTrack = (ViewGroup) mWindow.findViewById(R.id.quickcontact);
- mTrackScroll = (HorizontalScrollView) mWindow.findViewById(R.id.scroll);
+ mResolveList.setOnItemClickListener(this);
- mFooter = (FrameLayout) mWindow.findViewById(R.id.footer);
- mFooterDisambig = (LinearLayout) mWindow.findViewById(R.id.footer_disambig);
- mFooterClearDefaults = (LinearLayout) mWindow.findViewById(R.id.footer_clear_defaults);
- mResolveList = (ListView) mWindow.findViewById(android.R.id.list);
- mSetPrimaryCheckBox = (CheckBox) mWindow.findViewById(android.R.id.checkbox);
+ mHandler = new NotifyingAsyncQueryHandler(this, this);
- mDefaultsListView = (ListView) mWindow.findViewById(R.id.defaults_list);
- mClearDefaultsButton = (Button) mWindow.findViewById(R.id.clear_defaults_button);
- mClearDefaultsButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- clearDefaults();
- }
- });
-
- mResolveList.setOnItemClickListener(QuickContactWindow.this);
-
- mHandler = new NotifyingAsyncQueryHandler(mContext, this);
- }
-
- /**
- * Prepare a dialog to show in the given {@link Context}, and notify the
- * given {@link OnDismissListener} each time this dialog is dismissed.
- */
- public QuickContactWindow(Context context, OnDismissListener dismissListener) {
- this(context);
- mDismissListener = dismissListener;
+ show();
}
private View getHeaderView(int mode) {
View header = null;
switch (mode) {
case QuickContact.MODE_SMALL:
- header = mWindow.findViewById(R.id.header_small);
+ header = findViewById(R.id.header_small);
break;
case QuickContact.MODE_MEDIUM:
- header = mWindow.findViewById(R.id.header_medium);
+ header = findViewById(R.id.header_medium);
break;
case QuickContact.MODE_LARGE:
- header = mWindow.findViewById(R.id.header_large);
+ header = findViewById(R.id.header_large);
break;
}
@@ -311,60 +227,52 @@
return header;
}
- /**
- * Start showing a dialog for the given {@link Contacts#_ID} pointing
- * towards the given location.
- */
- public synchronized void show(Uri lookupUri, Rect anchor, int mode, String[] excludeMimes) {
- if (mQuerying || mShowing) {
- Log.w(TAG, "dismissing before showing");
- dismissInternal();
- }
+ private void show() {
- if (TRACE_LAUNCH && !android.os.Debug.isMethodTracingActive()) {
+ if (TRACE_LAUNCH) {
android.os.Debug.startMethodTracing(TRACE_TAG);
}
- // Validate incoming parameters
- final boolean validMode = (mode == QuickContact.MODE_SMALL
- || mode == QuickContact.MODE_MEDIUM || mode == QuickContact.MODE_LARGE);
- if (!validMode) {
- throw new IllegalArgumentException("Invalid mode, expecting MODE_LARGE, "
- + "MODE_MEDIUM, or MODE_SMALL");
+ final Intent intent = getIntent();
+
+ Uri lookupUri = intent.getData();
+
+ // Check to see whether it comes from the old version.
+ if (android.provider.Contacts.AUTHORITY.equals(lookupUri.getAuthority())) {
+ final long rawContactId = ContentUris.parseId(lookupUri);
+ lookupUri = RawContacts.getContactLookupUri(getContentResolver(),
+ ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
}
- if (anchor == null) {
- throw new IllegalArgumentException("Missing anchor rectangle");
+ mLookupUri = Preconditions.checkNotNull(lookupUri, "missing lookupUri");
+
+ // Read requested parameters for displaying
+ final Rect targetScreen = intent.getSourceBounds();
+ Preconditions.checkNotNull(targetScreen, "missing targetScreen");
+ mFloatingLayout.setChildTargetScreen(targetScreen);
+
+ mMode = intent.getIntExtra(QuickContact.EXTRA_MODE, QuickContact.MODE_MEDIUM);
+ mExcludeMimes = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
+
+ switch (mMode) {
+ case QuickContact.MODE_SMALL:
+ case QuickContact.MODE_MEDIUM:
+ case QuickContact.MODE_LARGE:
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected mode: " + mMode);
}
- // Prepare header view for requested mode
- mLookupUri = lookupUri;
- mAnchor = new Rect(anchor);
- mMode = mode;
- mExcludeMimes = excludeMimes;
-
- mHeader = getHeaderView(mode);
-
+ // find and prepare correct header view
+ mHeader = getHeaderView(mMode);
setHeaderText(R.id.name, R.string.quickcontact_missing_name);
-
setHeaderText(R.id.status, null);
setHeaderText(R.id.timestamp, null);
-
setHeaderImage(R.id.presence, null);
- resetTrack();
-
- // We need to have a focused view inside the QuickContact window so
- // that the BACK key event can be intercepted
- mRootView.requestFocus();
-
- mHasValidSocial = false;
- mDismissed = false;
- mQuerying = true;
-
// Start background query for data, but only select photo rows when they
// directly match the super-primary PHOTO_ID.
- final Uri dataUri = getDataUri(lookupUri);
+ final Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
mHandler.cancelOperation(TOKEN_DATA);
// Only request photo data when required by mode
@@ -380,222 +288,85 @@
}
}
- /**
- * Build a {@link Uri} into the {@link Data} table for the requested
- * {@link Contacts#CONTENT_LOOKUP_URI} style {@link Uri}.
- */
- private Uri getDataUri(Uri lookupUri) {
- return Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
+ @SuppressWarnings("unchecked")
+ private <T> T findTypedViewById(int id) {
+ return (T) super.findViewById(id);
}
- /**
- * Creates and configures the background resource
- */
- private void configureBackground(boolean arrowUp, int requestedX) {
- mBackground.configure(mContext.getResources(), arrowUp, requestedX);
+ private View.OnTouchListener mOnOutsideTouchListener = new View.OnTouchListener() {
+ /** {@inheritDoc} */
+ public boolean onTouch(View v, MotionEvent event) {
+ hide(true);
+ return true;
+ }
+ };
+
+ private View.OnClickListener mOnClearDefaultsClickListener = new View.OnClickListener() {
+ /** {@inheritDoc} */
+ public void onClick(View v) {
+ clearDefaults();
+ }
+ };
+
+ private void hide(boolean withAnimation) {
+ // cancel any pending queries
+ mHandler.cancelOperation(TOKEN_DATA);
+
+ if (withAnimation) {
+ mFloatingLayout.hideChild(new Runnable() {
+ /** {@inheritDoc} */
+ public void run() {
+ finish();
+ }
+ });
+ } else {
+ mFloatingLayout.hideChild(null);
+ finish();
+ }
}
- /**
- * Actual internal method to show this dialog. Called only by
- * {@link #considerShowing()} when all data requirements have been met.
- */
- private void showInternal() {
- mDecor = mWindow.getDecorView();
- mDecor.getViewTreeObserver().addOnGlobalLayoutListener(this);
- WindowManager.LayoutParams layoutParams = mWindow.getAttributes();
-
- layoutParams.width = mContext.getResources().getDimensionPixelSize(
- R.dimen.quick_contact_width);
- layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
-
- // Try to left align with the anchor control or center if the anchor is wide
- if (mAnchor.left + layoutParams.width <= mScreenWidth) {
- if (mAnchor.width() > layoutParams.width * MIN_RELATIVE_ANCHOR_WIDTH_TO_CENTER) {
- layoutParams.x = mAnchor.left + (mAnchor.width() - layoutParams.width) / 2;
- } else {
- layoutParams.x = mAnchor.left;
- }
- } else {
- // Not enough space. Try to right align to the anchor
- if (mAnchor.right - layoutParams.width >= 0) {
- layoutParams.x = mAnchor.right - layoutParams.width;
- } else {
- // Also not enough space. Use the whole screen width available
- layoutParams.x = 0;
- layoutParams.width = mScreenWidth;
- }
- }
-
- // Force layout measuring pass so we have baseline numbers
- mDecor.measure(layoutParams.width, layoutParams.height);
- final int blockHeight = mDecor.getMeasuredHeight();
-
- layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
-
- if (mUseableScreenHeight - mAnchor.bottom > blockHeight) {
- // Show downwards callout when enough room, aligning block top with bottom of
- // anchor area, and adjusting to inset arrow.
- configureBackground(true, mAnchor.centerX() - layoutParams.x);
- layoutParams.y = mAnchor.bottom;
- layoutParams.windowAnimations = R.style.QuickContactBelowAnimation;
- } else {
- // Show upwards callout, aligning bottom block
- // edge with top of anchor area, and adjusting to inset arrow.
- configureBackground(false, mAnchor.centerX() - layoutParams.x);
- layoutParams.y = mAnchor.top - blockHeight;
- layoutParams.windowAnimations = R.style.QuickContactAboveAnimation;
- }
-
- layoutParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
-
- mRequestedY = layoutParams.y;
- mWindowManager.addView(mDecor, layoutParams);
- mShowing = true;
- mQuerying = false;
- mDismissed = false;
-
- if (TRACE_LAUNCH) {
- android.os.Debug.stopMethodTracing();
- Log.d(TAG, "Window recycled " + mWindowRecycled + " times, chiclets "
- + mActionRecycled + " times");
- }
+ @Override
+ public void onBackPressed() {
+ hide(true);
}
/** {@inheritDoc} */
- @Override
- public void onGlobalLayout() {
- layoutInScreen();
- }
+ public synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ try {
+ if (isFinishing()) {
+ hide(false);
+ return;
+ } else if (cursor == null || cursor.getCount() == 0) {
+ Toast.makeText(this, R.string.invalidContactMessage, Toast.LENGTH_LONG).show();
+ hide(false);
+ return;
+ }
- /**
- * Adjust vertical {@link WindowManager.LayoutParams} to fit window as best
- * as possible, shifting up to display content as needed.
- */
- private void layoutInScreen() {
- if (!mShowing) return;
+ bindData(cursor);
- final WindowManager.LayoutParams l = mWindow.getAttributes();
- final int originalY = l.y;
-
- final int blockHeight = mDecor.getHeight();
-
- l.y = mRequestedY;
- if (mRequestedY + blockHeight > mUseableScreenHeight) {
- // Shift up from bottom when overflowing
- l.y = mUseableScreenHeight - blockHeight;
- }
-
- if (originalY != l.y) {
- // Only update when value is changed
- mWindow.setAttributes(l);
- }
- }
-
- /**
- * Dismiss this dialog if showing.
- */
- public synchronized void dismiss() {
- // Notify any listeners that we've been dismissed
- if (mDismissListener != null) {
- mDismissListener.onDismiss(this);
- }
-
- dismissInternal();
- }
-
- private void dismissInternal() {
- // Remove any attached window decor for recycling
- boolean hadDecor = mDecor != null;
- if (hadDecor) {
- mWindowManager.removeView(mDecor);
- mWindowRecycled++;
- mDecor.getViewTreeObserver().removeGlobalOnLayoutListener(this);
- mDecor = null;
- mWindow.closeAllPanels();
- }
- mShowing = false;
- mDismissed = true;
-
- // Cancel any pending queries
- mHandler.cancelOperation(TOKEN_DATA);
- mQuerying = false;
-
- // Completely hide header and reset track
- mHeader.setVisibility(View.GONE);
- resetTrack();
- }
-
- /**
- * Reset track to initial state, recycling any chiclets.
- */
- private void resetTrack() {
- // Clear background height-animation override
- mBackground.clearBottomOverride();
-
- // Release reference to last chiclet
- mLastAction = null;
-
- // Clear track actions and scroll to hard left
- mActions.clear();
-
- // Recycle any chiclets in use
- for (int i = mTrack.getChildCount() - 1; i >= 0; i--) {
- releaseView((CheckableImageView)mTrack.getChildAt(i));
- mTrack.removeViewAt(i);
- }
-
- mTrackScroll.fullScroll(View.FOCUS_LEFT);
-
- // Clear any primary requests
- mSetPrimaryCheckBox.setChecked(false);
-
- setNewActionViewChecked(null);
- mFooter.setVisibility(View.GONE);
- }
-
- /**
- * Consider showing this window, which will only call through to
- * {@link #showInternal()} when all data items are present.
- */
- private void considerShowing() {
- if (!mShowing && !mDismissed) {
if (mMode == QuickContact.MODE_MEDIUM && !mHasValidSocial) {
// Missing valid social, swap medium for small header
mHeader.setVisibility(View.GONE);
mHeader = getHeaderView(QuickContact.MODE_SMALL);
}
- // All queries have returned, pull curtain
- showInternal();
+ if (TRACE_LAUNCH) {
+ android.os.Debug.stopMethodTracing();
+ }
+
+ // data bound and ready, pull curtain to show
+ mFloatingLayout.showChild();
+
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
}
- /** {@inheritDoc} */
- @Override
- public synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
- // Bail early when query is stale
- if (cookie != mLookupUri) return;
-
- if (cursor == null) {
- // Problem while running query, so bail without showing
- Log.w(TAG, "Missing cursor for token=" + token);
- this.dismiss();
- return;
- }
-
- handleData(cursor);
-
- if (!cursor.isClosed()) {
- cursor.close();
- }
-
- considerShowing();
- }
-
/** Assign this string to the view, if found in {@link #mHeader}. */
private void setHeaderText(int id, int resId) {
- setHeaderText(id, mContext.getResources().getText(resId));
+ setHeaderText(id, getText(resId));
}
/** Assign this string to the view, if found in {@link #mHeader}. */
@@ -633,26 +404,22 @@
/**
* Handle the result from the {@link #TOKEN_DATA} query.
*/
- private void handleData(Cursor cursor) {
- final ResolveCache cache = ResolveCache.getInstance(mContext);
- if (cursor == null) return;
- if (cursor.getCount() == 0) {
- Toast.makeText(mContext, R.string.invalidContactMessage, Toast.LENGTH_LONG).show();
- dismiss();
- return;
- }
+ private void bindData(Cursor cursor) {
+ final ResolveCache cache = ResolveCache.getInstance(this);
+ final Context context = this;
if (!isMimeExcluded(Contacts.CONTENT_ITEM_TYPE)) {
// Add the profile shortcut action
- final Action action = new ProfileAction(mContext, mLookupUri);
+ final Action action = new ProfileAction(context, mLookupUri);
mActions.put(Contacts.CONTENT_ITEM_TYPE, action);
}
mDefaultsMap.clear();
final DataStatus status = new DataStatus();
- final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mContext);
- final ImageView photoView = (ImageView)mHeader.findViewById(R.id.photo);
+ final AccountTypeManager accountTypes = AccountTypeManager.getInstance(
+ context.getApplicationContext());
+ final ImageView photoView = (ImageView) mHeader.findViewById(R.id.photo);
Bitmap photoBitmap = null;
while (cursor.moveToNext()) {
@@ -684,7 +451,7 @@
// Build an action for this data entry, find a mapping to a UI
// element, build its summary from the cursor, and collect it
// along with all others of this MIME-type.
- final Action action = new DataAction(mContext, mimeType, kind, dataId, cursor);
+ final Action action = new DataAction(context, mimeType, kind, dataId, cursor);
final boolean wasAdded = considerAdd(action, cache);
if (wasAdded) {
// Remember the default
@@ -696,7 +463,7 @@
// If phone number, also insert as text message action
if (Phone.CONTENT_ITEM_TYPE.equals(mimeType) && kind != null) {
- final DataAction action = new DataAction(mContext, Constants.MIME_TYPE_SMS_ADDRESS,
+ final DataAction action = new DataAction(context, Constants.MIME_TYPE_SMS_ADDRESS,
kind, dataId, cursor);
considerAdd(action, cache);
}
@@ -709,7 +476,7 @@
final DataKind imKind = accountTypes.getKindOrFallback(accountType,
Im.CONTENT_ITEM_TYPE);
if (imKind != null) {
- final DataAction action = new DataAction(mContext, Im.CONTENT_ITEM_TYPE, imKind,
+ final DataAction action = new DataAction(context, Im.CONTENT_ITEM_TYPE, imKind,
dataId, cursor);
considerAdd(action, cache);
isIm = true;
@@ -722,7 +489,7 @@
final DataKind imKind = accountTypes.getKindOrFallback(accountType,
Im.CONTENT_ITEM_TYPE);
if (imKind != null) {
- final DataAction chatAction = new DataAction(mContext,
+ final DataAction chatAction = new DataAction(context,
Constants.MIME_TYPE_VIDEO_CHAT, imKind, dataId, cursor);
considerAdd(chatAction, cache);
}
@@ -730,6 +497,11 @@
}
}
+ // Collapse Action Lists (remove e.g. duplicate e-mail addresses from different sources)
+ for (ArrayList<Action> actionChildren : mActions.values()) {
+ Collapser.collapseList(actionChildren);
+ }
+
// Make sure that we only display the "clear default" action if there
// are actually several items to chose from
boolean shouldDisplayClearDefaults = false;
@@ -751,7 +523,7 @@
final int presence = cursor.getInt(DataQuery.CONTACT_PRESENCE);
final int chatCapability = cursor.getInt(DataQuery.CONTACT_CHAT_CAPABILITY);
final Drawable statusIcon = ContactPresenceIconUtil.getChatCapabilityIcon(
- mContext, presence, chatCapability);
+ context, presence, chatCapability);
setHeaderText(R.id.name, name);
setHeaderImage(R.id.presence, statusIcon);
@@ -767,7 +539,7 @@
if (mHasValidSocial && mMode != QuickContact.MODE_SMALL) {
// Update status when valid was found
setHeaderText(R.id.status, status.getStatus());
- setHeaderText(R.id.timestamp, status.getTimestampLabel(mContext));
+ setHeaderText(R.id.timestamp, status.getTimestampLabel(context));
}
// Turn our list of actions into UI elements
@@ -781,7 +553,7 @@
for (String mimeType : PRECEDING_MIMETYPES) {
if (containedTypes.contains(mimeType)) {
hasData = true;
- mTrack.addView(inflateAction(mimeType, cache));
+ mTrack.addView(inflateAction(mimeType, cache, mTrack));
containedTypes.remove(mimeType);
}
}
@@ -793,7 +565,7 @@
for (String mimeType : FOLLOWING_MIMETYPES) {
if (containedTypes.contains(mimeType)) {
hasData = true;
- mTrack.addView(inflateAction(mimeType, cache));
+ mTrack.addView(inflateAction(mimeType, cache, mTrack));
containedTypes.remove(mimeType);
}
}
@@ -802,9 +574,11 @@
if (containedTypes.contains(ClearDefaultsAction.PSEUDO_MIME_TYPE)) {
final ClearDefaultsAction action = (ClearDefaultsAction) mActions.get(
ClearDefaultsAction.PSEUDO_MIME_TYPE).get(0);
- final CheckableImageView view = obtainView();
+ final CheckableImageView view = (CheckableImageView) getLayoutInflater().inflate(
+ R.layout.quickcontact_item, mTrack, false);
+
view.setChecked(false);
- final String description = mContext.getResources().getString(
+ final String description = context.getResources().getString(
R.string.quickcontact_clear_defaults_description);
view.setContentDescription(description);
view.setImageResource(R.drawable.ic_menu_settings_holo_light);
@@ -820,12 +594,13 @@
if (remainingTypes.length > 0) hasData = true;
Arrays.sort(remainingTypes);
for (String mimeType : remainingTypes) {
- mTrack.addView(inflateAction(mimeType, cache), index++);
+ mTrack.addView(inflateAction(mimeType, cache, mTrack), index++);
}
if (!hasData) {
// When there is no data to display, add a TextView to show the user there's no data
- View view = mInflater.inflate(R.layout.quickcontact_item_nodata, mTrack, false);
+ View view = getLayoutInflater().inflate(
+ R.layout.quickcontact_item_nodata, mTrack, false);
mTrack.addView(view, index++);
}
}
@@ -834,7 +609,9 @@
* Clears the defaults currently set on the Contact
*/
private void clearDefaults() {
+ final Context context = this;
final Set<String> mimeTypesKeySet = mDefaultsMap.keySet();
+
// Copy to array so that we can modify the HashMap below
final String[] mimeTypes = new String[mimeTypesKeySet.size()];
mimeTypesKeySet.toArray(mimeTypes);
@@ -842,9 +619,9 @@
// Send clear default Intents, one by one
for (String mimeType : mimeTypes) {
final Action action = mDefaultsMap.get(mimeType);
- final Intent intent =
- ContactSaveService.createClearPrimaryIntent(mContext, action.getDataId());
- mContext.startService(intent);
+ final Intent intent = ContactSaveService.createClearPrimaryIntent(
+ context, action.getDataId());
+ context.startService(intent);
mDefaultsMap.remove(mimeType);
}
@@ -855,7 +632,6 @@
for (int i = mTrack.getChildCount() - 1; i >= 0; i--) {
final CheckableImageView button = (CheckableImageView) mTrack.getChildAt(i);
if (button.getTag() instanceof ClearDefaultsAction) {
- releaseView(button);
mTrack.removeViewAt(i);
break;
}
@@ -879,41 +655,15 @@
}
/**
- * Obtain a new {@link CheckableImageView} for a new chiclet, either by
- * recycling one from {@link #mActionPool}, or by inflating a new one. When
- * finished, use {@link #releaseView(CheckableImageView)} to return back into the pool for
- * later recycling.
- */
- private synchronized CheckableImageView obtainView() {
- CheckableImageView view = mActionPool.poll();
- if (view == null || QuickContactActivity.FORCE_CREATE) {
- view = (CheckableImageView) mInflater.inflate(R.layout.quickcontact_item, mTrack,
- false);
- }
- return view;
- }
-
- /**
- * Return the given {@link CheckableImageView} into our internal pool for
- * possible recycling during another pass.
- */
- private synchronized void releaseView(CheckableImageView view) {
- mActionPool.offer(view);
- mActionRecycled++;
- }
-
- /**
* Inflate the in-track view for the action of the given MIME-type, collapsing duplicate values.
* Will use the icon provided by the {@link DataKind}.
*/
- private View inflateAction(String mimeType, ResolveCache resolveCache) {
- final CheckableImageView view = obtainView();
+ private View inflateAction(String mimeType, ResolveCache resolveCache, ViewGroup root) {
+ final CheckableImageView view = (CheckableImageView) getLayoutInflater().inflate(
+ R.layout.quickcontact_item, root, false);
// Add direct intent if single child, otherwise flag for multiple
List<Action> children = mActions.get(mimeType);
- if (children.size() > 1) {
- Collapser.collapseList(children);
- }
view.setTag(mimeType);
final Action firstInfo = children.get(0);
@@ -990,6 +740,13 @@
expandAnimator.setDuration(ANIMATION_EXPAND_TIME);
expandAnimator.start();
+ expandAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBackground.clearBottomOverride();
+ }
+ });
+
final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(mFooter,
"alpha", 0.0f, 1.0f);
fadeInAnimator.setDuration(ANIMATION_FADE_IN_TIME);
@@ -1002,9 +759,12 @@
/** {@inheritDoc} */
@Override
public void onClick(View view) {
+ final Context context = this;
+
final boolean isActionView = (view instanceof CheckableImageView);
final CheckableImageView actionView = isActionView ? (CheckableImageView)view : null;
final Object tag = view.getTag();
+
if (tag instanceof ClearDefaultsAction) {
// Do nothing if already open
if (actionView == mLastAction) return;
@@ -1045,29 +805,28 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- final View result = convertView != null ? convertView :
- mInflater.inflate(R.layout.quickcontact_default_item,
- parent, false);
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(
+ R.layout.quickcontact_default_item, parent, false);
+ }
+
// Set action title based on summary value
final Action defaultAction = actions[position];
- TextView text1 = (TextView)result.findViewById(android.R.id.text1);
- TextView text2 = (TextView)result.findViewById(android.R.id.text2);
+ final TextView text1 = (TextView) convertView.findViewById(
+ android.R.id.text1);
+ final TextView text2 = (TextView) convertView.findViewById(
+ android.R.id.text2);
text1.setText(defaultAction.getHeader());
text2.setText(defaultAction.getBody());
- result.setTag(defaultAction);
- return result;
+ convertView.setTag(defaultAction);
+ return convertView;
}
});
animateExpand(true);
- // Make sure we resize to make room for ListView
- if (mDecor != null) {
- mDecor.forceLayout();
- mDecor.invalidate();
- }
}
};
if (mFooter.getVisibility() == View.VISIBLE) {
@@ -1116,24 +875,24 @@
public void run() {
// Incoming tag is concrete intent, so try launching
try {
- mContext.startActivity(action.getIntent());
+ context.startActivity(action.getIntent());
} catch (ActivityNotFoundException e) {
- Toast.makeText(mContext, R.string.quickcontact_missing_app,
+ Toast.makeText(context, R.string.quickcontact_missing_app,
Toast.LENGTH_SHORT).show();
}
// Hide the resolution list, if present
setNewActionViewChecked(null);
- dismiss();
- mFooter.setVisibility(View.GONE);
// Set default?
final long dataId = action.getDataId();
if (makePrimary && dataId != -1) {
Intent serviceIntent = ContactSaveService.createSetSuperPrimaryIntent(
- mContext, dataId);
- mContext.startService(serviceIntent);
+ context, dataId);
+ context.startService(serviceIntent);
}
+
+ hide(false);
}
};
if (isActionView && mFooter.getVisibility() == View.VISIBLE) {
@@ -1178,31 +937,31 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
- final View result = convertView != null ? convertView :
- mInflater.inflate(R.layout.quickcontact_resolve_item,
- parent, false);
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(
+ R.layout.quickcontact_resolve_item, parent, false);
+ }
+
// Set action title based on summary value
final Action listAction = actionList.get(position);
- TextView text1 = (TextView)result.findViewById(android.R.id.text1);
- TextView text2 = (TextView)result.findViewById(android.R.id.text2);
+ final TextView text1 = (TextView) convertView.findViewById(
+ android.R.id.text1);
+ final TextView text2 = (TextView) convertView.findViewById(
+ android.R.id.text2);
text1.setText(listAction.getHeader());
text2.setText(listAction.getBody());
- result.setTag(listAction);
- return result;
+ convertView.setTag(listAction);
+ return convertView;
}
});
animateExpand(false);
- // Make sure we resize to make room for ListView
- if (mDecor != null) {
- mDecor.forceLayout();
- mDecor.invalidate();
- }
}
};
+
if (mFooter.getVisibility() == View.VISIBLE) {
// If the expansion list is currently opened, animate its collapse and then
// execute the target app
@@ -1213,191 +972,6 @@
}
}
- @Override
- public void onBackPressed() {
- dismiss();
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (mWindow.superDispatchKeyEvent(event)) {
- return true;
- }
- return event.dispatch(this, mDecor != null
- ? mDecor.getKeyDispatcherState() : null, this);
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- event.startTracking();
- return true;
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
- && !event.isCanceled()) {
- onBackPressed();
- return true;
- }
-
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
- return false;
- }
-
- /** {@inheritDoc} */
- public boolean dispatchKeyShortcutEvent(KeyEvent event) {
- return mWindow.superDispatchKeyShortcutEvent(event);
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- // TODO: make this window accessible
- return false;
- }
-
- /**
- * Detect if the given {@link MotionEvent} is outside the boundaries of this
- * window, which usually means we should dismiss.
- */
- protected void detectEventOutside(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN && mDecor != null) {
- // Only try detecting outside events on down-press
- mDecor.getHitRect(mRect);
- final int x = (int)event.getX();
- final int y = (int)event.getY();
- if (!mRect.contains(x, y)) {
- event.setAction(MotionEvent.ACTION_OUTSIDE);
- }
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- detectEventOutside(event);
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- dismiss();
- return true;
- }
- return mWindow.superDispatchTouchEvent(event);
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean dispatchTrackballEvent(MotionEvent event) {
- return mWindow.superDispatchTrackballEvent(event);
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean dispatchGenericMotionEvent(MotionEvent event) {
- return mWindow.superDispatchGenericMotionEvent(event);
- }
-
- /** {@inheritDoc} */
- @Override
- public void onContentChanged() {
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onCreatePanelMenu(int featureId, Menu menu) {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public View onCreatePanelView(int featureId) {
- return null;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onMenuOpened(int featureId, Menu menu) {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public void onPanelClosed(int featureId, Menu menu) {
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onPreparePanel(int featureId, View view, Menu menu) {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public boolean onSearchRequested() {
- return false;
- }
-
- /** {@inheritDoc} */
- @Override
- public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams attrs) {
- if (mDecor != null) {
- mWindowManager.updateViewLayout(mDecor, attrs);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- }
-
- /** {@inheritDoc} */
- @Override
- public void onAttachedToWindow() {
- // No actions
- }
-
- /** {@inheritDoc} */
- @Override
- public void onDetachedFromWindow() {
- // No actions
- }
-
- /** {@inheritDoc} */
- @Override
- public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
- return null;
- }
-
- @Override
- public void onActionModeStarted(ActionMode mode) {
- }
-
- @Override
- public void onActionModeFinished(ActionMode mode) {
- }
private interface DataQuery {
final String[] PROJECTION = new String[] {
diff --git a/src/com/android/contacts/util/NotifyingAsyncQueryHandler.java b/src/com/android/contacts/util/NotifyingAsyncQueryHandler.java
index 83fae29..c8cfc8d 100644
--- a/src/com/android/contacts/util/NotifyingAsyncQueryHandler.java
+++ b/src/com/android/contacts/util/NotifyingAsyncQueryHandler.java
@@ -29,8 +29,6 @@
* <p>
* This pattern can be used to perform background queries without leaking
* {@link Context} objects.
- *
- * @hide pending API council review
*/
public class NotifyingAsyncQueryHandler extends AsyncQueryHandler {
private WeakReference<AsyncQueryListener> mListener;
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
index 23319aa..d3a8060 100644
--- a/src/com/android/contacts/util/PhoneCapabilityTester.java
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -16,6 +16,8 @@
package com.android.contacts.util;
+import com.android.contacts.R;
+
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -79,4 +81,12 @@
Uri.fromParts(Constants.SCHEME_SMSTO, "", null));
return isIntentRegistered(context, intent);
}
+
+ /**
+ * True if we are using two-pane layouts ("tablet mode"), false if we are using single views
+ * ("phone mode")
+ */
+ public static boolean isUsingTwoPanes(Context context) {
+ return context.getResources().getBoolean(R.bool.config_use_two_panes);
+ }
}
diff --git a/src/com/android/contacts/vcard/ExportProcessor.java b/src/com/android/contacts/vcard/ExportProcessor.java
index 67c9c4a..7b5e001 100644
--- a/src/com/android/contacts/vcard/ExportProcessor.java
+++ b/src/com/android/contacts/vcard/ExportProcessor.java
@@ -22,18 +22,22 @@
import android.app.Notification;
import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContactsEntity;
import android.text.TextUtils;
import android.util.Log;
-import android.widget.RemoteViews;
+import java.io.BufferedWriter;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
/**
* Class for processing one export request from a user. Dropped after exporting requested Uri(s).
@@ -92,6 +96,7 @@
if (DEBUG) Log.d(LOG_TAG, String.format("vCard export (id: %d) has started.", mJobId));
final ExportRequest request = mExportRequest;
VCardComposer composer = null;
+ Writer writer = null;
boolean successful = false;
try {
if (isCancelled()) {
@@ -129,9 +134,14 @@
// VCardConfig.FLAG_USE_QP_TO_PRIMARY_PROPERTIES);
// composer = new VCardComposer(ExportVCardActivity.this, vcardType, true);
- composer.addHandler(composer.new HandlerForOutputStream(outputStream));
-
- if (!composer.init()) {
+ writer = new BufferedWriter(new OutputStreamWriter(outputStream));
+ final Uri contentUriForRawContactsEntity = RawContactsEntity.CONTENT_URI.buildUpon()
+ .appendQueryParameter(RawContactsEntity.FOR_EXPORT_ONLY, "1")
+ .build();
+ // TODO: should provide better selection.
+ if (!composer.init(Contacts.CONTENT_URI, new String[] {Contacts._ID},
+ null, null,
+ null, contentUriForRawContactsEntity)) {
final String errorReason = composer.getErrorReason();
Log.e(LOG_TAG, "initialization of vCard composer failed: " + errorReason);
final String translatedErrorReason =
@@ -157,7 +167,9 @@
Log.i(LOG_TAG, "Export request is cancelled during composing vCard");
return;
}
- if (!composer.createOneEntry()) {
+ try {
+ writer.write(composer.createOneEntry());
+ } catch (IOException e) {
final String errorReason = composer.getErrorReason();
Log.e(LOG_TAG, "Failed to read a contact: " + errorReason);
final String translatedErrorReason =
@@ -192,7 +204,13 @@
if (composer != null) {
composer.terminate();
}
-
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {
+ Log.w(LOG_TAG, "IOException is thrown during close(). Ignored. " + e);
+ }
+ }
mService.handleFinishExportNotification(mJobId, successful);
}
}
diff --git a/src/com/android/contacts/vcard/ImportVCardActivity.java b/src/com/android/contacts/vcard/ImportVCardActivity.java
index b3376e9..17b89c3 100644
--- a/src/com/android/contacts/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/vcard/ImportVCardActivity.java
@@ -21,7 +21,6 @@
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.util.AccountSelectionUtil;
import com.android.vcard.VCardEntryCounter;
-import com.android.vcard.VCardInterpreterCollection;
import com.android.vcard.VCardParser;
import com.android.vcard.VCardParser_V21;
import com.android.vcard.VCardParser_V30;
@@ -399,7 +398,6 @@
final ContentResolver resolver = ImportVCardActivity.this.getContentResolver();
VCardEntryCounter counter = null;
VCardSourceDetector detector = null;
- VCardInterpreterCollection interpreter = null;
int vcardVersion = VCARD_VERSION_V21;
try {
boolean shouldUseV30 = false;
@@ -408,9 +406,9 @@
try {
counter = new VCardEntryCounter();
detector = new VCardSourceDetector();
- interpreter = new VCardInterpreterCollection(
- Arrays.asList(counter, detector));
- mVCardParser.parse(is, interpreter);
+ mVCardParser.addInterpreter(counter);
+ mVCardParser.addInterpreter(detector);
+ mVCardParser.parse(is);
} catch (VCardVersionException e1) {
try {
is.close();
@@ -423,9 +421,9 @@
try {
counter = new VCardEntryCounter();
detector = new VCardSourceDetector();
- interpreter = new VCardInterpreterCollection(
- Arrays.asList(counter, detector));
- mVCardParser.parse(is, interpreter);
+ mVCardParser.addInterpreter(counter);
+ mVCardParser.addInterpreter(detector);
+ mVCardParser.parse(is);
} catch (VCardVersionException e2) {
throw new VCardException("vCard with unspported version.");
}
diff --git a/tests/res/values/donottranslate_strings.xml b/tests/res/values/donottranslate_strings.xml
index 8557fd6..bd272c3 100644
--- a/tests/res/values/donottranslate_strings.xml
+++ b/tests/res/values/donottranslate_strings.xml
@@ -32,6 +32,7 @@
<item>ACTION_PICK: phone (legacy)</item>
<item>ACTION_PICK: postal</item>
<item>ACTION_PICK: postal (legacy)</item>
+ <item>ACTION_PICK: e-mail</item>
<item>ACTION_CREATE_SHORTCUT: contact</item>
<item>ACTION_CREATE_SHORTCUT: dial</item>
<item>ACTION_CREATE_SHORTCUT: message</item>
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index 4acaa92..389041a 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -21,9 +21,9 @@
import static android.content.ContentProviderOperation.TYPE_UPDATE;
import com.android.contacts.model.AccountType;
-import com.android.contacts.model.AccountType.DataKind;
import com.android.contacts.model.AccountType.EditType;
import com.android.contacts.model.AccountTypeManager;
+import com.android.contacts.model.DataKind;
import com.android.contacts.model.EntityDelta;
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.android.contacts.model.EntityDeltaList;
@@ -81,45 +81,50 @@
MockContactsSource() {
this.accountType = TEST_ACCOUNT_TYPE;
+ final DataKind nameKind = new DataKind(StructuredName.CONTENT_ITEM_TYPE,
+ R.string.nameLabelsGroup, -1, -1, true);
+ nameKind.typeOverallMax = 1;
+ addKind(nameKind);
+
// Phone allows maximum 2 home, 1 work, and unlimited other, with
// constraint of 5 numbers maximum.
- DataKind kind = new DataKind(Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+ final DataKind phoneKind = new DataKind(Phone.CONTENT_ITEM_TYPE, -1, -1, 10, true);
- kind.typeOverallMax = 5;
- kind.typeColumn = Phone.TYPE;
- kind.typeList = Lists.newArrayList();
- kind.typeList.add(new EditType(Phone.TYPE_HOME, -1).setSpecificMax(2));
- kind.typeList.add(new EditType(Phone.TYPE_WORK, -1).setSpecificMax(1));
- kind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1).setSecondary(true));
- kind.typeList.add(new EditType(Phone.TYPE_OTHER, -1));
+ phoneKind.typeOverallMax = 5;
+ phoneKind.typeColumn = Phone.TYPE;
+ phoneKind.typeList = Lists.newArrayList();
+ phoneKind.typeList.add(new EditType(Phone.TYPE_HOME, -1).setSpecificMax(2));
+ phoneKind.typeList.add(new EditType(Phone.TYPE_WORK, -1).setSpecificMax(1));
+ phoneKind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1).setSecondary(true));
+ phoneKind.typeList.add(new EditType(Phone.TYPE_OTHER, -1));
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(Phone.NUMBER, -1, -1));
- kind.fieldList.add(new EditField(Phone.LABEL, -1, -1));
+ phoneKind.fieldList = Lists.newArrayList();
+ phoneKind.fieldList.add(new EditField(Phone.NUMBER, -1, -1));
+ phoneKind.fieldList.add(new EditField(Phone.LABEL, -1, -1));
- addKind(kind);
+ addKind(phoneKind);
// Email is unlimited
- kind = new DataKind(Email.CONTENT_ITEM_TYPE, -1, -1, 10, true);
- kind.typeOverallMax = -1;
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(Email.DATA, -1, -1));
- addKind(kind);
+ final DataKind emailKind = new DataKind(Email.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+ emailKind.typeOverallMax = -1;
+ emailKind.fieldList = Lists.newArrayList();
+ emailKind.fieldList.add(new EditField(Email.DATA, -1, -1));
+ addKind(emailKind);
// IM is only one
- kind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10, true);
- kind.typeOverallMax = 1;
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(Im.DATA, -1, -1));
- addKind(kind);
+ final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+ imKind.typeOverallMax = 1;
+ imKind.fieldList = Lists.newArrayList();
+ imKind.fieldList.add(new EditField(Im.DATA, -1, -1));
+ addKind(imKind);
// Organization is only one
- kind = new DataKind(Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true);
- kind.typeOverallMax = 1;
- kind.fieldList = Lists.newArrayList();
- kind.fieldList.add(new EditField(Organization.COMPANY, -1, -1));
- kind.fieldList.add(new EditField(Organization.TITLE, -1, -1));
- addKind(kind);
+ final DataKind orgKind = new DataKind(Organization.CONTENT_ITEM_TYPE, -1, -1, 10, true);
+ orgKind.typeOverallMax = 1;
+ orgKind.fieldList = Lists.newArrayList();
+ orgKind.fieldList.add(new EditField(Organization.COMPANY, -1, -1));
+ orgKind.fieldList.add(new EditField(Organization.TITLE, -1, -1));
+ addKind(orgKind);
}
@Override
@@ -330,7 +335,7 @@
// Test row that has type values, but core fields are empty
final EntityDelta state = getEntity(TEST_ID);
- final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
+ EntityModifier.insertChild(state, kindPhone, typeHome);
// Build diff, expecting insert for data row and update enforcement
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
@@ -420,7 +425,7 @@
public void testTrimEmptyUntouched() {
final AccountType source = getAccountType();
final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
// Build "before" that has empty row
final EntityDelta state = getEntity(TEST_ID);
@@ -497,7 +502,7 @@
final AccountType accountType = getAccountType();
final AccountTypeManager accountTypes = getAccountTypes(accountType);
final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
- final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
+ EntityModifier.getType(kindPhone, Phone.TYPE_HOME);
// Try creating a contact without any child entries
final EntityDelta state = getEntity(null);
@@ -528,7 +533,7 @@
// Try creating a contact with single empty entry
final EntityDelta state = getEntity(null);
- final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome);
+ EntityModifier.insertChild(state, kindPhone, typeHome);
final EntityDeltaList set = EntityDeltaList.fromSingle(state);
// Build diff, expecting two insert operations
diff --git a/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java b/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
index 912950f..88da971 100644
--- a/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
+++ b/tests/src/com/android/contacts/activities/ContactBrowserActivityTest.java
@@ -16,6 +16,7 @@
package com.android.contacts.activities;
+import com.android.contacts.ContactPhotoManager;
import com.android.contacts.ContactsApplication;
import com.android.contacts.R;
import com.android.contacts.detail.ContactDetailFragment;
@@ -26,6 +27,7 @@
import com.android.contacts.test.InjectedServices;
import com.android.contacts.tests.mocks.ContactsMockContext;
import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.tests.mocks.MockContactPhotoManager;
import com.android.contacts.tests.mocks.MockContentProvider;
import com.android.contacts.tests.mocks.MockContentProvider.Query;
import com.android.contacts.tests.mocks.MockSharedPreferences;
@@ -85,7 +87,8 @@
InjectedServices services = new InjectedServices();
services.setContentResolver(mContext.getContentResolver());
services.setSharedPreferences(new MockSharedPreferences());
-
+ services.setSystemService(ContactPhotoManager.CONTACT_PHOTO_SERVICE,
+ new MockContactPhotoManager());
AccountType accountType = new BaseAccountType();
accountType.accountType = TEST_ACCOUNT_TYPE;
diff --git a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
index 43e844e..c401a8c 100644
--- a/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/PhoneNumberInteractionTest.java
@@ -124,6 +124,26 @@
assertEquals("sms:456", interaction.startedIntent.getDataString());
}
+ public void testShouldCollapseWith() {
+ PhoneNumberInteraction.PhoneItem phoneItem1 = new PhoneNumberInteraction.PhoneItem();
+ PhoneNumberInteraction.PhoneItem phoneItem2 = new PhoneNumberInteraction.PhoneItem();
+
+ phoneItem1.phoneNumber = "123";
+ phoneItem2.phoneNumber = "123";
+
+ assertTrue(phoneItem1.shouldCollapseWith(phoneItem2));
+
+ phoneItem1.phoneNumber = "123";
+ phoneItem2.phoneNumber = "456";
+
+ assertFalse(phoneItem1.shouldCollapseWith(phoneItem2));
+
+ phoneItem1.phoneNumber = "123#,123";
+ phoneItem2.phoneNumber = "123#,456";
+
+ assertFalse(phoneItem1.shouldCollapseWith(phoneItem2));
+ }
+
public void testCallNumberWhenThereAreDuplicates() {
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 13);
expectQuery(contactUri)
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index 50a1f1f..03b6302 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -73,6 +73,7 @@
ACTION_PICK_PHONE_LEGACY,
ACTION_PICK_POSTAL,
ACTION_PICK_POSTAL_LEGACY,
+ ACTION_PICK_EMAIL,
ACTION_CREATE_SHORTCUT_CONTACT,
ACTION_CREATE_SHORTCUT_DIAL,
ACTION_CREATE_SHORTCUT_MESSAGE,
@@ -195,6 +196,11 @@
startContactSelectionActivityForResult(intent);
break;
}
+ case ACTION_PICK_EMAIL: {
+ startContactSelectionActivityForResult(
+ new Intent(Intent.ACTION_PICK, Email.CONTENT_URI));
+ break;
+ }
case ACTION_CREATE_SHORTCUT_CONTACT: {
Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
startContactSelectionActivityForResult(intent);
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
new file mode 100644
index 0000000..6da205b
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.tests.mocks;
+
+import com.android.contacts.ContactPhotoManager;
+
+import android.net.Uri;
+import android.widget.ImageView;
+
+/**
+ * A photo preloader that always uses the "no contact" picture and never executes any real
+ * db queries
+ */
+public class MockContactPhotoManager extends ContactPhotoManager {
+ @Override
+ public void loadPhoto(ImageView view, long photoId) {
+ view.setImageResource(mDefaultResourceId);
+ }
+
+ @Override
+ public void loadPhoto(ImageView view, Uri photoUri) {
+ view.setImageResource(mDefaultResourceId);
+ }
+
+ @Override
+ public void pause() {
+ }
+
+ @Override
+ public void resume() {
+ }
+
+ @Override
+ public void refreshCache() {
+ }
+
+ @Override
+ public void preloadPhotosInBackground() {
+ }
+}