diff options
180 files changed, 7891 insertions, 246 deletions
@@ -28,6 +28,8 @@ LOCAL_AAPT_FLAGS := \ --auto-add-overlay \ --extra-packages com.android.phone.common +LOCAL_JAVA_LIBRARIES := telephony-common + LOCAL_STATIC_JAVA_LIBRARIES := \ com.android.vcard \ guava \ diff --git a/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java b/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java index ab2d3954..d3dd722c 100644 --- a/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java +++ b/TestCommon/src/com/android/contacts/common/test/mocks/MockAccountTypeManager.java @@ -66,6 +66,11 @@ public class MockAccountTypeManager extends AccountTypeManager { } @Override + public List<AccountWithDataSet> getAccounts(boolean writableOnly, int flag) { + return Arrays.asList(mAccounts); + } + + @Override public List<AccountWithDataSet> getGroupWritableAccounts() { return Arrays.asList(mAccounts); } diff --git a/TestCommon/src/com/android/contacts/common/test/mocks/MockContactPhotoManager.java b/TestCommon/src/com/android/contacts/common/test/mocks/MockContactPhotoManager.java index db8f06f2..3b143deb 100644 --- a/TestCommon/src/com/android/contacts/common/test/mocks/MockContactPhotoManager.java +++ b/TestCommon/src/com/android/contacts/common/test/mocks/MockContactPhotoManager.java @@ -16,6 +16,7 @@ package com.android.contacts.common.test.mocks; +import android.accounts.Account; import android.graphics.Bitmap; import android.net.Uri; import android.view.View; @@ -29,16 +30,19 @@ import com.android.contacts.common.ContactPhotoManager; */ public class MockContactPhotoManager extends ContactPhotoManager { @Override - public void loadThumbnail(ImageView view, long photoId, boolean darkTheme, boolean isCircular, - DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider) { - defaultProvider.applyDefaultImage(view, -1, darkTheme, null); + public void loadThumbnail(ImageView view, long photoId, Account account, + boolean darkTheme, boolean isCircular, + DefaultImageRequest defaultImageRequest, + DefaultImageProvider defaultProvider) { + defaultProvider.applyDefaultImage(view, account, -1, darkTheme, null); } @Override - public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme, - boolean isCircular, DefaultImageRequest defaultImageRequest, + public void loadPhoto(ImageView view, Uri photoUri, Account account, + int requestedExtent, boolean darkTheme, boolean isCircular, + DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider) { - defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme, null); + defaultProvider.applyDefaultImage(view, account, requestedExtent, darkTheme, null); } @Override @@ -69,4 +73,8 @@ public class MockContactPhotoManager extends ContactPhotoManager { @Override public void preloadPhotosInBackground() { } + + @Override + public void clear() { + } } diff --git a/res/drawable-hdpi/ic_action_call.png b/res/drawable-hdpi/ic_action_call.png Binary files differnew file mode 100644 index 00000000..7493a607 --- /dev/null +++ b/res/drawable-hdpi/ic_action_call.png diff --git a/res/drawable-hdpi/ic_check_wht_24dp.png b/res/drawable-hdpi/ic_check_wht_24dp.png Binary files differnew file mode 100644 index 00000000..12ce8e0d --- /dev/null +++ b/res/drawable-hdpi/ic_check_wht_24dp.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim.png b/res/drawable-hdpi/ic_contact_picture_sim.png Binary files differnew file mode 100755 index 00000000..7b6cc26f --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim_1.png b/res/drawable-hdpi/ic_contact_picture_sim_1.png Binary files differnew file mode 100755 index 00000000..ec2ebcb5 --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim_1.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim_2.png b/res/drawable-hdpi/ic_contact_picture_sim_2.png Binary files differnew file mode 100755 index 00000000..3b68c682 --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim_2.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim_business.png b/res/drawable-hdpi/ic_contact_picture_sim_business.png Binary files differnew file mode 100755 index 00000000..4df1ecd5 --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim_business.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim_personal.png b/res/drawable-hdpi/ic_contact_picture_sim_personal.png Binary files differnew file mode 100755 index 00000000..44f4b930 --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim_personal.png diff --git a/res/drawable-hdpi/ic_contact_picture_sim_primary.png b/res/drawable-hdpi/ic_contact_picture_sim_primary.png Binary files differnew file mode 100755 index 00000000..a5bf9214 --- /dev/null +++ b/res/drawable-hdpi/ic_contact_picture_sim_primary.png diff --git a/res/drawable-hdpi/ic_menu_settings_holo_light.png b/res/drawable-hdpi/ic_menu_settings_holo_light.png Binary files differindex b7bb5c41..ca012b85 100644..100755 --- a/res/drawable-hdpi/ic_menu_settings_holo_light.png +++ b/res/drawable-hdpi/ic_menu_settings_holo_light.png diff --git a/res/drawable-hdpi/ic_rx_videocam.png b/res/drawable-hdpi/ic_rx_videocam.png Binary files differnew file mode 100644 index 00000000..ccdda670 --- /dev/null +++ b/res/drawable-hdpi/ic_rx_videocam.png diff --git a/res/drawable-hdpi/ic_tx_videocam.png b/res/drawable-hdpi/ic_tx_videocam.png Binary files differnew file mode 100644 index 00000000..603ddc89 --- /dev/null +++ b/res/drawable-hdpi/ic_tx_videocam.png diff --git a/res/drawable-hdpi/phone_account.png b/res/drawable-hdpi/phone_account.png Binary files differnew file mode 100755 index 00000000..f2324885 --- /dev/null +++ b/res/drawable-hdpi/phone_account.png diff --git a/res/drawable-hdpi/sim1_account.png b/res/drawable-hdpi/sim1_account.png Binary files differnew file mode 100755 index 00000000..2d9a51c0 --- /dev/null +++ b/res/drawable-hdpi/sim1_account.png diff --git a/res/drawable-hdpi/sim2_account.png b/res/drawable-hdpi/sim2_account.png Binary files differnew file mode 100755 index 00000000..c512d524 --- /dev/null +++ b/res/drawable-hdpi/sim2_account.png diff --git a/res/drawable-hdpi/simcard_account.png b/res/drawable-hdpi/simcard_account.png Binary files differnew file mode 100755 index 00000000..0ee3dac2 --- /dev/null +++ b/res/drawable-hdpi/simcard_account.png diff --git a/res/drawable-mdpi/ic_action_call.png b/res/drawable-mdpi/ic_action_call.png Binary files differnew file mode 100644 index 00000000..a5a7c371 --- /dev/null +++ b/res/drawable-mdpi/ic_action_call.png diff --git a/res/drawable-mdpi/ic_check_wht_24dp.png b/res/drawable-mdpi/ic_check_wht_24dp.png Binary files differnew file mode 100644 index 00000000..c7de7050 --- /dev/null +++ b/res/drawable-mdpi/ic_check_wht_24dp.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim.png b/res/drawable-mdpi/ic_contact_picture_sim.png Binary files differnew file mode 100755 index 00000000..dd63d11d --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim_1.png b/res/drawable-mdpi/ic_contact_picture_sim_1.png Binary files differnew file mode 100755 index 00000000..4793a07e --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim_1.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim_2.png b/res/drawable-mdpi/ic_contact_picture_sim_2.png Binary files differnew file mode 100755 index 00000000..665a6714 --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim_2.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim_business.png b/res/drawable-mdpi/ic_contact_picture_sim_business.png Binary files differnew file mode 100755 index 00000000..c266e266 --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim_business.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim_personal.png b/res/drawable-mdpi/ic_contact_picture_sim_personal.png Binary files differnew file mode 100755 index 00000000..f1e75966 --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim_personal.png diff --git a/res/drawable-mdpi/ic_contact_picture_sim_primary.png b/res/drawable-mdpi/ic_contact_picture_sim_primary.png Binary files differnew file mode 100755 index 00000000..493067a9 --- /dev/null +++ b/res/drawable-mdpi/ic_contact_picture_sim_primary.png diff --git a/res/drawable-mdpi/ic_menu_settings_holo_light.png b/res/drawable-mdpi/ic_menu_settings_holo_light.png Binary files differindex 1ebc112e..45a5ff0f 100644..100755 --- a/res/drawable-mdpi/ic_menu_settings_holo_light.png +++ b/res/drawable-mdpi/ic_menu_settings_holo_light.png diff --git a/res/drawable-mdpi/ic_rx_videocam.png b/res/drawable-mdpi/ic_rx_videocam.png Binary files differnew file mode 100755 index 00000000..1b43a07d --- /dev/null +++ b/res/drawable-mdpi/ic_rx_videocam.png diff --git a/res/drawable-mdpi/ic_tx_videocam.png b/res/drawable-mdpi/ic_tx_videocam.png Binary files differnew file mode 100755 index 00000000..64995d14 --- /dev/null +++ b/res/drawable-mdpi/ic_tx_videocam.png diff --git a/res/drawable-mdpi/phone_account.png b/res/drawable-mdpi/phone_account.png Binary files differnew file mode 100755 index 00000000..1fa24f6c --- /dev/null +++ b/res/drawable-mdpi/phone_account.png diff --git a/res/drawable-mdpi/sim1_account.png b/res/drawable-mdpi/sim1_account.png Binary files differnew file mode 100755 index 00000000..cd80def2 --- /dev/null +++ b/res/drawable-mdpi/sim1_account.png diff --git a/res/drawable-mdpi/sim2_account.png b/res/drawable-mdpi/sim2_account.png Binary files differnew file mode 100755 index 00000000..fd52224a --- /dev/null +++ b/res/drawable-mdpi/sim2_account.png diff --git a/res/drawable-mdpi/simcard_account.png b/res/drawable-mdpi/simcard_account.png Binary files differnew file mode 100755 index 00000000..e5a76881 --- /dev/null +++ b/res/drawable-mdpi/simcard_account.png diff --git a/res/drawable-xhdpi/ic_action_call.png b/res/drawable-xhdpi/ic_action_call.png Binary files differnew file mode 100644 index 00000000..e16ef951 --- /dev/null +++ b/res/drawable-xhdpi/ic_action_call.png diff --git a/res/drawable-xhdpi/ic_check_wht_24dp.png b/res/drawable-xhdpi/ic_check_wht_24dp.png Binary files differnew file mode 100644 index 00000000..e34b73e5 --- /dev/null +++ b/res/drawable-xhdpi/ic_check_wht_24dp.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim.png b/res/drawable-xhdpi/ic_contact_picture_sim.png Binary files differnew file mode 100755 index 00000000..a39b7df0 --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim_1.png b/res/drawable-xhdpi/ic_contact_picture_sim_1.png Binary files differnew file mode 100755 index 00000000..300c0288 --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim_1.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim_2.png b/res/drawable-xhdpi/ic_contact_picture_sim_2.png Binary files differnew file mode 100755 index 00000000..c7ce4223 --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim_2.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim_business.png b/res/drawable-xhdpi/ic_contact_picture_sim_business.png Binary files differnew file mode 100755 index 00000000..abf631f9 --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim_business.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim_personal.png b/res/drawable-xhdpi/ic_contact_picture_sim_personal.png Binary files differnew file mode 100755 index 00000000..e5f0cf0a --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim_personal.png diff --git a/res/drawable-xhdpi/ic_contact_picture_sim_primary.png b/res/drawable-xhdpi/ic_contact_picture_sim_primary.png Binary files differnew file mode 100755 index 00000000..543d6a7a --- /dev/null +++ b/res/drawable-xhdpi/ic_contact_picture_sim_primary.png diff --git a/res/drawable-xhdpi/ic_menu_settings_holo_light.png b/res/drawable-xhdpi/ic_menu_settings_holo_light.png Binary files differindex 68ba92bd..91d0444d 100644..100755 --- a/res/drawable-xhdpi/ic_menu_settings_holo_light.png +++ b/res/drawable-xhdpi/ic_menu_settings_holo_light.png diff --git a/res/drawable-xhdpi/ic_rx_videocam.png b/res/drawable-xhdpi/ic_rx_videocam.png Binary files differnew file mode 100755 index 00000000..43319dc9 --- /dev/null +++ b/res/drawable-xhdpi/ic_rx_videocam.png diff --git a/res/drawable-xhdpi/ic_tx_videocam.png b/res/drawable-xhdpi/ic_tx_videocam.png Binary files differnew file mode 100755 index 00000000..d2671edf --- /dev/null +++ b/res/drawable-xhdpi/ic_tx_videocam.png diff --git a/res/drawable-xhdpi/phone_account.png b/res/drawable-xhdpi/phone_account.png Binary files differnew file mode 100755 index 00000000..a61f2034 --- /dev/null +++ b/res/drawable-xhdpi/phone_account.png diff --git a/res/drawable-xhdpi/sim1_account.png b/res/drawable-xhdpi/sim1_account.png Binary files differnew file mode 100755 index 00000000..c0ae46f2 --- /dev/null +++ b/res/drawable-xhdpi/sim1_account.png diff --git a/res/drawable-xhdpi/sim2_account.png b/res/drawable-xhdpi/sim2_account.png Binary files differnew file mode 100755 index 00000000..68fb25ce --- /dev/null +++ b/res/drawable-xhdpi/sim2_account.png diff --git a/res/drawable-xhdpi/simcard_account.png b/res/drawable-xhdpi/simcard_account.png Binary files differnew file mode 100755 index 00000000..92b382ee --- /dev/null +++ b/res/drawable-xhdpi/simcard_account.png diff --git a/res/drawable-xxhdpi/ic_action_call.png b/res/drawable-xxhdpi/ic_action_call.png Binary files differnew file mode 100644 index 00000000..c4cfdac8 --- /dev/null +++ b/res/drawable-xxhdpi/ic_action_call.png diff --git a/res/drawable-xxhdpi/ic_check_wht_24dp.png b/res/drawable-xxhdpi/ic_check_wht_24dp.png Binary files differnew file mode 100644 index 00000000..4c6a653f --- /dev/null +++ b/res/drawable-xxhdpi/ic_check_wht_24dp.png diff --git a/res/drawable-xxhdpi/ic_menu_settings_holo_light.png b/res/drawable-xxhdpi/ic_menu_settings_holo_light.png Binary files differindex 5b672a3d..c87e0463 100644..100755 --- a/res/drawable-xxhdpi/ic_menu_settings_holo_light.png +++ b/res/drawable-xxhdpi/ic_menu_settings_holo_light.png diff --git a/res/drawable-xxhdpi/ic_rx_videocam.png b/res/drawable-xxhdpi/ic_rx_videocam.png Binary files differnew file mode 100755 index 00000000..89d29b7f --- /dev/null +++ b/res/drawable-xxhdpi/ic_rx_videocam.png diff --git a/res/drawable-xxhdpi/ic_tx_videocam.png b/res/drawable-xxhdpi/ic_tx_videocam.png Binary files differnew file mode 100755 index 00000000..8d897ba5 --- /dev/null +++ b/res/drawable-xxhdpi/ic_tx_videocam.png diff --git a/res/drawable-xxhdpi/phone_account.png b/res/drawable-xxhdpi/phone_account.png Binary files differnew file mode 100755 index 00000000..04b06fda --- /dev/null +++ b/res/drawable-xxhdpi/phone_account.png diff --git a/res/drawable-xxhdpi/sim1_account.png b/res/drawable-xxhdpi/sim1_account.png Binary files differnew file mode 100755 index 00000000..9293bdbe --- /dev/null +++ b/res/drawable-xxhdpi/sim1_account.png diff --git a/res/drawable-xxhdpi/sim2_account.png b/res/drawable-xxhdpi/sim2_account.png Binary files differnew file mode 100755 index 00000000..4788f1cd --- /dev/null +++ b/res/drawable-xxhdpi/sim2_account.png diff --git a/res/drawable-xxhdpi/simcard_account.png b/res/drawable-xxhdpi/simcard_account.png Binary files differnew file mode 100755 index 00000000..e98fd1d9 --- /dev/null +++ b/res/drawable-xxhdpi/simcard_account.png diff --git a/res/drawable-xxxhdpi/ic_menu_settings_holo_light.png b/res/drawable-xxxhdpi/ic_menu_settings_holo_light.png Binary files differnew file mode 100755 index 00000000..dfdd5798 --- /dev/null +++ b/res/drawable-xxxhdpi/ic_menu_settings_holo_light.png diff --git a/res/drawable-xxxhdpi/ic_rx_videocam.png b/res/drawable-xxxhdpi/ic_rx_videocam.png Binary files differnew file mode 100755 index 00000000..095e0905 --- /dev/null +++ b/res/drawable-xxxhdpi/ic_rx_videocam.png diff --git a/res/drawable-xxxhdpi/ic_tx_videocam.png b/res/drawable-xxxhdpi/ic_tx_videocam.png Binary files differnew file mode 100755 index 00000000..79ea67b2 --- /dev/null +++ b/res/drawable-xxxhdpi/ic_tx_videocam.png diff --git a/res/drawable-xxxhdpi/phone_account.png b/res/drawable-xxxhdpi/phone_account.png Binary files differnew file mode 100755 index 00000000..3d726f60 --- /dev/null +++ b/res/drawable-xxxhdpi/phone_account.png diff --git a/res/drawable-xxxhdpi/sim1_account.png b/res/drawable-xxxhdpi/sim1_account.png Binary files differnew file mode 100755 index 00000000..389569ac --- /dev/null +++ b/res/drawable-xxxhdpi/sim1_account.png diff --git a/res/drawable-xxxhdpi/sim2_account.png b/res/drawable-xxxhdpi/sim2_account.png Binary files differnew file mode 100755 index 00000000..ce5d8ddb --- /dev/null +++ b/res/drawable-xxxhdpi/sim2_account.png diff --git a/res/drawable-xxxhdpi/simcard_account.png b/res/drawable-xxxhdpi/simcard_account.png Binary files differnew file mode 100755 index 00000000..5f18f34b --- /dev/null +++ b/res/drawable-xxxhdpi/simcard_account.png diff --git a/res/drawable/call_background_activated.xml b/res/drawable/call_background_activated.xml new file mode 100644 index 00000000..9fe8d3f6 --- /dev/null +++ b/res/drawable/call_background_activated.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <gradient android:startColor="#33b5e5" android:endColor="#33b5e5" + android:angle="270" /> + <corners android:radius="2dp" /> + <stroke android:color="#33b5e5" android:width="1dp" /> + <padding android:top="5dp" android:bottom="5dp" android:left="5dp" + android:right="5dp" /> +</shape>
\ No newline at end of file diff --git a/res/drawable/call_background_holo.xml b/res/drawable/call_background_holo.xml new file mode 100644 index 00000000..b947b20a --- /dev/null +++ b/res/drawable/call_background_holo.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <gradient android:startColor="#00000000" + android:endColor="#00000000" + android:angle="270" /> + <corners android:radius="2dp" /> + <padding android:top="5dp" android:bottom="5dp" android:left="5dp" + android:right="5dp" /> +</shape>
\ No newline at end of file diff --git a/res/drawable/ic_action_call_background.xml b/res/drawable/ic_action_call_background.xml new file mode 100644 index 00000000..71ac2a9b --- /dev/null +++ b/res/drawable/ic_action_call_background.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT 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_focused="true" + android:state_pressed="true" + android:drawable="@drawable/call_background_activated" /> + <item android:state_focused="false" + android:state_pressed="true" + android:drawable="@drawable/call_background_activated"/> + <item android:state_focused="false" + android:state_pressed="false" + android:drawable="@drawable/call_background_holo"/> +</selector>
\ No newline at end of file diff --git a/res/layout/contact_tile_frequent.xml b/res/layout/contact_tile_frequent.xml index b1e83ce0..8c718fb2 100644 --- a/res/layout/contact_tile_frequent.xml +++ b/res/layout/contact_tile_frequent.xml @@ -38,7 +38,7 @@ android:id="@+id/contact_tile_name" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textColor="@android:color/black" + android:textColor="@color/frequent_contact_text_color" android:textSize="@dimen/contact_browser_list_item_text_size" android:singleLine="true" android:fadingEdge="horizontal" diff --git a/res/layout/contact_tile_starred.xml b/res/layout/contact_tile_starred.xml index 777cc058..88aa1e88 100644 --- a/res/layout/contact_tile_starred.xml +++ b/res/layout/contact_tile_starred.xml @@ -43,7 +43,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="7dp" - android:textColor="#202020" + android:textColor="@color/contact_tile_text_color" android:textSize="@dimen/contact_browser_list_item_text_size" android:singleLine="true" android:fadingEdge="horizontal" diff --git a/res/layout/ip_prefix_dialog.xml b/res/layout/ip_prefix_dialog.xml new file mode 100644 index 00000000..9de02dcb --- /dev/null +++ b/res/layout/ip_prefix_dialog.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <EditText + android:id="@+id/ip_prefix_dialog_edit" + android:layout_width="match_parent" + android:layout_height="45dip" + android:layout_margin="10dip" + android:inputType="phone" + android:hint="@string/ipcall_dialog_edit_hint"/> + +</LinearLayout> diff --git a/res/layout/search_bar_expanded.xml b/res/layout/search_bar_expanded.xml index 3c71b508..ff7c3227 100644 --- a/res/layout/search_bar_expanded.xml +++ b/res/layout/search_bar_expanded.xml @@ -37,7 +37,7 @@ android:layout_width="0dp" android:layout_height="@dimen/search_box_icon_size" android:layout_weight="1" - android:layout_marginLeft="@dimen/search_box_text_left_margin" + android:layout_marginStart="@dimen/search_box_text_left_margin" android:textSize="@dimen/search_text_size" android:fontFamily="@string/search_font_family" android:textColor="@color/searchbox_text_color" diff --git a/res/values-af/cm_strings.xml b/res/values-af/cm_strings.xml new file mode 100644 index 00000000..6ab5a69c --- /dev/null +++ b/res/values-af/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Plaaslike tablet rekening</string> + <string name="local_storage_account" product="default">Plaaslike telefoon rekening</string> + <string name="import_contacts_sim">Voer kontakte in van SIM kaart?</string> + <string name="manage_sim_contacts">Bestuur SIM kaart kontakte</string> + <string name="export_to_sim">Uitvoer na SIM-kaart</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' kon nie ingevoer word nie a.g.v. \'n I/U fout</string> + <string name="contact_share_failed_toast">Nie meer as <xliff:g id="count">%d</xliff:g> kontakte kan gedeel word nie</string> + <string name="label_groups">Groepe</string> + <string name="exporting">Uitvoering\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> van <xliff:g id="total_number">%2$s</xliff:g> lêers</string> + <string name="export_failed">Uitvoer het misluk</string> + <string name="sim_card_full">SIM kaart is vol</string> + <string name="export_finished">Uitvoer Klaar</string> + <string name="tag_too_long">Kontak naam is te lank</string> + <string name="sim_contacts_not_loaded">Kon nie SIM kontakte laai nie</string> + <plurals name="export_cancelled"> + <item quantity="one">Uitvoering was gekanselleer, %d item is uitgevoer</item> + <item quantity="other">Uitvoering was gekanselleer, %d items is uitgevoer</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> het nie \'n telefoonnommer of epos adres nie</string> + <string name="import_from_sim_select">Kies kaart om in te voer</string> + <string name="no_sdcard_title" product="nosdcard">Spasie onbeskikbaar</string> + <string name="no_sdcard_title" product="default">Geen SD kaart</string> + <string name="deleteConfirmation_title">Verwyder kontak?</string> + <string name="deleteConfirmation">Hierdie kontak sal verwyder word.</string> + <string name="copy_done">Kontak suksesvol gekopieer</string> + <string name="copy_failure">Kopiëring van die kontak het misluk</string> + <string name="card_no_space">Kopiëring van die kontak het misluk, die SIM-kaart is vol</string> + <string name="settings_contact_display_options_description">Stel hoe jou kontakte vertoon en gesorteer sal word.</string> + <string name="ip_call_by_slot">IP oproep via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Geen IP nommer</string> + <string name="no_ip_number_on_sim_card">Geen IP nommer op SIM-kaart</string> + <string name="set_ip_number">Stel IP nommer</string> + <string name="ipcall_dialog_title">IP oproep instellings</string> + <string name="ipcall_dialog_edit_hint">Voer die IP voorvoegsel in</string> + <string name="import_contacts_from_all_cards">Voer kontakte in van alle SIM kaarte</string> + <string name="select_path">Kies</string> + <string name="select_sim">Kies SIM</string> +</resources> diff --git a/res/values-ar/cm_strings.xml b/res/values-ar/cm_strings.xml new file mode 100644 index 00000000..02e6d067 --- /dev/null +++ b/res/values-ar/cm_strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">حساب الكمبيوتر اللوحي المحلي</string> + <string name="local_storage_account" product="default">حساب الهاتف المحلية</string> +</resources> diff --git a/res/values-ast-rES/cm_strings.xml b/res/values-ast-rES/cm_strings.xml new file mode 100644 index 00000000..bb45c4fb --- /dev/null +++ b/res/values-ast-rES/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Cuenta llocal de la tablet</string> + <string name="local_storage_account" product="default">Cuenta llocal del teléfonu</string> + <string name="import_contacts_sim">¿Importar contautos de la tarxeta SIM?</string> + <string name="manage_sim_contacts">Xestionar contautos de tarxeta SIM</string> + <string name="export_to_sim">Esportar a la tarxeta SIM</string> + <string name="fail_reason_import_vcard">\u00AB<xliff:g id="name">%s</xliff:g>\u00BB nun pue importase pola mor d\'un fallu de E/S</string> + <string name="contact_share_failed_toast">Nun puen compartise más de <xliff:g id="count">%d</xliff:g> contautos</string> + <string name="label_groups">Grupu</string> + <string name="exporting">Esportando\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> de <xliff:g id="total_number">%2$s</xliff:g> ficheros</string> + <string name="export_failed">Falló al esportar</string> + <string name="sim_card_full">La tarxeta SIM ta enllena</string> + <string name="export_finished">Finó la esportación</string> + <string name="tag_too_long">El nome del contautu ye enforma llargu</string> + <string name="sim_contacts_not_loaded">Nun puen cargase los contautos de la tarxeta SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Esportación encaboxada. Esportóse %d contautu</item> + <item quantity="other">Esportación encaboxada. Esportáronse %d contautos</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> nun tien un númberu de tefnu o una direición de corréu</string> + <string name="import_from_sim_select">Escueyi una tarxeta pa importar</string> + <string name="no_sdcard_title" product="nosdcard">Almacenamientu non disponible</string> + <string name="no_sdcard_title" product="default">Falta la tarxeta SD</string> + <string name="deleteConfirmation_title">Desaniciar contautu?</string> + <string name="deleteConfirmation">El contautu va desaniciase.</string> + <string name="copy_done">Contautu copiáu correchamente</string> + <string name="copy_failure">Falló la copia del contautu</string> + <string name="card_no_space">Falló la copia de tolos contautos. La tarxeta SIM ta enllena</string> + <string name="settings_contact_display_options_description">Configurar cómo s\'amuesen y s\'ordenen los contautos</string> + <string name="ip_call_by_slot">Llamada IP vía <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nun hai númberu IP</string> + <string name="no_ip_number_on_sim_card">Nun hai númberu IP na tarxeta SIM</string> + <string name="set_ip_number">Afitar númberu IP</string> + <string name="ipcall_dialog_title">Axustes de llamada IP</string> + <string name="ipcall_dialog_edit_hint">Introduz el prefixu IP</string> + <string name="import_contacts_from_all_cards">Importar contautos de toles tarxetes SIM</string> + <string name="select_path">Seleiciona\'l camín</string> + <string name="select_sim">Seleicionar SIM</string> +</resources> diff --git a/res/values-ast-rES/strings.xml b/res/values-ast-rES/strings.xml new file mode 100644 index 00000000..6883c771 --- /dev/null +++ b/res/values-ast-rES/strings.xml @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + ~ Copyright (C) 2012 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="toast_text_copied">Testu copiáu</string> + <string name="call_custom">Llamar a <xliff:g id="CUSTOM">%s</xliff:g> + </string> + <string name="call_home">Llamar a casa</string> + <string name="call_mobile">Llamar al móvil</string> + <string name="call_work">Llamar al trabayu</string> + <string name="call_fax_work">Llamar al fax del trabayu</string> + <string name="call_fax_home">Llamar al fax de casa</string> + <string name="call_pager">Llamar al busca</string> + <string name="call_other">Llamar</string> + <string name="call_callback">Llamar a un númberu de devolución de llamada</string> + <string name="call_car">Llamar al coche</string> + <string name="call_company_main">Llamar al teléfonu principal de la empresa</string> + <string name="call_isdn">Llamar a RDSI</string> + <string name="call_main">Llamar al teléfonu principal</string> + <string name="call_other_fax">Llamar al fax</string> + <string name="call_radio">Llamar a la radio</string> + <string name="call_telex">Llamar al télex</string> + <string name="call_tty_tdd">Llamar a TTY/TDD</string> + <string name="call_work_mobile">Llamar al móvil del trabayu</string> + <string name="call_work_pager">Llamar al busca del trabayu</string> + <string name="call_assistant">Llamar al <xliff:g id="ASSISTANT">%s</xliff:g></string> + <string name="call_mms">Llamar a MMS</string> + <string name="sms_custom">Testu <xliff:g id="CUSTOM">%s</xliff:g></string> + <string name="sms_home">Unviar SMS a casa</string> + <string name="sms_mobile">Unviar SMS al móvil</string> + <string name="sms_work">Unviar SMS al trabayu</string> + <string name="sms_fax_work">Unviar SMS al fax del trabayu</string> + <string name="sms_fax_home">Unviar SMS al fax de casa</string> + <string name="sms_pager">Unviar SMS al busca</string> + <string name="sms_other">Unviar SMS</string> + <string name="sms_callback">Unviar SMS a un númberu de devolución de llamada</string> + <string name="sms_car">Unviar SMS al coche</string> + <string name="sms_company_main">Unviar SMS al teléfonu principal de la empresa</string> + <string name="sms_isdn">Unviar SMS a RDSI</string> + <string name="sms_main">Unviar SMS al númberu de teléfonu principal</string> + <string name="sms_other_fax">Unviar SMS al fax</string> + <string name="sms_radio">Unviar SMS a la radio</string> + <string name="sms_telex">Unviar SMS al télex</string> + <string name="sms_tty_tdd">Unviar SMS a TTY/TDD</string> + <string name="sms_work_mobile">Unviar SMS al móvil del trabayu</string> + <string name="sms_work_pager">Unviar SMS al busca del trabayu</string> + <string name="sms_assistant">Unviar SMS al <xliff:g id="ASSISTANT">%s</xliff:g></string> + <string name="sms_mms">Unviar SMS a MMS</string> + <string name="description_video_call">Facer videollamada</string> + <string name="clearFrequentsConfirmation_title">¿Llimpiar contautos frecuentes?</string> + <string name="clearFrequentsConfirmation">Vas llimpiar la llista de contautos frecuentes de les aplicaciones Contautos y Teléfonu y con esto vas obligar a les aplicaciones de corréu-e a que memoricen les tos preferencies otra vegada.</string> + <string name="clearFrequentsProgress_title">Llimpiando contautos frecuentes…</string> + <string name="status_available">Disponible</string> + <string name="status_away">Ausente</string> + <string name="status_busy">Ocupáu</string> + <string name="contactsList">Contautos</string> + <string name="local_invisible_directory">Otros</string> + <string name="directory_search_label">Direutoriu</string> + <string name="local_search_label">Tolos contautos</string> + <string name="user_profile_contacts_list_header" msgid="9154761216179882405">Yo</string> + <string name="search_results_searching">Buscando...</string> + <string name="foundTooManyContacts">Alcontráronse más de <xliff:g id="COUNT">%d</xliff:g> contautos.</string> + <string name="listFoundAllContactsZero">Nengún contautu</string> + <plurals name="searchFoundContacts"> + <item quantity="one">1 contautu alcontráu</item> + <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> contautos alcontraos\"</item> + </plurals> + <string name="description_quick_contact_for">Contautu rápidu de <xliff:g id="NAME">%1$s</xliff:g></string> + <string name="missing_name">(Ensin nome)</string> + <string name="favoritesFrequentCalled">Más llamaos</string> + <string name="favoritesFrequentContacted">Contautos frecuentes</string> + <string name="description_view_contact_detail" msgid="2795575601596468581">Ver contautu</string> + <string name="list_filter_phones">Tolos contautos con númberu</string> + <string name="view_updates_from_group">Ver anovamientos</string> + <string name="account_phone" product="tablet">Namái na tablet (ensin sincronizar)</string> + <string name="account_phone" product="default">Namái nel teléfonu, non sincronizáu</string> + <string name="nameLabelsGroup">Nome</string> + <string name="nicknameLabelsGroup">Nomatu</string> + <string name="full_name">Nome</string> + <string name="name_given">Nome</string> + <string name="name_family">Apellíu</string> + <string name="name_prefix">Prefixu del nome</string> + <string name="name_middle">Segundu nome</string> + <string name="name_suffix">Sufixu del nome</string> + <string name="name_phonetic">Nome fonéticu</string> + <string name="name_phonetic_given">Nome fonéticu</string> + <string name="name_phonetic_middle">Segundu nome fonéticu</string> + <string name="name_phonetic_family">Apellíu fonéticu</string> + <string name="phoneLabelsGroup">Teléfonu</string> + <string name="emailLabelsGroup">Corréu-e</string> + <string name="postalLabelsGroup">Señes</string> + <string name="imLabelsGroup">Chat</string> + <string name="organizationLabelsGroup">Organización</string> + <string name="relationLabelsGroup">Rellación</string> + <string name="eventLabelsGroup">Eventos</string> + <string name="sms">Mensaxe de testu</string> + <string name="postal_address">Señes</string> + <string name="ghostData_company">Empresa</string> + <string name="ghostData_title">Nome</string> + <string name="label_notes">Notes</string> + <string name="label_sip_address">SIP</string> + <string name="websiteLabelsGroup">Sitiu web</string> + <string name="groupsLabel">Grupos</string> + <string name="email_home">Unviar corréu a casa</string> + <string name="email_mobile">Unviar corréu al móvil</string> + <string name="email_work">Unviar corréu al trabayu</string> + <string name="email_other">Unviar corréu</string> + <string name="email_custom">Unviar corréu a <xliff:g id="CUSTOM">%s</xliff:g></string> + <string name="email">Corréu-e electrónicu</string> + <string name="postal_street">Cai</string> + <string name="postal_pobox">Apartáu postal</string> + <string name="postal_neighborhood">Vecindariu</string> + <string name="postal_city">Ciudá</string> + <string name="postal_region">Estáu</string> + <string name="postal_postcode">Códigu postal</string> + <string name="postal_country">País</string> + <string name="map_home">Ver direición de casa</string> + <string name="map_work">Ver direición del trabayu</string> + <string name="map_other">Ver direición</string> + <string name="map_custom">Ver direición de <xliff:g id="CUSTOM">%s</xliff:g></string> + <string name="chat_aim">Chat con AIM</string> + <string name="chat_msn">Chat con Windows Live</string> + <string name="chat_yahoo">Chat con Yahoo!</string> + <string name="chat_skype">Chat con Skype</string> + <string name="chat_qq">Chat con QQ</string> + <string name="chat_gtalk">Chat con Google Talk</string> + <string name="chat_icq">Chat con ICQ</string> + <string name="chat_jabber">Chat con Jabber</string> + <string name="chat">Chat</string> + <string name="description_minus_button">desaniciar</string> + <string name="expand_collapse_name_fields_description">Enantar o contrayer campos de nome</string> + <string name="list_filter_all_accounts">Tolos contautos</string> + <string name="list_filter_all_starred">Destacaos</string> + <string name="list_filter_customize">Personalizar</string> + <string name="list_filter_single">Contautu</string> + <string name="display_ungrouped">Tolos demás contautos</string> + <string name="display_all_contacts">Tolos contautos</string> + <string name="menu_sync_remove">Desaniciar grupu de sincronización</string> + <string name="dialog_sync_add">Amestar grupu de sincronización</string> + <string name="display_more_groups">Más grupos…</string> + <string name="display_warn_remove_ungrouped">Si desanicies \"<xliff:g id="GROUP">%s</xliff:g>\" de les sincronizaciones, tamién van desaniciase tolos contautos ensin agrupar.</string> + <string name="savingDisplayGroups">Guardando opciones de visualización…</string> + <string name="menu_done">Fecho</string> + <string name="menu_doNotSave">Encaboxar</string> + <string name="listAllContactsInAccount">Contautos en <xliff:g id="NAME">%s</xliff:g></string> + <string name="listCustomView">Contautos en vista personalizada</string> + <string name="listSingleContact">Contautu únicu</string> + <string name="dialog_new_contact_account">Crear contautu na cuenta</string> + <string name="import_from_sim">Importar contautos de la tarxeta SIM</string> + <string name="import_from_sim_number">Importar dende tarxeta SIM #<xliff:g id="sim_number" example="2">%d</xliff:g></string> + <string name="import_from_sdcard" product="default">Importar d\'almacenamientu</string> + <string name="cancel_import_confirmation_message">¿Quies encaboxar la importación de <xliff:g id="FILENAME">%s</xliff:g>?</string> + <string name="cancel_export_confirmation_message">¿Quies encaboxar la esportación de <xliff:g id="FILENAME">%s</xliff:g>?</string> + <string name="cancel_vcard_import_or_export_failed">Fallu al encaboxar la importación/esportación de vCard</string> + <string name="fail_reason_unknown">Fallu desconocíu</string> + <string name="fail_reason_could_not_open_file">Nun pudo abrise\'l ficheru \"<xliff:g id="FILE_NAME">%s</xliff:g>" (<xliff:g id="EXACT_REASON">%s</xliff:g>).</string> + <string name="fail_reason_could_not_initialize_exporter">Nun pudo aniciase l\'esportador (\"<xliff:g id="EXACT_REASON">%s</xliff:g>\").</string> + <string name="fail_reason_no_exportable_contact">Nun hai contautos qu\'esportar.</string> + <string name="fail_reason_error_occurred_during_export">Hebo un fallu al esportar (\"<xliff:g id="EXACT_REASON">%s</xliff:g>\").</string> + <string name="fail_reason_too_long_filename">El nome de ficheru ye enforma llargu (\"<xliff:g id="FILENAME">%s</xliff:g>\").</string> + <string name="fail_reason_too_many_vcard" product="nosdcard">Hai munchos ficheros vCard nel almacenamientu.</string> + <string name="fail_reason_too_many_vcard" product="default">Hai munchos ficheros vCard na tarxeta SD.</string> + <string name="fail_reason_io_error">Fallu de E/S</string> + <string name="fail_reason_low_memory_during_import">Nun hai bastante espaciu de memoria (el ficheru pue ser enforma grande).</string> + <string name="fail_reason_vcard_parse_error">Nun pudo analizase\'l ficheru vCard por un fallu inesperáu.</string> + <string name="fail_reason_not_supported">Formatu non almitíu</string> + <string name="fail_reason_failed_to_collect_vcard_meta_info">Nun pudieron recuperase los metadatos de los ficheros vCard.</string> + <string name="fail_reason_failed_to_read_files">Nun pudo importase ún o más ficheros (%s).</string> + <string name="exporting_vcard_finished_title">Esportación de <xliff:g id="FILENAME">%s</xliff:g> finada</string> + <string name="exporting_vcard_canceled_title">Encaboxóse la esportación de <xliff:g id="FILENAME">%s</xliff:g>.</string> + <string name="exporting_contact_list_title">Esportando datos de contautu...</string> + <string name="exporting_contact_list_message">Tán esportándose los tos datos de contautos a <xliff:g id="FILE_NAME">%s</xliff:g>.</string> + <string name="composer_failed_to_get_database_infomation">Nun pudo obtenese información de la base de datos.</string> + <string name="composer_has_no_exportable_contact" product="tablet">Nun hai contautos qu\'esportar. Si yá tienes contautos na tablet, ye dable que\'l fornidor de datos nun permita que s\'esporten los contautos del tablet.</string> + <string name="composer_has_no_exportable_contact" product="default">Nun hai contautos qu\'esportar. Si yá tienes contautos nel teléfonu, ye dable que\'l fornidor de datos nun permita que s\'esporten los contautos del teléfonu.</string> + <string name="composer_not_initialized">El redautor de vCard nun s\'anició correutamente.</string> + <string name="exporting_contact_failed_title">Fallu al esportar</string> + <string name="exporting_contact_failed_message">Nun s\'esportaron los datos de contautu(\"\n\"motivu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\").</string> + <string name="no_sdcard_message" product="nosdcard">Nun hai nengún almacenamientu.</string> + <string name="no_sdcard_message" product="default">Nun se deteutó nenguna tarxeta SD.</string> + <string name="confirm_export_message">La to llista de contautos va esportase al ficheru <xliff:g id="VCARD_FILENAME">%s</xliff:g>.</string> + <string name="importing_vcard_description">Importando <xliff:g id="NAME">%s</xliff:g>...</string> + <string name="reading_vcard_failed_title">Fallu al lleer los datos de vCard</string> + <string name="reading_vcard_canceled_title">Llectura de datos de vCard encaboxada</string> + <string name="importing_vcard_finished_title">Importación de <xliff:g id="FILENAME">%s</xliff:g> de vCard finada</string> + <string name="importing_vcard_canceled_title">Encaboxóse la importación de <xliff:g id="FILENAME">%s</xliff:g>.</string> + <string name="vcard_import_will_start_message"><xliff:g id="FILENAME">%s</xliff:g> va importase darréu.</string> + <string name="vcard_import_will_start_message_with_default_name">El ficheru va importase darréu.</string> + <string name="vcard_import_request_rejected_message">Refugóse la solicitú d\'importación de vCard. Inténtalo de nueves más tarde.</string> + <string name="vcard_export_will_start_message"><xliff:g id="FILENAME">%s</xliff:g> va esportase darréu.</string> + <string name="vcard_export_request_rejected_message">Refugóse la solicitú d\'esportación de vCard. Inténtalo de nueves más tarde.</string> + <string name="vcard_unknown_filename">contautu</string> + <string name="caching_vcard_message">Tán almacenándose los ficheros vCard na la caché. La importación va aniciase aína.</string> + <string name="percentage"><xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g></string> + <string name="vcard_import_failed">Fallu al importar el ficheru vCard</string> + <string name="import_failure_no_vcard_file" product="nosdcard">Nun s\'atoparon ficheros vCard nel almacenamientu.</string> + <string name="import_failure_no_vcard_file" product="default">Nun s\'atoparon ficheros vCard na tarxeta SD.</string> + <string name="nfc_vcard_file_name">Contautu recibíu per NFC</string> + <string name="confirm_export_title">¿Esportar contautos?</string> + <string name="select_vcard_title">Seleicionar ficheru vCard</string> + <string name="import_one_vcard_string">Importar un ficheru de vCard</string> + <string name="import_multiple_vcard_string">Importar dellos ficheros de vCard</string> + <string name="import_all_vcard_string">Importar tolos ficheros de vCard</string> + <string name="searching_vcard_message" product="nosdcard">Guetando por datos de vCard nel almacenamientu...</string> + <string name="searching_vcard_message" product="default">Guetando por datos de vCard na tarxeta SD...</string> + <string name="caching_vcard_title">Almacenando na caché...</string> + <string name="scanning_sdcard_failed_message" product="nosdcard">Nun pudo analizase l\'almacenamientu (motivu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\").</string> + <string name="scanning_sdcard_failed_message" product="default">Nun pudo analizase la tarxeta SD (motivu: \"<xliff:g id="FAIL_REASON">%s</xliff:g>\").</string> + <string name="progress_notifier_message">Importando <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g></string> + <string name="export_to_sdcard" product="default">Esportar a almacenamientu</string> + <string name="display_options_sort_list_by">Ordenar por</string> + <string name="display_options_sort_by_given_name">Nome</string> + <string name="display_options_sort_by_family_name">Apellíu</string> + <string name="display_options_view_names_as">Formatu nome</string> + <string name="display_options_view_given_name_first">Nome primero</string> + <string name="display_options_view_family_name_first">Apellíu primero</string> + <string name="share_visible_contacts">Compartir contautos visibles</string> + <string name="dialog_import_export">Importar/esportar contautos</string> + <string name="dialog_import">Importar contautos</string> + <string name="share_error">Nun pue compartise esti contautu.</string> + <string name="menu_search">Guetar</string> + <string name="menu_contacts_filter">Contautos qu\'amosar</string> + <string name="activity_title_contacts_filter">Contautos qu\'amosar</string> + <string name="custom_list_filter">Definición de vista personalizada</string> + <string name="hint_findContacts">Guetar contautos</string> + <string name="contactsFavoritesLabel">Favoritos</string> + <string name="listTotalAllContactsZero">Nun hai nengún contautu.</string> + <string name="listTotalAllContactsZeroCustom">Nun hai contautos visibles.</string> + <string name="listTotalAllContactsZeroStarred">Nun hai favoritos.</string> + <string name="listTotalAllContactsZeroGroup">Nengún contautu en <xliff:g id="name" example="Friends">%s</xliff:g></string> + <string name="menu_clear_frequents">Llimpiar frecuentes</string> + <string name="menu_select_sim">Seleicionar tarxeta SIM</string> + <string name="menu_accounts">Cuentes</string> + <string name="menu_import_export">Importar/esportar</string> + <string name="tab_font_family">sans-serif</string> + <string name="contact_status_update_attribution">per aciu de <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string> + <string name="contact_status_update_attribution_with_date"><xliff:g id="date" example="3 hours ago">%1$s</xliff:g> per aciu de <xliff:g id="source" example="Google Talk">%2$s</xliff:g></string> + <string name="letter_tile_letter_font_family">sans-serif-light</string> + <string name="action_menu_back_from_search">Parar la gueta</string> + <string name="description_clear_search">Llimpiar gueta</string> + <string name="search_font_family">sans-serif</string> + <string name="settings_contact_display_options_title">Opciones visualización contautos</string> +</resources> diff --git a/res/values-az-rAZ/cm_strings.xml b/res/values-az-rAZ/cm_strings.xml new file mode 100644 index 00000000..c0d1b6bf --- /dev/null +++ b/res/values-az-rAZ/cm_strings.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Yerli tablet hesabı</string> + <string name="local_storage_account" product="default">Yerli telefon hesabı</string> + <string name="label_groups">Qrup</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> / <xliff:g id="total_number">%2$s</xliff:g> fayl</string> + <string name="export_failed">İxrac uğursuz oldu</string> + <string name="export_finished">İxrac tamamlandı</string> + <string name="import_from_sim_select">İdxal olunacaq kartı seçin</string> + <string name="no_sdcard_title" product="nosdcard">Yaddaş əlçatmazdır</string> + <string name="no_sdcard_title" product="default">SD kart yoxdur</string> + <string name="deleteConfirmation_title">Şəxs silinsin?</string> + <string name="deleteConfirmation">Bu şəxs silinəcək.</string> + <string name="no_ip_number">IP nömrəsi yoxdur</string> + <string name="no_ip_number_on_sim_card">SIM kartda IP nömrəsi yoxdur</string> + <string name="ipcall_dialog_edit_hint">Zəhmət olmasa IP önəlavəsini daxil edin</string> + <string name="select_sim">SIM seç</string> +</resources> diff --git a/res/values-bn-rBD/cm_strings.xml b/res/values-bn-rBD/cm_strings.xml new file mode 100644 index 00000000..f0655567 --- /dev/null +++ b/res/values-bn-rBD/cm_strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">স্থানীয় ট্যাবলেট একাউন্ট</string> + <string name="export_to_sim">সিম কার্ডে রপ্তানি করুন</string> + <string name="select_sim">সিম নির্বাচন</string> +</resources> diff --git a/res/values-ca/cm_strings.xml b/res/values-ca/cm_strings.xml new file mode 100644 index 00000000..0ed51aea --- /dev/null +++ b/res/values-ca/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Compte local de la tauleta</string> + <string name="local_storage_account" product="default">Compte local del telèfon</string> + <string name="import_contacts_sim">Vols importar els contactes de la targeta SIM?</string> + <string name="manage_sim_contacts">Gestiona els contactes de la targeta SIM</string> + <string name="export_to_sim">Exporta a la targeta SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' no han pogut ser importats degur a un error d\'E/S</string> + <string name="contact_share_failed_toast">Només hi ha <xliff:g id="count">%d</xliff:g> contactes que puguin ser compartits</string> + <string name="label_groups">Grup</string> + <string name="exporting">S\'està exportant\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> de <xliff:g id="total_number">%2$s</xliff:g> fitxers</string> + <string name="export_failed">S\'ha produït un error en l\'exportació</string> + <string name="sim_card_full">La targeta SIM és plena</string> + <string name="export_finished">S\'ha finalitzat l\'exportació</string> + <string name="tag_too_long">El nom del contacte és massa llarg</string> + <string name="sim_contacts_not_loaded">No s\'han pogut carregar els contactes de la SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">S\'ha cancel·lat l\'exportació, %d element ha sigut exportat</item> + <item quantity="other">S\'ha cancel·lat l\'exportació, %d elements han sigut exportats</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> no té un número de telèfon o una adreça de correu electrònic</string> + <string name="import_from_sim_select">Tria la targeta a importar</string> + <string name="no_sdcard_title" product="nosdcard">Emmagatzematge no disponible</string> + <string name="no_sdcard_title" product="default">No hi ha targeta SD</string> + <string name="deleteConfirmation_title">Vols esborrar el contacte?</string> + <string name="deleteConfirmation">Aquest contacte serà esborrat.</string> + <string name="copy_done">El contacte ha sigut copiat satisfactòriament</string> + <string name="copy_failure">No s\'ha pogut copiar el contacte</string> + <string name="card_no_space">No s\'ha pogut copiar el contacte, la targeta SIM és plena</string> + <string name="settings_contact_display_options_description">Configura com són mostrats i ordenats els contactes.</string> + <string name="ip_call_by_slot">Trucada IP amb <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Sense número IP</string> + <string name="no_ip_number_on_sim_card">Sense número IP a la targeta SIM</string> + <string name="set_ip_number">Estableix un número IP</string> + <string name="ipcall_dialog_title">Ajustaments de trucada IP</string> + <string name="ipcall_dialog_edit_hint">Si us plau introdueix el prefix IP</string> + <string name="import_contacts_from_all_cards">Importa els contactes de totes les targetes SIM</string> + <string name="select_path">Selecciona la ruta</string> + <string name="select_sim">Selecciona SIM</string> +</resources> diff --git a/res/values-cs/cm_strings.xml b/res/values-cs/cm_strings.xml new file mode 100644 index 00000000..a10c6aa1 --- /dev/null +++ b/res/values-cs/cm_strings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokální účet tabletu</string> + <string name="local_storage_account" product="default">Lokální účet telefonu</string> + <string name="import_contacts_sim">Importovat kontakty ze SIM karty?</string> + <string name="manage_sim_contacts">Spravovat kontakty na SIM kartě</string> + <string name="export_to_sim">Exportovat na SIM kartu</string> + <string name="fail_reason_import_vcard">Z důvodu chyby přístupu nelze importovat „<xliff:g id="name">%s</xliff:g>“</string> + <string name="contact_share_failed_toast">Nelze sdílet více než <xliff:g id="count">%d</xliff:g> kontaktů</string> + <string name="label_groups">Skupina</string> + <string name="exporting">Exportování\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> z <xliff:g id="total_number">%2$s</xliff:g> souborů</string> + <string name="export_failed">Export se nezdařil</string> + <string name="sim_card_full">SIM karta je plná</string> + <string name="export_finished">Export dokončen</string> + <string name="tag_too_long">Jméno kontaktu je příliš dlouhé</string> + <string name="sim_contacts_not_loaded">Nelze načíst kontakty SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Export byl zrušen, %d kontakt byl exportován</item> + <item quantity="few">Export byl zrušen, %d kontakty byly exportovány</item> + <item quantity="other">Export byl zrušen, %d kontaktů bylo exportováno</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s </xliff:g> nemá telefonní číslo ani e-mailovou adresu</string> + <string name="import_from_sim_select">Vyberte kartu pro import</string> + <string name="no_sdcard_title" product="nosdcard">Úložiště nedostupné</string> + <string name="no_sdcard_title" product="default">Žádná SD karta</string> + <string name="deleteConfirmation_title">Odstranit kontakt?</string> + <string name="deleteConfirmation">Tento kontakt bude odstraněn.</string> + <string name="copy_done">Kontakt byl úspěšně zkopírován</string> + <string name="copy_failure">Kopírování kontaktu selhalo</string> + <string name="card_no_space">Kopírování kontaktu selhalo, SIM karta je plná</string> + <string name="settings_contact_display_options_description">Nastavit jak budou kontakty zobrazeny a řazeny.</string> + <string name="ip_call_by_slot">IP volání prostřednictvím <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Žádné IP číslo</string> + <string name="no_ip_number_on_sim_card">Žádné IP číslo na SIM kartě</string> + <string name="set_ip_number">Nastavit IP číslo</string> + <string name="ipcall_dialog_title">Nastavení IP volání</string> + <string name="ipcall_dialog_edit_hint">Zadejte prefix pro IP</string> + <string name="import_contacts_from_all_cards">Importovat kontakty ze všech SIM karet</string> + <string name="select_path">Vybrat cestu</string> + <string name="select_sim">Vybrat SIM kartu</string> +</resources> diff --git a/res/values-da/cm_strings.xml b/res/values-da/cm_strings.xml new file mode 100644 index 00000000..e6cd5b2e --- /dev/null +++ b/res/values-da/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokal tabletkonto</string> + <string name="local_storage_account" product="default">Lokal telefonkonto</string> + <string name="import_contacts_sim">Importér kontakter fra SIM-kort?</string> + <string name="manage_sim_contacts">Administrer SIM-kort kontakter</string> + <string name="export_to_sim">Eksportér til SIM-kortet</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' kunne ikke importeres på grund af en I/O-fejl</string> + <string name="contact_share_failed_toast">Ikke mere end <xliff:g id="count">%d</xliff:g> kontakter kan deles</string> + <string name="label_groups">Gruppe</string> + <string name="exporting">Eksporterer\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> af <xliff:g id="total_number">%2$s</xliff:g> filer</string> + <string name="export_failed">Eksport mislykkedes</string> + <string name="sim_card_full">SIM-kort er fyldt</string> + <string name="export_finished">Eksport afsluttet</string> + <string name="tag_too_long">Kontaktnavn er for langt</string> + <string name="sim_contacts_not_loaded">Kan ikke indlæse SIM-kontakter</string> + <plurals name="export_cancelled"> + <item quantity="one">Eksport blev annulleret, %d element blev eksporteret</item> + <item quantity="other">Eksport blev annulleret, %d elementer blev eksporteret</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> har ikke et telefonnummer eller en e-mail adresse</string> + <string name="import_from_sim_select">Vælg det kort, der skal importeres</string> + <string name="no_sdcard_title" product="nosdcard">Lager ikke tilgængelig</string> + <string name="no_sdcard_title" product="default">Intet SD-kort</string> + <string name="deleteConfirmation_title">Slet kontaktperson?</string> + <string name="deleteConfirmation">Denne kontaktperson vil blive slettet.</string> + <string name="copy_done">Kontakt blev kopieret korrekt</string> + <string name="copy_failure">Kopiering af kontaktpersonen mislykkedes</string> + <string name="card_no_space">Kopiering af kontaktpersonen mislykkedes, SIM-kortet er fyldt</string> + <string name="settings_contact_display_options_description">Konfigurer hvordan, dine kontakter vises og sorteres.</string> + <string name="ip_call_by_slot">IP-opkald med <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Intet IP-nummer</string> + <string name="no_ip_number_on_sim_card">Intet IP-nummer på SIM-kortet</string> + <string name="set_ip_number">Angiv IP-nummer</string> + <string name="ipcall_dialog_title">IP-opkaldsindstillinger</string> + <string name="ipcall_dialog_edit_hint">Indtast IP-præfiks</string> + <string name="import_contacts_from_all_cards">Importér kontakter fra alle SIM-kort</string> + <string name="select_path">Vælg sti</string> + <string name="select_sim">Vælg SIM</string> +</resources> diff --git a/res/values-de/cm_strings.xml b/res/values-de/cm_strings.xml new file mode 100644 index 00000000..2c175fc8 --- /dev/null +++ b/res/values-de/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokales Tablet-Konto</string> + <string name="local_storage_account" product="default">Lokales Telefon-Konto</string> + <string name="import_contacts_sim">Kontakte von der SIM-Karte importieren?</string> + <string name="manage_sim_contacts">Kontakte auf SIM-Karte verwalten</string> + <string name="export_to_sim">Auf SIM-Karte exportieren</string> + <string name="fail_reason_import_vcard">\"<xliff:g id="name">%s</xliff:g>\" konnte aufgrund eines I/O-Fehlers nicht importiert werden</string> + <string name="contact_share_failed_toast">Es können nicht mehr als <xliff:g id="count">%d</xliff:g> Kontakte geteilt werden</string> + <string name="label_groups">Gruppe</string> + <string name="exporting">Exportieren\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> von <xliff:g id="total_number">%2$s</xliff:g> Dateien</string> + <string name="export_failed">Exportieren fehlgeschlagen</string> + <string name="sim_card_full">SIM-Karte ist voll</string> + <string name="export_finished">Export abgeschlossen</string> + <string name="tag_too_long">Der Kontaktname ist zu lang</string> + <string name="sim_contacts_not_loaded">SIM-Kontakte konnten nicht geladen werden</string> + <plurals name="export_cancelled"> + <item quantity="one">Exportieren abgebrochen, %d Element wurde exportiert</item> + <item quantity="other">Exportieren abgebrochen, %d Elemente wurden exportiert</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> hat keine Telefonnummer oder E-Mail-Adresse</string> + <string name="import_from_sim_select">SIM-Karte zum Importieren wählen</string> + <string name="no_sdcard_title" product="nosdcard">Speicher nicht verfügbar</string> + <string name="no_sdcard_title" product="default">Keine SD-Karte</string> + <string name="deleteConfirmation_title">Kontakt löschen?</string> + <string name="deleteConfirmation">Dieser Kontakt wird gelöscht.</string> + <string name="copy_done">Kontakt wurde erfolgreich kopiert</string> + <string name="copy_failure">Kopieren des Kontaktes fehlgeschlagen</string> + <string name="card_no_space">Das Kopieren des Kontaktes ist fehlgeschlagen, da die SIM-Karte voll ist</string> + <string name="settings_contact_display_options_description">Konfigurieren Sie, wie Ihre Kontakte angezeigt und sortiert werden.</string> + <string name="ip_call_by_slot">VoIP-Anruf über <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Keine VoIP-Nummer</string> + <string name="no_ip_number_on_sim_card">Keine VoIP-Nummer auf der SIM-Karte</string> + <string name="set_ip_number">VoIP-Nummer festlegen</string> + <string name="ipcall_dialog_title">VoIP-Einstellungen</string> + <string name="ipcall_dialog_edit_hint">Bitte VoIP-Prefix eingeben</string> + <string name="import_contacts_from_all_cards">Kontakte von allen SIM-Karten importieren</string> + <string name="select_path">Pfad auswählen</string> + <string name="select_sim">SIM-Karte wählen</string> +</resources> diff --git a/res/values-el/cm_strings.xml b/res/values-el/cm_strings.xml new file mode 100644 index 00000000..ff219acb --- /dev/null +++ b/res/values-el/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Τοπικός λογαριασμός tablet</string> + <string name="local_storage_account" product="default">Τοπικός λογαριασμός τηλεφώνου</string> + <string name="import_contacts_sim">Εισαγωγή επαφών από την κάρτα SIM;</string> + <string name="manage_sim_contacts">Διαχείριση επαφών κάρτας SIM</string> + <string name="export_to_sim">Εξαγωγή στην κάρτα SIM</string> + <string name="fail_reason_import_vcard">Δεν ήταν δυνατή η εισαγωγή του \'<xliff:g id="name">%s</xliff:g>\' εξαιτίας σφάλματος εισόδου/εξόδου</string> + <string name="contact_share_failed_toast">Δεν είναι δυνατή η κοινή χρήση περισσότερων από <xliff:g id="count">%d</xliff:g> επαφών</string> + <string name="label_groups">Ομάδα</string> + <string name="exporting">Εξαγωγή\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> από <xliff:g id="total_number">%2$s</xliff:g> αρχεία</string> + <string name="export_failed">Η εξαγωγή απέτυχε</string> + <string name="sim_card_full">Η κάρτα SIM είναι γεμάτη</string> + <string name="export_finished">Η εξαγωγή ολοκληρώθηκε</string> + <string name="tag_too_long">Το όνομα της επαφής είναι πολύ μεγάλο</string> + <string name="sim_contacts_not_loaded">Δεν είναι δυνατή η φόρτωση των επαφών SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Η εξαγωγή ακυρώθηκε, %d επαφή εξήχθη</item> + <item quantity="other">Η εξαγωγή ακυρώθηκε, %d επαφές εξήχθησαν</item> + </plurals> + <string name="export_no_phone_or_email">Η επαφή <xliff:g id="name">%s</xliff:g> δεν έχει τηλεφωνικό αριθμό ή ηλεκτρονική διεύθυνση</string> + <string name="import_from_sim_select">Επιλέξτε κάρτα για εισαγωγή</string> + <string name="no_sdcard_title" product="nosdcard">Ο αποθ. χώρος δεν είναι διαθέσιμος</string> + <string name="no_sdcard_title" product="default">Δεν υπάρχει κάρτα SD</string> + <string name="deleteConfirmation_title">Διαγραφή επαφής;</string> + <string name="deleteConfirmation">Αυτή η επαφή θα διαγραφεί.</string> + <string name="copy_done">Η επαφή αντιγράφηκε με επιτυχία</string> + <string name="copy_failure">Η αντιγραφή της επαφής απέτυχε</string> + <string name="card_no_space">Η αντιγραφή της επαφής απέτυχε, η κάρτα SIM είναι γεμάτη</string> + <string name="settings_contact_display_options_description">Ρυθμίσετε το πώς εμφανίζονται και ταξινομούνται οι επαφές σας.</string> + <string name="ip_call_by_slot">Κλήση IP μέσω <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Κανένας αριθμός IP</string> + <string name="no_ip_number_on_sim_card">Κανένας αριθμός IP στην κάρτα SIM</string> + <string name="set_ip_number">Ορισμός αριθμού IP</string> + <string name="ipcall_dialog_title">Ρυθμίσεις κλήσεων IP</string> + <string name="ipcall_dialog_edit_hint">Παρακαλώ εισάγετε το πρόθεμα της IP</string> + <string name="import_contacts_from_all_cards">Εισαγωγή επαφών από όλες τις κάρτες SIM</string> + <string name="select_path">Επιλέξτε διαδρομή</string> + <string name="select_sim">Επιλέξτε SIM</string> +</resources> diff --git a/res/values-en-rAU/cm_strings.xml b/res/values-en-rAU/cm_strings.xml new file mode 100644 index 00000000..54626950 --- /dev/null +++ b/res/values-en-rAU/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Local tablet account</string> + <string name="local_storage_account" product="default">Local phone account</string> + <string name="import_contacts_sim">Import contacts from SIM card?</string> + <string name="manage_sim_contacts">Manage SIM card contacts</string> + <string name="export_to_sim">Export to SIM card</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' could not be imported due to an I/O error</string> + <string name="contact_share_failed_toast">No more than <xliff:g id="count">%d</xliff:g> contacts can be shared</string> + <string name="label_groups">Group</string> + <string name="exporting">Exporting\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> of <xliff:g id="total_number">%2$s</xliff:g> files</string> + <string name="export_failed">Export failed</string> + <string name="sim_card_full">SIM card is full</string> + <string name="export_finished">Export finished</string> + <string name="tag_too_long">Contact name is too long</string> + <string name="sim_contacts_not_loaded">Unable to load SIM contacts</string> + <plurals name="export_cancelled"> + <item quantity="one">Export was cancelled, %d item was exported</item> + <item quantity="other">Export was cancelled, %d items were exported</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> does not have a phone number or email address</string> + <string name="import_from_sim_select">Choose card to import</string> + <string name="no_sdcard_title" product="nosdcard">Storage unavailable</string> + <string name="no_sdcard_title" product="default">No SD card</string> + <string name="deleteConfirmation_title">Delete contact?</string> + <string name="deleteConfirmation">This contact will be deleted.</string> + <string name="copy_done">Contact was copied successfully</string> + <string name="copy_failure">Copying the contact failed</string> + <string name="card_no_space">Copying the contact failed, SIM card is full</string> + <string name="settings_contact_display_options_description">Configure how your contacts are displayed and sorted.</string> + <string name="ip_call_by_slot">IP call via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">No IP number</string> + <string name="no_ip_number_on_sim_card">No IP number on SIM card</string> + <string name="set_ip_number">Set IP number</string> + <string name="ipcall_dialog_title">IP call settings</string> + <string name="ipcall_dialog_edit_hint">Please input the IP prefix</string> + <string name="import_contacts_from_all_cards">Import contacts from all SIM cards</string> + <string name="select_path">Select path</string> + <string name="select_sim">Select SIM</string> +</resources> diff --git a/res/values-en-rIN/cm_strings.xml b/res/values-en-rIN/cm_strings.xml new file mode 100644 index 00000000..54626950 --- /dev/null +++ b/res/values-en-rIN/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Local tablet account</string> + <string name="local_storage_account" product="default">Local phone account</string> + <string name="import_contacts_sim">Import contacts from SIM card?</string> + <string name="manage_sim_contacts">Manage SIM card contacts</string> + <string name="export_to_sim">Export to SIM card</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' could not be imported due to an I/O error</string> + <string name="contact_share_failed_toast">No more than <xliff:g id="count">%d</xliff:g> contacts can be shared</string> + <string name="label_groups">Group</string> + <string name="exporting">Exporting\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> of <xliff:g id="total_number">%2$s</xliff:g> files</string> + <string name="export_failed">Export failed</string> + <string name="sim_card_full">SIM card is full</string> + <string name="export_finished">Export finished</string> + <string name="tag_too_long">Contact name is too long</string> + <string name="sim_contacts_not_loaded">Unable to load SIM contacts</string> + <plurals name="export_cancelled"> + <item quantity="one">Export was cancelled, %d item was exported</item> + <item quantity="other">Export was cancelled, %d items were exported</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> does not have a phone number or email address</string> + <string name="import_from_sim_select">Choose card to import</string> + <string name="no_sdcard_title" product="nosdcard">Storage unavailable</string> + <string name="no_sdcard_title" product="default">No SD card</string> + <string name="deleteConfirmation_title">Delete contact?</string> + <string name="deleteConfirmation">This contact will be deleted.</string> + <string name="copy_done">Contact was copied successfully</string> + <string name="copy_failure">Copying the contact failed</string> + <string name="card_no_space">Copying the contact failed, SIM card is full</string> + <string name="settings_contact_display_options_description">Configure how your contacts are displayed and sorted.</string> + <string name="ip_call_by_slot">IP call via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">No IP number</string> + <string name="no_ip_number_on_sim_card">No IP number on SIM card</string> + <string name="set_ip_number">Set IP number</string> + <string name="ipcall_dialog_title">IP call settings</string> + <string name="ipcall_dialog_edit_hint">Please input the IP prefix</string> + <string name="import_contacts_from_all_cards">Import contacts from all SIM cards</string> + <string name="select_path">Select path</string> + <string name="select_sim">Select SIM</string> +</resources> diff --git a/res/values-es/cm_strings.xml b/res/values-es/cm_strings.xml new file mode 100644 index 00000000..9a31f140 --- /dev/null +++ b/res/values-es/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Cuenta local del tablet</string> + <string name="local_storage_account" product="default">Cuenta local del teléfono</string> + <string name="import_contacts_sim">¿Importar contactos de la tarjeta SIM?</string> + <string name="manage_sim_contacts">Gestionar los contactos de la tarjeta SIM</string> + <string name="export_to_sim">Exportar a la tarjeta SIM</string> + <string name="fail_reason_import_vcard">\u00AB<xliff:g id="name">%s</xliff:g>\u00BB no puede ser importado debido a un error de E/S</string> + <string name="contact_share_failed_toast">No pueden ser compartidos más de <xliff:g id="count">%d</xliff:g> contactos</string> + <string name="label_groups">Grupo</string> + <string name="exporting">Exportando\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> de <xliff:g id="total_number">%2$s</xliff:g> archivos</string> + <string name="export_failed">Fallo al exportar</string> + <string name="sim_card_full">La tarjeta SIM está llena</string> + <string name="export_finished">Exportación finalizada</string> + <string name="tag_too_long">El nombre del contacto es demasiado largo</string> + <string name="sim_contacts_not_loaded">No se puede cargar los contactos de la tarjeta SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Exportación cancelada. Se exportó %d contacto</item> + <item quantity="other">Exportación cancelada. Se exportaron %d contactos</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> no tiene un número de teléfono o una dirección de correo</string> + <string name="import_from_sim_select">Elige una tarjeta para importar</string> + <string name="no_sdcard_title" product="nosdcard">Almacenamiento no disponible</string> + <string name="no_sdcard_title" product="default">No hay tarjeta SD</string> + <string name="deleteConfirmation_title">¿Eliminar contacto?</string> + <string name="deleteConfirmation">Este contacto será eliminado.</string> + <string name="copy_done">Contacto copiado satisfactoriamente</string> + <string name="copy_failure">Falló la copia del contacto</string> + <string name="card_no_space">Falló la copia de todos los contactos. La tarjeta SIM está llena</string> + <string name="settings_contact_display_options_description">Configurar cómo se muestran y se ordenan tus contactos.</string> + <string name="ip_call_by_slot">Llamada IP vía <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">No hay número IP</string> + <string name="no_ip_number_on_sim_card">No hay número IP en la tarjeta SIM</string> + <string name="set_ip_number">Establecer número IP</string> + <string name="ipcall_dialog_title">Configuracion de llamadas IP</string> + <string name="ipcall_dialog_edit_hint">Por favor, introduce el prefijo IP</string> + <string name="import_contacts_from_all_cards">Importar contactos de todas las tarjetas SIM</string> + <string name="select_path">Selecciona la ruta</string> + <string name="select_sim">Seleccionar SIM</string> +</resources> diff --git a/res/values-et-rEE/cm_strings.xml b/res/values-et-rEE/cm_strings.xml new file mode 100644 index 00000000..b72098a0 --- /dev/null +++ b/res/values-et-rEE/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Kohalik tahvli konto</string> + <string name="local_storage_account" product="default">Kohalik telefoni konto</string> + <string name="import_contacts_sim">Impordi kontaktid SIM-kaardilt?</string> + <string name="manage_sim_contacts">Halda SIM-kaardi kontakte</string> + <string name="export_to_sim">Ekspordi SIM-kaardile</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' ei saa importida, kuna ilmnes I/O tõrge</string> + <string name="contact_share_failed_toast">Enam kui <xliff:g id="count">%d </xliff:g> kontakti ei saa jagada</string> + <string name="label_groups">Grupp</string> + <string name="exporting">Ekspordin\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> fail <xliff:g id="total_number">%2$s</xliff:g>-st</string> + <string name="export_failed">Eksportimine nurjus</string> + <string name="sim_card_full">SIM-kaart on täis</string> + <string name="export_finished">Eksport lõpetatud</string> + <string name="tag_too_long">Kontakti nimi on liiga pikk</string> + <string name="sim_contacts_not_loaded">Ei saa laadida kontakte SIM-kaardilt</string> + <plurals name="export_cancelled"> + <item quantity="one">Eksport katkestati, %d kirje eksporditi</item> + <item quantity="other">Eksport katkestati, %d kirjet eksporditi</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> on ilma telefoni numbri või e-posti aadressita</string> + <string name="import_from_sim_select">Vali SIM-kaart importimiseks</string> + <string name="no_sdcard_title" product="nosdcard">Mälu pole saadaval</string> + <string name="no_sdcard_title" product="default">SD kaarti pole</string> + <string name="deleteConfirmation_title">Kustuta kontakt?</string> + <string name="deleteConfirmation">See kontakt kustutatakse.</string> + <string name="copy_done">Kontakt kopeeriti edukalt</string> + <string name="copy_failure">Kontakti kopeerimine nurjus</string> + <string name="card_no_space">Kontakti kopeerimine nurjus, SIM-kaart on täis</string> + <string name="settings_contact_display_options_description">Saate seadistada, kuidas kontakte kuvada ja sorteerida.</string> + <string name="ip_call_by_slot">IP kõne läbi <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Ei ole IP number</string> + <string name="no_ip_number_on_sim_card">Ei ole IP numbrit SIM-kaardil</string> + <string name="set_ip_number">Määra IP number</string> + <string name="ipcall_dialog_title">IP kõne seaded</string> + <string name="ipcall_dialog_edit_hint">Sisestage IP eesliide</string> + <string name="import_contacts_from_all_cards">Impordi kontaktid kõikidelt SIM-kaartidelt</string> + <string name="select_path">Vali teekond</string> + <string name="select_sim">Vali SIM-kaart</string> +</resources> diff --git a/res/values-eu-rES/cm_strings.xml b/res/values-eu-rES/cm_strings.xml new file mode 100644 index 00000000..83343617 --- /dev/null +++ b/res/values-eu-rES/cm_strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Tablet-aren tokiko kontua</string> + <string name="local_storage_account" product="default">Telefonoaren tokiko kontua</string> +</resources> diff --git a/res/values-fi/cm_strings.xml b/res/values-fi/cm_strings.xml new file mode 100644 index 00000000..2ac50502 --- /dev/null +++ b/res/values-fi/cm_strings.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Paikallinen tablet-tili</string> + <string name="local_storage_account" product="default">Paikallinen puhelin-tili</string> + <string name="import_contacts_sim">Tuo yhteystiedot SIM-kortilta?</string> + <string name="manage_sim_contacts">Hallitse SIM-kortin yhteystietoja</string> + <string name="export_to_sim">Vie SIM-kortille</string> + <string name="fail_reason_import_vcard">Yhteystietoa \'<xliff:g id="name">%s</xliff:g>\' ei voitu tuoda I/O-virheen takia</string> + <string name="contact_share_failed_toast">Enintään <xliff:g id="count">%d</xliff:g> yhteystietoa voidaan jakaa</string> + <string name="label_groups">Ryhmä</string> + <string name="exporting">Viedään\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g>/<xliff:g id="total_number">%2$s</xliff:g> tiedostoa</string> + <string name="export_failed">Vienti epäonnistui</string> + <string name="sim_card_full">SIM-kortti on täynnä</string> + <string name="export_finished">Vienti valmis</string> + <string name="tag_too_long">Yhteystiedon nimi on liian pitkä</string> + <string name="sim_contacts_not_loaded">Ei voi ladata SIM-kortin yhteystietoja</string> + <string name="export_no_phone_or_email">Yhteystiedolla <xliff:g id="name">%s</xliff:g> ei ole puhelinnumeroa tai sähköpostiosoitetta</string> + <string name="import_from_sim_select">Valitse kortti josta tuodaan</string> + <string name="no_sdcard_title" product="nosdcard">Tallennustila ei saatavilla</string> + <string name="no_sdcard_title" product="default">Ei SD-korttia</string> + <string name="deleteConfirmation_title">Poista yhteystieto?</string> + <string name="deleteConfirmation">Tämä yhteystieto poistetaan.</string> + <string name="copy_done">Yhteystieto kopioitu onnistuneesti</string> + <string name="copy_failure">Yhteystiedon kopioiminen epäonnistui</string> + <string name="card_no_space">Yhteystiedon kopioiminen epäonnistui, SIM-kortti on täynnä</string> + <string name="settings_contact_display_options_description">Määritä, kuinka yhteystiedot näytetään ja lajitellaan.</string> + <string name="ip_call_by_slot">IP-puhelu <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Ei IP-numeroa</string> + <string name="no_ip_number_on_sim_card">Ei IP-numeroa SIM-kortilla</string> + <string name="set_ip_number">Aseta IP-numero</string> + <string name="ipcall_dialog_title">IP-puheluasetukset</string> + <string name="ipcall_dialog_edit_hint">Anna IP:n etuliite</string> + <string name="import_contacts_from_all_cards">Tuo yhteystietoja kaikilta SIM-korteilta</string> + <string name="select_path">Valitse polku</string> + <string name="select_sim">Valitse SIM</string> +</resources> diff --git a/res/values-fr/cm_strings.xml b/res/values-fr/cm_strings.xml new file mode 100644 index 00000000..12176218 --- /dev/null +++ b/res/values-fr/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Compte local de la tablette</string> + <string name="local_storage_account" product="default">Compte local du téléphone</string> + <string name="import_contacts_sim">Importer les contacts depuis la carte SIM ?</string> + <string name="manage_sim_contacts">Gérer les contacts de la carte SIM</string> + <string name="export_to_sim">Exporter vers la carte SIM</string> + <string name="fail_reason_import_vcard">« <xliff:g id="name">%s</xliff:g> » n\'a pas pu être importé en raison d\'une erreur I/O</string> + <string name="contact_share_failed_toast">Vous ne pouvez pas partager plus de <xliff:g id="count">%d</xliff:g> contacts</string> + <string name="label_groups">Groupe</string> + <string name="exporting">Exportation\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> sur <xliff:g id="total_number">%2$s</xliff:g> fichiers</string> + <string name="export_failed">Échec de l\'exportation</string> + <string name="sim_card_full">Carte SIM saturée</string> + <string name="export_finished">Export terminé</string> + <string name="tag_too_long">Nom du contact trop long</string> + <string name="sim_contacts_not_loaded">Impossible de charger les contacts SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">L\'exportation à été annulée, %d élément a été exporté</item> + <item quantity="other">L\'exportation à été annulée, %d éléments ont été exportés</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> n\'a pas de numéro de téléphone ou d\'adresse e-mail</string> + <string name="import_from_sim_select">Choisissez la carte SIM à importer</string> + <string name="no_sdcard_title" product="nosdcard">Stockage non disponible</string> + <string name="no_sdcard_title" product="default">Aucune carte SD</string> + <string name="deleteConfirmation_title">Supprimer le contact ?</string> + <string name="deleteConfirmation">Ce contact sera supprimé.</string> + <string name="copy_done">Le contact a été copié avec succès</string> + <string name="copy_failure">Copie du contact échouée</string> + <string name="card_no_space">Copie du contact échouée, la carte SIM est saturée</string> + <string name="settings_contact_display_options_description">Configurer comment vos contacts sont affichés et triés.</string> + <string name="ip_call_by_slot">Appel IP via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Aucun numéro IP</string> + <string name="no_ip_number_on_sim_card">Aucun numéro IP sur la carte SIM</string> + <string name="set_ip_number">Définir un numéro IP</string> + <string name="ipcall_dialog_title">Paramètres d\'appels IP</string> + <string name="ipcall_dialog_edit_hint">Veuillez entrer le préfixe IP</string> + <string name="import_contacts_from_all_cards">Importer les contacts de toutes les cartes SIM</string> + <string name="select_path">Sélectionner un répertoire</string> + <string name="select_sim">Sélectionner la SIM</string> +</resources> diff --git a/res/values-gl-rES/cm_strings.xml b/res/values-gl-rES/cm_strings.xml new file mode 100644 index 00000000..87dba162 --- /dev/null +++ b/res/values-gl-rES/cm_strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Conta local do tablet</string> + <string name="local_storage_account" product="default">Conta local do teléfono</string> +</resources> diff --git a/res/values-hr/cm_strings.xml b/res/values-hr/cm_strings.xml new file mode 100644 index 00000000..336acdf9 --- /dev/null +++ b/res/values-hr/cm_strings.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokalni tablet račun</string> + <string name="local_storage_account" product="default">Lokalni račun telefona</string> +</resources> diff --git a/res/values-hu/cm_strings.xml b/res/values-hu/cm_strings.xml new file mode 100644 index 00000000..53bebee3 --- /dev/null +++ b/res/values-hu/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Helyi táblagép fiók</string> + <string name="local_storage_account" product="default">Helyi telefon fiók</string> + <string name="import_contacts_sim">Importálja a névjegyeket a SIM-kártyáról?</string> + <string name="manage_sim_contacts">SIM-kártya névjegyek kezelése</string> + <string name="export_to_sim">Exportálás SIM kártyára</string> + <string name="fail_reason_import_vcard">\"<xliff:g id="name">%s</xliff:g>\" I/O hiba miatt nem lehetett importálni</string> + <string name="contact_share_failed_toast"><xliff:g id="count">%d</xliff:g> névjegynél több nem osztható meg</string> + <string name="label_groups">Csoport</string> + <string name="exporting">Exportálás\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> / <xliff:g id="total_number">%2$s</xliff:g> fájl</string> + <string name="export_failed">Exportálás sikertelen</string> + <string name="sim_card_full">SIM-kártya megtelt</string> + <string name="export_finished">Exportálás kész</string> + <string name="tag_too_long">A névjegynél megadott név túl hosszú</string> + <string name="sim_contacts_not_loaded">Nem sikerült betölteni a SIM névjegyeket</string> + <plurals name="export_cancelled"> + <item quantity="one">Exportálás megszakítva, %d elem lett importálva</item> + <item quantity="other">Exportálás megszakítva, %d elem lett importálva</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> nem rendelkezik telefonszámmal, vagy e-mail címmel</string> + <string name="import_from_sim_select">Kártya kiválasztása importáláshoz</string> + <string name="no_sdcard_title" product="nosdcard">A tárhely nem érhető el</string> + <string name="no_sdcard_title" product="default">Nincs SD kártya</string> + <string name="deleteConfirmation_title">Törli a névjegyet?</string> + <string name="deleteConfirmation">Ez a névjegy törlésre kerül.</string> + <string name="copy_done">A névjegy másolása sikeres</string> + <string name="copy_failure">A névjegy másolása sikertelen</string> + <string name="card_no_space">A névjegy másolása sikertelen, a SIM-kártya megtelt</string> + <string name="settings_contact_display_options_description">Névjegy megjelenítési lehetőségei.</string> + <string name="ip_call_by_slot">IP hívás a következővel: <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nincs IP szám</string> + <string name="no_ip_number_on_sim_card">Nincs IP szám a SIM kártyán</string> + <string name="set_ip_number">IP cím beállítása</string> + <string name="ipcall_dialog_title">IP hívás beállításai</string> + <string name="ipcall_dialog_edit_hint">Kérem adja meg az IP előtagot</string> + <string name="import_contacts_from_all_cards">Névjegyek importálása az összes SIM-kártyáról</string> + <string name="select_path">Útvonal kiválasztása</string> + <string name="select_sim">SIM kiválasztása</string> +</resources> diff --git a/res/values-in/cm_strings.xml b/res/values-in/cm_strings.xml new file mode 100644 index 00000000..69abdb9c --- /dev/null +++ b/res/values-in/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Akun lokal tablet</string> + <string name="local_storage_account" product="default">Akun lokal telepon</string> + <string name="import_contacts_sim">Impor kontak dari kartu SIM?</string> + <string name="manage_sim_contacts">Kelola kontak kartu SIM</string> + <string name="export_to_sim">Ekspor ke kartu SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' tidak dapat diimpor karena kesalahan I/O</string> + <string name="contact_share_failed_toast">Tidak lebih dari <xliff:g id="count">%d</xliff:g> kontak dapat ditambahkan</string> + <string name="label_groups">Grup</string> + <string name="exporting">Mengekspor\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> dari <xliff:g id="total_number">%2$s</xliff:g> berkas</string> + <string name="export_failed">Ekspor gagal</string> + <string name="sim_card_full">Kartu SIM penuh</string> + <string name="export_finished">Ekspor selesai</string> + <string name="tag_too_long">Nama kontak terlalu panjang</string> + <string name="sim_contacts_not_loaded">Tidak dapat memuat kontak SIM</string> + <plurals name="export_cancelled"> + <item quantity="other">Ekspor dibatalkan, %d item telah diekspor</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> tidak memiliki nomor telepon atau alamat email</string> + <string name="import_from_sim_select">Pilih kartu untuk mengimpor</string> + <string name="no_sdcard_title" product="nosdcard">Penyimpanan tidak tersedia</string> + <string name="no_sdcard_title" product="default">Tidak ada kartu SD</string> + <string name="deleteConfirmation_title">Hapus kontak?</string> + <string name="deleteConfirmation">Kontak ini akan dihapus.</string> + <string name="copy_done">Kontak berhasil disalin</string> + <string name="copy_failure">Menyalin kontak gagal</string> + <string name="card_no_space">Menyalin kontak gagal, kartu SIM penuh</string> + <string name="settings_contact_display_options_description">Konfigurasi bagaimana kontak Anda ditampilkan dan diurutkan.</string> + <string name="ip_call_by_slot">Panggilan IP melalui <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Tidak ada Nomor IP</string> + <string name="no_ip_number_on_sim_card">Tidak ada Nomor IP pada kartu SIM</string> + <string name="set_ip_number">Atur nomor IP</string> + <string name="ipcall_dialog_title">Pengaturan panggilan IP</string> + <string name="ipcall_dialog_edit_hint">Silahkan memasukkan awalan IP</string> + <string name="import_contacts_from_all_cards">Impor kontak dari semua kartu SIM</string> + <string name="select_path">Pilih path</string> + <string name="select_sim">Pilih SIM</string> +</resources> diff --git a/res/values-it/cm_strings.xml b/res/values-it/cm_strings.xml new file mode 100644 index 00000000..0a894806 --- /dev/null +++ b/res/values-it/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Account locale tablet</string> + <string name="local_storage_account" product="default">Account locale telefono</string> + <string name="import_contacts_sim">Importare i contatti dalla scheda SIM?</string> + <string name="manage_sim_contacts">Gestisci i contatti della SIM</string> + <string name="export_to_sim">Esporta nella SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' non possono essere importati a causa di un errore di I/O</string> + <string name="contact_share_failed_toast">Non possono essere condivisi più di <xliff:g id="count">%d</xliff:g> contatti</string> + <string name="label_groups">Gruppo</string> + <string name="exporting">Esportando\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> di <xliff:g id="total_number">%2$s</xliff:g> file</string> + <string name="export_failed">Esportazione fallita</string> + <string name="sim_card_full">Scheda SIM piena</string> + <string name="export_finished">Esportazione completata</string> + <string name="tag_too_long">Nome del contatto troppo lungo</string> + <string name="sim_contacts_not_loaded">Impossibile caricare contatti SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Importazione annullata, %d elemento è stato eliminato</item> + <item quantity="other">Importazione annullata, %d elementi sono stati eliminati</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> non ha un numero di telefono o un indirizzo email</string> + <string name="import_from_sim_select">Scegli la scheda da importare</string> + <string name="no_sdcard_title" product="nosdcard">Memoria non disponibile</string> + <string name="no_sdcard_title" product="default">Nessuna scheda SD</string> + <string name="deleteConfirmation_title">Eliminare il contatto?</string> + <string name="deleteConfirmation">Questo contatto sarà eliminato.</string> + <string name="copy_done">Contatto copiato con successo</string> + <string name="copy_failure">Copia del contatto fallita</string> + <string name="card_no_space">Copia del contatto fallita, la SIM è piena</string> + <string name="settings_contact_display_options_description">Configurare la visualizzazione dei contatti.</string> + <string name="ip_call_by_slot">Chiamata IP con <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nessun numero IP</string> + <string name="no_ip_number_on_sim_card">Nessun numero IP sulla SIM</string> + <string name="set_ip_number">Imposta numero IP</string> + <string name="ipcall_dialog_title">Impostazioni chiamata IP</string> + <string name="ipcall_dialog_edit_hint">Inserisci il prefisso IP</string> + <string name="import_contacts_from_all_cards">Importa i contatti da tutte le schede SIM</string> + <string name="select_path">Seleziona percorso</string> + <string name="select_sim">Seleziona SIM</string> +</resources> diff --git a/res/values-iw/cm_strings.xml b/res/values-iw/cm_strings.xml new file mode 100644 index 00000000..a2555e34 --- /dev/null +++ b/res/values-iw/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">חשבון טאבלט מקומי</string> + <string name="local_storage_account" product="default">חשבון סמארטפון מקומי</string> + <string name="import_contacts_sim">לייבא אנשי קשר מכרטיס ה-SIM?</string> + <string name="manage_sim_contacts">נהל אנשי קשר ב-SIM</string> + <string name="export_to_sim">יצא לכרטיס SIM</string> + <string name="fail_reason_import_vcard">הייבוא של \'<xliff:g id="name">%s</xliff:g>\' נכשל עקב שגיאת קלט/פלט</string> + <string name="contact_share_failed_toast">לא ניתן לשתף יותר מ- <xliff:g id="count">%d</xliff:g> אנשי קשר</string> + <string name="label_groups">קבוצה</string> + <string name="exporting">מייצא\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number"> %1$s </xliff:g> מ- <xliff:g id="total_number"> %2$s </xliff:g> קבצים</string> + <string name="export_failed">הייצוא נכשל</string> + <string name="sim_card_full">כרטיס ה-SIM מלא</string> + <string name="export_finished">הייצוא הסתיים</string> + <string name="tag_too_long">שם איש הקשר ארוך מדי</string> + <string name="sim_contacts_not_loaded">לא ניתן לטעון את אנשי הקשר מה-SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">הייבוא בוטל, פריט %d יובא</item> + <item quantity="other">הייבוא בוטל, %d פריטים יובאו</item> + </plurals> + <string name="export_no_phone_or_email">ל<xliff:g id="name">%s</xliff:g> אין מספר טלפון או כתובת דוא\"ל</string> + <string name="import_from_sim_select">בחר כרטיס לייבוא</string> + <string name="no_sdcard_title" product="nosdcard">שטח אחסון אינו זמין</string> + <string name="no_sdcard_title" product="default">אין כרטיס זיכרון</string> + <string name="deleteConfirmation_title">למחוק איש קשר?</string> + <string name="deleteConfirmation">איש קשר זה יימחק.</string> + <string name="copy_done">איש הקשר הועתק בהצלחה</string> + <string name="copy_failure">העתקת איש הקשר נכשלה</string> + <string name="card_no_space">העתקת איש הקשר נכשלה, כרטיס ה-SIM מלא</string> + <string name="settings_contact_display_options_description">הגדר כיצד אנשי הקשר שלך יוצגו ובאיזה סדר.</string> + <string name="ip_call_by_slot">שיחת IP דרך <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">אין מספר IP</string> + <string name="no_ip_number_on_sim_card">אין מספר IP בכרטיס ה-SIM</string> + <string name="set_ip_number">הכנס מספר IP</string> + <string name="ipcall_dialog_title">הגדרות שיחת IP</string> + <string name="ipcall_dialog_edit_hint">הזן את קידומת ה-IP</string> + <string name="import_contacts_from_all_cards">ייבא אנשי קשר מכל כרטיסי ה-SIM</string> + <string name="select_path">בחר נתיב</string> + <string name="select_sim">בחר SIM</string> +</resources> diff --git a/res/values-ja/cm_strings.xml b/res/values-ja/cm_strings.xml new file mode 100644 index 00000000..7a1325fd --- /dev/null +++ b/res/values-ja/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">タブレットのローカルアカウント</string> + <string name="local_storage_account" product="default">携帯電話のローカルアカウント</string> + <string name="import_contacts_sim">SIMカードから連絡先をインポートしますか?</string> + <string name="manage_sim_contacts">SIMカードの連絡先を管理</string> + <string name="export_to_sim">SIMカードにエクスポート</string> + <string name="fail_reason_import_vcard">「<xliff:g id="name">%s</xliff:g>」はI/0エラーによりインポートできませんでした</string> + <string name="contact_share_failed_toast"><xliff:g id="count">%d</xliff:g>件以上の連絡先は共有できません</string> + <string name="label_groups">グループ</string> + <string name="exporting">エクスポート中\u2026</string> + <string name="reading_vcard_files"><xliff:g id="total_number">%2$s</xliff:g>個のうち<xliff:g id="current_number">%1$s</xliff:g>個のファイル</string> + <string name="export_failed">エクスポートできませんでした</string> + <string name="sim_card_full">SIMカードがいっぱいです</string> + <string name="export_finished">エクスポートが完了しました</string> + <string name="tag_too_long">連絡先の名前が長すぎます</string> + <string name="sim_contacts_not_loaded">SIMの連絡先を読み込めませんでした</string> + <plurals name="export_cancelled"> + <item quantity="other">エクスポートはキャンセルされました、%d個のアイテムがエクスポートされました</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g>には電話番号またはメールアドレスがありません</string> + <string name="import_from_sim_select">インポートするカードを選択</string> + <string name="no_sdcard_title" product="nosdcard">ストレージが利用できません</string> + <string name="no_sdcard_title" product="default">SDカードがありません</string> + <string name="deleteConfirmation_title">連絡先を削除しますか?</string> + <string name="deleteConfirmation">この連絡先は削除されます。</string> + <string name="copy_done">連絡先のコピーが完了しました</string> + <string name="copy_failure">連絡先をコピーできませんでした</string> + <string name="card_no_space">連絡先をコピーできませんでした、SIMカードがいっぱいです</string> + <string name="settings_contact_display_options_description">連絡先の表示と並び順を設定する</string> + <string name="ip_call_by_slot"><xliff:g id="subName">%s</xliff:g>経由でIP電話で発信</string> + <string name="no_ip_number">IP番号がありません</string> + <string name="no_ip_number_on_sim_card">SIMカードにIP番号がありません</string> + <string name="set_ip_number">IP番号を設定</string> + <string name="ipcall_dialog_title">IP電話の設定</string> + <string name="ipcall_dialog_edit_hint">IP電話のプレフィックスを入力してください</string> + <string name="import_contacts_from_all_cards">すべてのSIMカードから連絡先をインポート</string> + <string name="select_path">パスを選択</string> + <string name="select_sim">SIMを選択</string> +</resources> diff --git a/res/values-ko/cm_strings.xml b/res/values-ko/cm_strings.xml new file mode 100644 index 00000000..32bed9b7 --- /dev/null +++ b/res/values-ko/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">로컬 태블릿 계정</string> + <string name="local_storage_account" product="default">로컬 휴대전화 계정</string> + <string name="import_contacts_sim">SIM 카드에서 연락처를 가져올까요?</string> + <string name="manage_sim_contacts">SIM 카드 연락처 관리</string> + <string name="export_to_sim">SIM 카드로 내보내기</string> + <string name="fail_reason_import_vcard">I/O 오류로 인해 \'<xliff:g id="name">%s</xliff:g>\'을(를) 가져올 수 없었습니다</string> + <string name="contact_share_failed_toast"><xliff:g id="count">%d</xliff:g>건보다 많은 수의 연락처는 공유할 수 없습니다</string> + <string name="label_groups">그룹</string> + <string name="exporting">내보내는 중\u2026</string> + <string name="reading_vcard_files"><xliff:g id="total_number">%2$s</xliff:g>개 중 <xliff:g id="current_number">%1$s</xliff:g>번째 파일</string> + <string name="export_failed">내보내기 실패</string> + <string name="sim_card_full">SIM 카드가 가득 찼습니다</string> + <string name="export_finished">내보내기 완료</string> + <string name="tag_too_long">연락처 이름이 너무 깁니다</string> + <string name="sim_contacts_not_loaded">SIM 연락처를 불러올 수 없습니다</string> + <plurals name="export_cancelled"> + <item quantity="other">내보내기가 취소되었으며, %d건의 항목의 내보내기가 완료되었습니다</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g>에 전화번호 또는 이메일 주소가 필요합니다</string> + <string name="import_from_sim_select">가져올 SIM 카드 선택</string> + <string name="no_sdcard_title" product="nosdcard">저장소를 사용할 수 없음</string> + <string name="no_sdcard_title" product="default">SD 카드 없음</string> + <string name="deleteConfirmation_title">연락처를 삭제할까요?</string> + <string name="deleteConfirmation">이 연락처가 삭제될 것입니다.</string> + <string name="copy_done">연락처가 성공적으로 복사되었습니다</string> + <string name="copy_failure">연락처를 복사하지 못했습니다</string> + <string name="card_no_space">SIM 카드가 가득 차 있어 연락처를 복사하지 못했습니다</string> + <string name="settings_contact_display_options_description">연락처가 표시 및 정렬되는 방식을 구성합니다.</string> + <string name="ip_call_by_slot"><xliff:g id="subName">%s</xliff:g>(으)로 IP 통화</string> + <string name="no_ip_number">IP 번호 없음</string> + <string name="no_ip_number_on_sim_card">SIM 카드에 IP 번호 없음</string> + <string name="set_ip_number">IP 번호 설정</string> + <string name="ipcall_dialog_title">IP 통화 설정</string> + <string name="ipcall_dialog_edit_hint">IP 접두사를 입력해주세요</string> + <string name="import_contacts_from_all_cards">모든 SIM 카드에서 연락처 가져오기</string> + <string name="select_path">경로 선택</string> + <string name="select_sim">SIM 선택</string> +</resources> diff --git a/res/values-ku/cm_strings.xml b/res/values-ku/cm_strings.xml new file mode 100644 index 00000000..34ca6eda --- /dev/null +++ b/res/values-ku/cm_strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">هەژماری ناوخۆی تاتەبژمێر</string> + <string name="local_storage_account" product="default">هەژماری ناوخۆی تەلەفۆن</string> + <string name="export_to_sim">ناردنی ناو بۆ سیماکارت</string> + <string name="label_groups">گرووپ</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> ی <xliff:g id="total_number">%2$s</xliff:g> فایلەکان</string> + <string name="export_failed">هەناردن سەرکەوتوو نەبوو</string> + <string name="export_finished">هەناردن تەواو بوو</string> + <string name="import_from_sim_select">کارتێک هەڵبژێرە بۆ هاوردن</string> + <string name="no_sdcard_title" product="nosdcard">بیرگە بەردەست نییە</string> + <string name="no_sdcard_title" product="default">میمۆری دهرهکی نییه</string> + <string name="deleteConfirmation_title">سڕینەوەی پەیوەندی؟?</string> + <string name="deleteConfirmation">ئەم پەیوەندییە دەسڕدرێتەوە.</string> + <string name="no_ip_number">ژمارەی IP نییە</string> + <string name="no_ip_number_on_sim_card">ژمارەی IP لە ناو سیمکارتدا نییە</string> + <string name="ipcall_dialog_edit_hint">تکایە پێشگری IP تێبکە</string> + <string name="select_sim">دیاریکردنی سیم</string> +</resources> diff --git a/res/values-ku/strings.xml b/res/values-ku/strings.xml new file mode 100644 index 00000000..ed234831 --- /dev/null +++ b/res/values-ku/strings.xml @@ -0,0 +1,247 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + ~ Copyright (C) 2012 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="toast_text_copied">دهق له بهر گیرایهوه</string> + <string name="call_custom">پهیوهندی + <xliff:g id="custom">%s</xliff:g> + </string> + <string name="call_home">پهیوهندی ماڵهوه</string> + <string name="call_mobile">پهیوهندی مۆبایل</string> + <string name="call_work">پهیوهندی سهرکار</string> + <string name="call_fax_work">پهیوهندی فاکسی سهرکار</string> + <string name="call_fax_home">پهیوهندی فاکسی ماڵهوه</string> + <string name="call_pager">لاپهڕه پهیوهندی</string> + <string name="call_other">پەیوەندیکردن</string> + <string name="call_callback">پهیوهندی گهڕانهوه</string> + <string name="call_car">پهیوهندی ئۆتۆمبێل</string> + <string name="call_company_main">پهیوهندی کۆمپانیای سهرهکی</string> + <string name="call_isdn">پهیوهندی ISDN</string> + <string name="call_main">پهیوهندی سهرهکی</string> + <string name="call_other_fax">پهیوهندی فاکس</string> + <string name="call_radio">پهیوهندی ڕادیۆ</string> + <string name="call_telex">پهیوهندی تێلئێکس</string> + <string name="call_tty_tdd">پهیوهندی TTY/TDD</string> + <string name="call_work_mobile">پهیوهندی سهرکاری مۆبایل</string> + <string name="call_work_pager">لاپهڕه پهیوهندی سهر کار</string> + <string name="call_assistant">پهیوهندی + <xliff:g id="assistant">%s</xliff:g> + </string> + <string name="call_mms">پهیوهندی MMS</string> + <string name="sms_custom">دهق + <xliff:g id="custom">%s</xliff:g> + </string> + <string name="sms_home">دهقی ماڵهوه</string> + <string name="sms_mobile">دهقی مۆبایل</string> + <string name="sms_work">دهقی سهر کار</string> + <string name="sms_fax_work">دهقی سهرکاری فاکس</string> + <string name="sms_fax_home">دهقی ماڵهوهی فاکس</string> + <string name="sms_pager">لاپهڕه دهق</string> + <string name="sms_other">دهق</string> + <string name="sms_callback">دهقی پهیوهندی گهڕانهوه</string> + <string name="sms_car">دهقی ئۆتۆمبێل</string> + <string name="sms_company_main">دهقی کۆمپانیای سهرهکی</string> + <string name="sms_isdn">دهقی ISDN</string> + <string name="sms_main">دهقی سهرهکی</string> + <string name="sms_other_fax">دهقی فاکس</string> + <string name="sms_radio">دهقی ڕادیۆ</string> + <string name="sms_telex">دهقی تێلێکس</string> + <string name="sms_tty_tdd">دهقی TTY/TDD</string> + <string name="sms_work_mobile">دهقی ژمارهی سهر کار</string> + <string name="sms_work_pager">دهقی لاپهڕهی سهر کار</string> + <string name="sms_assistant">دهق + <xliff:g id="assistant">%s</xliff:g> + </string> + <string name="sms_mms">دهقی MMS</string> + <string name="clearFrequentsConfirmation_title">پاککردنهوهی زوو-زوو پهیوهندی پێوهکراوهکان؟</string> + <string name="clearFrequentsConfirmation">تۆ زوو-زوو پهیوهندی پێوهکراوهکان پاک دهکهیتهوه له لیستی + خهڵک وه ژماره. وه بهرنامه مێڵهکان بۆ فێربوونی ڕێکخستنی ناونیشانهکان + . + </string> + <string name="clearFrequentsProgress_title">پاککردنهوهی پهیوهندییه زوو-زووهکان\u2026</string> + <string name="status_available">بەردەست</string> + <string name="status_away">ئاماده نییه</string> + <string name="status_busy">سەرقاڵ</string> + <string name="contactsList">ناوەکان</string> + <string name="local_invisible_directory">دیکە</string> + <string name="directory_search_label">بوخچه</string> + <string name="local_search_label">هەموو ناوەکان</string> + <string name="user_profile_contacts_list_header" msgid="9154761216179882405">من</string> + <string name="search_results_searching">گەڕان\u2026</string> + <string name="foundTooManyContacts">زیاتر له <xliff:g id="count">%d</xliff:g> دۆزرایهوه.</string> + <string name="listFoundAllContactsZero">ناو نییە</string> + <plurals name="searchFoundContacts"> + <item quantity="one">١ دانە دۆزرایەوە</item> + <item quantity="other"><xliff:g id="count">%d</xliff:g> دانە دۆزرایەوە</item> + </plurals> + <string name="description_quick_contact_for">پهیوهندی خێرا بۆ <xliff:g id="name">%1$s</xliff:g></string> + <string name="missing_name">(ناوی نییه)</string> + <string name="favoritesFrequentCalled">زۆرترین پەیوەندیکردن</string> + <string name="favoritesFrequentContacted">زۆرترین ژماره پهیوهندییهکان</string> + <string name="description_view_contact_detail" msgid="2795575601596468581">بینینی ناو</string> + <string name="list_filter_phones">ههموو پهیوهندییهکان لەگەڵ ژمارەی تەلەفۆنەکان</string> + <string name="view_updates_from_group">بینینی نوێکاری</string> + <string name="account_phone" product="tablet">تهنیا-تابلێت، گواستنهوه نهکراوه</string> + <string name="account_phone" product="default">تهنیا-مۆبایل، گواستنهوه نهکراوه</string> + <string name="nameLabelsGroup">ناو</string> + <string name="nicknameLabelsGroup">نازناو</string> + <string name="full_name">ناو</string> + <string name="name_prefix">ناوی پێشگر</string> + <string name="name_middle">ناوی ناوهند</string> + <string name="name_suffix">ناوی پاشگر</string> + <string name="name_phonetic">ناوی دهنگی</string> + <string name="name_phonetic_middle">ناوی دهنگی ناوهند</string> + <string name="phoneLabelsGroup">مۆبایل</string> + <string name="emailLabelsGroup">پۆست</string> + <string name="postalLabelsGroup">ناونیشان</string> + <string name="imLabelsGroup">IM</string> + <string name="organizationLabelsGroup">ناوی ڕێکخراو</string> + <string name="relationLabelsGroup">پهیوهندی کۆمهڵایهتی</string> + <string name="eventLabelsGroup">ڕۆژه تایبهتهکان</string> + <string name="sms">نامهی دهقی</string> + <string name="postal_address">ناونیشان</string> + <string name="ghostData_company">کۆمپانیا</string> + <string name="ghostData_title">سەردێڕ</string> + <string name="label_notes">تێبینییهکان</string> + <string name="websiteLabelsGroup">ماڵپەڕ</string> + <string name="groupsLabel">کۆمهڵهکان</string> + <string name="email_home">پۆستی ئهلیکترۆنی ماڵهوه</string> + <string name="email_mobile">پۆستی ئهلیکترۆنی مۆبایل</string> + <string name="email_work">پۆستی ئهلیکترۆنی سهر کار</string> + <string name="email_other">پۆستی ئهلەکترۆنی</string> + <string name="email_custom">پۆست <xliff:g id="custom">%s</xliff:g></string> + <string name="email">پۆستی ئهلەکترۆنی</string> + <string name="postal_street">شهقام</string> + <string name="postal_pobox">سندوقی PO</string> + <string name="postal_neighborhood">دراوسێ</string> + <string name="postal_city">شار</string> + <string name="postal_region">وڵات</string> + <string name="postal_postcode">کۆدی پۆستی</string> + <string name="postal_country">وڵات</string> + <string name="map_home">بینینی ناونیشانی ماڵهوه</string> + <string name="map_work">بینینی ناونیشانی سهر کار</string> + <string name="map_other">بینینی ناونیشان</string> + <string name="map_custom">بینینی <xliff:g id="custom">%s</xliff:g> ناونیشان</string> + <string name="chat_aim">گفتوگۆکردن بهبهکارهێنانی AIM</string> + <string name="chat_msn">گفتوگۆکردن بهبهکارهێنانی Windows Live</string> + <string name="chat_yahoo">گفتوگۆکردن بهبهکارهێنانی Yahoo</string> + <string name="chat_skype">گفتوگۆکردن بهبهکارهێنانی سکایپ</string> + <string name="chat_qq">گفتوگۆکردن بهبهکارهێنانی QQ</string> + <string name="chat_gtalk">گفتوگۆکردن بهبهکارهێنانی Google Talk</string> + <string name="chat_icq">گفتوگۆکردن بهبهکارهێنانی ICQ</string> + <string name="chat_jabber">گفتوگۆکردن بهبهکارهێنانی Jabber</string> + <string name="chat">گفتوگۆکردن</string> + <string name="description_minus_button">سڕینەوە</string> + <string name="expand_collapse_name_fields_description">فراوانکردن یان تهسک کردنهوهی بۆشایی ناوهکان</string> + <string name="list_filter_all_accounts">هەموو ناوەکان</string> + <string name="list_filter_all_starred">ئهستێرهدار</string> + <string name="list_filter_customize">خواستی خۆت</string> + <string name="list_filter_single">ناو</string> + <string name="display_ungrouped">ههموو پهیوهندییهکانی تر</string> + <string name="display_all_contacts">هەموو ناوەکان</string> + <string name="menu_sync_remove">سڕینهوهی گواستنهوهی گروپ</string> + <string name="dialog_sync_add">زیادکردنی گواستنهوهی گروپ</string> + <string name="display_more_groups">گروپی زیاتر\u2026</string> + <string name="display_warn_remove_ungrouped">سڕینهوهی \"<xliff:g id="group" example="Starred">%s</xliff:g>\" له گواستنهوه و ههروهها سڕینهوهی ههر نا گروپێکی پهیوهندی له گواستنهوه.</string> + <string name="savingDisplayGroups">پاشهکهوتکردنی نیشاندانی ڕێکخستن\u2026</string> + <string name="menu_done">کراو</string> + <string name="menu_doNotSave">هەڵوەشاندنەوە</string> + <string name="listAllContactsInAccount">پهیوهندی له <xliff:g id="name" example="abc@gmail.com">%s</xliff:g></string> + <string name="listCustomView">پهیوهندی له بینینی خوازراو</string> + <string name="listSingleContact">پهیوهندی تاک</string> + <string name="dialog_new_contact_account">دروستکردنی پهیوهندی له ژێر ههژماردا</string> + <string name="import_from_sim">هاوردهکردن له سیمکاردهوه</string> + <string name="import_from_sdcard" product="default">هاوردهکردن له بیرگهوه</string> + <string name="cancel_import_confirmation_message">لابردنی هاوردهکردن له <xliff:g id="filename" example="import.vcf">%s</xliff:g>؟</string> + <string name="cancel_export_confirmation_message">لابردنی ناردن له <xliff:g id="filename" example="export.vcf">%s</xliff:g>؟</string> + <string name="cancel_vcard_import_or_export_failed">نهتوانرا هاورده کردن و ناردنی vCard ههڵبوهشێنرێت</string> + <string name="fail_reason_unknown">ههڵهی نهزانراو.</string> + <string name="fail_reason_could_not_open_file">نهتوانرا \"<xliff:g id="file_name">%s</xliff:g>" بکرێتهوه: <xliff:g id="exact_reason">%s</xliff:g>.</string> + <string name="fail_reason_could_not_initialize_exporter">نهتوانرا دهستبکرێت به ناردن: \"<xliff:g id="exact_reason">%s</xliff:g>\".</string> + <string name="fail_reason_no_exportable_contact">هیچ پهیوهندییهکانی شایهن ناردن نییه.</string> + <string name="fail_reason_error_occurred_during_export">ههڵهیهک ڕوویدا لهکاتی ناردن: \"<xliff:g id="exact_reason">%s</xliff:g>\".</string> + <string name="fail_reason_too_long_filename">داواکاری ناوی پهڕگه زۆر درێژه (\"<xliff:g id="filename">%s</xliff:g>\").</string> + <string name="fail_reason_too_many_vcard" product="nosdcard">زۆر پهڕگهی vCard ههیه له بیرگه.</string> + <string name="fail_reason_too_many_vcard" product="default">زۆر پهڕگهی vCard ههیه له بیرگهی دهرهکی.</string> + <string name="fail_reason_io_error">ههڵهی I/O</string> + <string name="fail_reason_low_memory_during_import">بۆشایی بیرگه نییه. پهڕگهکه زۆر گهورهیه.</string> + <string name="fail_reason_vcard_parse_error">نهتوانرا پێوانهی vCard بکرێت بههۆی هۆکارێکی چاوهڕوان نهکراوهوه.</string> + <string name="fail_reason_not_supported">جۆری پهڕگهکه گونجاو نییه.</string> + <string name="fail_reason_failed_to_collect_vcard_meta_info">نهتوانرا زانیاری مێتا دهستبکهوێت له پهڕگهی vCard.</string> + <string name="fail_reason_failed_to_read_files">پهڕگهیهک یان زیاتر له دانهیهک نهتوانرا هاورده بکرێت (%s).</string> + <string name="exporting_vcard_finished_title">ناردن تهواوبوو <xliff:g id="filename" example="export.vcf">%s</xliff:g>.</string> + <string name="exporting_vcard_canceled_title">ناردنی<xliff:g id="filename" example="export.vcf">%s</xliff:g> ههڵوهشێنرایهوه.</string> + <string name="exporting_contact_list_title">ناردنی زانیاری پهیوهندی</string> + <string name="exporting_contact_list_message">زانیاری پهیوهندی دهنێردرێت بۆ: <xliff:g id="file_name">%s</xliff:g>.</string> + <string name="composer_failed_to_get_database_infomation">نهتوانرا زانیاری داتابهیس وهربگیرێت.</string> + <string name="composer_has_no_exportable_contact" product="tablet">هیچ پهیوهندییهکانی شایهن ناردن نیه. ئهگهر پهیوهندیت ههیه لهسهر تابلێتهکهت، ههندێک داتا لهوانهیه ڕێگری بکات له پهیوهندییهکان بۆ ناردن لهسهر تابلێتهکهت.</string> + <string name="composer_has_no_exportable_contact" product="default">هیچ پهیوهندییهکانی شایهن ناردن نیه. ئهگهر پهیوهندیت ههیه لهسهر مۆبایلهکهت، ههندێک داتا لهوانهیه ڕێگری بکات له پهیوهندییهکان بۆ ناردن لهسهر مۆبایلهکهت.</string> + <string name="composer_not_initialized">کهپسکهری vCard کاری نهکرد.</string> + <string name="exporting_contact_failed_title">نهتوانرا بنێردرێ</string> + <string name="exporting_contact_failed_message">داتای پهیوهندی نهتوانرا بنێردرێ.\nهۆکار: \"<xliff:g id="fail_reason">%s</xliff:g>\"</string> + <string name="no_sdcard_message" product="nosdcard">هیچ بیرگهیهک نهدۆزرایهوه.</string> + <string name="no_sdcard_message" product="default">هیچ بیرگهی دهرهکی نهدۆزرایهوه.</string> + <string name="confirm_export_message">لیستی پهیوهندییهکانت دهنێردرێ بۆ پهڕگهی: <xliff:g id="vcard_filename">%s</xliff:g>.</string> + <string name="importing_vcard_description">هاوردهکردن <xliff:g id="name" example="Joe Due">%s</xliff:g></string> + <string name="reading_vcard_failed_title">نهتوانرا VCard بخوێنرێتهوه</string> + <string name="reading_vcard_canceled_title">خوێندنهوهی vCard ههڵوهشێنرایهوه</string> + <string name="importing_vcard_finished_title">هاوردهکردنی VCard تهواوبوو <xliff:g id="filename" example="import.vcf">%s</xliff:g></string> + <string name="importing_vcard_canceled_title">هاوردهکردنی <xliff:g id="filename" example="import.vcf">%s</xliff:g> ههڵوهشێنرایهوه</string> + <string name="vcard_import_will_start_message"><xliff:g id="filename" example="import.vcf">%s</xliff:g> هاورده دهکرێت به کورتی.</string> + <string name="vcard_import_will_start_message_with_default_name">پهڕگهکه هاورده دهکرێ به کورتی</string> + <string name="vcard_import_request_rejected_message">vCard و ناردنی وه داواکردنی ڕهتکرایهوه. دواتر ههوڵ بدهرهوه.</string> + <string name="vcard_export_will_start_message"><xliff:g id="filename" example="import.vcf">%s</xliff:g> دهنێردرێت به کورتی.</string> + <string name="vcard_export_request_rejected_message">vCard و ناردنی وه داواکردنی ڕهتکرایهوه. دواتر ههوڵ بدهرهوه.</string> + <string name="vcard_unknown_filename">پهیوهندی</string> + <string name="caching_vcard_message">گرتنی vCard بۆ بیرگهی ناوهکی. له ڕاستیدا دێته ناوی به زویی.</string> + <string name="percentage"><xliff:g id="percentage" example="50">%s</xliff:g><xliff:g id="percentsign" example="%">%%</xliff:g></string> + <string name="vcard_import_failed">نهتوانرا vCard تێبکرێت.</string> + <string name="import_failure_no_vcard_file" product="nosdcard">هیچ vCard ـێک نهدۆزرایهوه.</string> + <string name="import_failure_no_vcard_file" product="default">هیچ vCard نهدۆزرایهوه لهسهر بیرگه.</string> + <string name="nfc_vcard_file_name">وهرگری پهیوهندی لهلایهن NFC</string> + <string name="confirm_export_title">ناردنی پهیوهندییهکان؟</string> + <string name="select_vcard_title">دیاریکردنی پهڕگهی vCard</string> + <string name="import_one_vcard_string">کردنهناوی یهک پهڕگهی vCard</string> + <string name="import_multiple_vcard_string">کردنه ناوی چهند پهڕگهیهکی vCard</string> + <string name="import_all_vcard_string">تێکردنی ههموو پهڕگهکانی vCard</string> + <string name="searching_vcard_message" product="nosdcard">گهڕان به دوای داتا له بیرگهی vCard\u2026</string> + <string name="searching_vcard_message" product="default">گهڕان به دوای داتای vCard له بیرگهی دهرهکی\u2026</string> + <string name="caching_vcard_title">حهشارگهکردن</string> + <string name="scanning_sdcard_failed_message" product="nosdcard">بیرگهکه نهتوانرا بپشکنرێ. (هۆکار: \"\"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + <string name="scanning_sdcard_failed_message" product="default">بیرگهکه نهتوانرا بپشکنرێ. (هۆکار: \"\"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + <string name="progress_notifier_message">هاوردهکردنی <xliff:g id="current_number">%s</xliff:g>/<xliff:g id="total_number">%s</xliff:g>: <xliff:g id="name" example="Joe Due">%s</xliff:g></string> + <string name="export_to_sdcard" product="default">ناردن بۆ بیرگه</string> + <string name="share_visible_contacts">بهشداریپێکردنی پهیوهندییه دیارهکان</string> + <string name="dialog_import_export">هاوردهکردن/ناردنی پهیوهندی</string> + <string name="dialog_import">هاوردنی ناوەکان</string> + <string name="share_error">ئهم پهیوهندییه ناتوانرێ بهشداریپێبکرێت.</string> + <string name="menu_search">گهڕان</string> + <string name="menu_contacts_filter">پهیوهندی شایهن نیشاندان</string> + <string name="activity_title_contacts_filter">ناوەکان بۆ پیشاندان</string> + <string name="custom_list_filter">شایهنی بینینی خوازراو</string> + <string name="hint_findContacts">دۆزینهوهی پهیوهندی</string> + <string name="contactsFavoritesLabel">دڵخوازهکان</string> + <string name="listTotalAllContactsZero">ناو نییە.</string> + <string name="listTotalAllContactsZeroCustom">هیچ پهیوهندییهکی دیار نییه.</string> + <string name="listTotalAllContactsZeroStarred">هیچ دڵخوازێک نییه.</string> + <string name="listTotalAllContactsZeroGroup">هیچ پهیوهندییهک نییه له <xliff:g id="name" example="Friends">%s</xliff:g></string> + <string name="menu_clear_frequents">پاککردنهوهی زوو-زووه پهیوهندییهکان</string> + <string name="menu_accounts">ههژمارهکان</string> + <string name="menu_import_export">هاوردهکردن/ناردن</string> + <string name="contact_status_update_attribution">لهلایهن <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string> + <string name="contact_status_update_attribution_with_date"><xliff:g id="date" example="3 hours ago">%1$s</xliff:g> لهڕێگهی <xliff:g id="source" example="Google Talk">%2$s</xliff:g></string> +</resources> diff --git a/res/values-lb/cm_strings.xml b/res/values-lb/cm_strings.xml new file mode 100644 index 00000000..f2ee54b9 --- /dev/null +++ b/res/values-lb/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokalen Tabletkont</string> + <string name="local_storage_account" product="default">Lokalen Telefonskont</string> + <string name="import_contacts_sim">Kontakter vun der SIM-Kaart importéieren?</string> + <string name="manage_sim_contacts">Kontakter vun der SIM-Kaart geréieren</string> + <string name="export_to_sim">Op d\'SIM-Kaart exportéieren</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' konnt wéinst engem I/O-Feeler net importéiert ginn</string> + <string name="contact_share_failed_toast">Et kënnen net méi wéi <xliff:g id="count">%d</xliff:g> Kontakter gedeelt ginn</string> + <string name="label_groups">Grupp</string> + <string name="exporting">Gëtt exportéiert\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> / <xliff:g id="total_number">%2$s</xliff:g> Fichieren</string> + <string name="export_failed">Export feelgeschloen</string> + <string name="sim_card_full">SIM-Kaart ass voll</string> + <string name="export_finished">Export ofgeschloss</string> + <string name="tag_too_long">Kontaktnumm ass ze laang</string> + <string name="sim_contacts_not_loaded">SIM-Kontakter kënnen net geluede ginn</string> + <plurals name="export_cancelled"> + <item quantity="one">Den Export gouf ofgebrach, %d Element gouf importéiert</item> + <item quantity="other">Den Export gouf ofgebrach, %d Elementer goufen importéiert</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> huet keng Telefonsnummer oder E-Mail-Adress</string> + <string name="import_from_sim_select">SIM-Kaart fir den Import auswielen</string> + <string name="no_sdcard_title" product="nosdcard">Späicher net disponibel</string> + <string name="no_sdcard_title" product="default">Keng SD-Kaart</string> + <string name="deleteConfirmation_title">Kontakt läschen?</string> + <string name="deleteConfirmation">Dëse Kontakt gëtt geläscht.</string> + <string name="copy_done">Kontakt gouf erfollegräich kopéiert</string> + <string name="copy_failure">De Kontakt konnt net kopéiert ginn</string> + <string name="card_no_space">D\'Kopéiere vu Kontakter ass feelgeschloen, d\'SIM-Kaart ass voll</string> + <string name="settings_contact_display_options_description">Konfiguréier, wéi deng Kontakter ugewisen an zortéiert solle ginn.</string> + <string name="ip_call_by_slot">VOIP-Uruff iwwer <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Keng VOIP-Nummer</string> + <string name="no_ip_number_on_sim_card">Keng VOIP-Nummer op der SIM-Kaart</string> + <string name="set_ip_number">VOIP-Nummer setzen</string> + <string name="ipcall_dialog_title">Astellunge fir VOIP-Uriff</string> + <string name="ipcall_dialog_edit_hint">Gëff w.e.g. de VOIP-Prefix an</string> + <string name="import_contacts_from_all_cards">Kontakter vun alle SIM-Kaarten importéieren</string> + <string name="select_path">Pad auswielen</string> + <string name="select_sim">SIM auswielen</string> +</resources> diff --git a/res/values-lb/strings.xml b/res/values-lb/strings.xml new file mode 100644 index 00000000..ccb684ba --- /dev/null +++ b/res/values-lb/strings.xml @@ -0,0 +1,253 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + ~ Copyright (C) 2012 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="toast_text_copied">Text kopéiert</string> + <string name="call_custom"><xliff:g id="custom">%s</xliff:g> uruffen</string> + <string name="call_home">Doheem uruffen</string> + <string name="call_mobile">Handy uruffen</string> + <string name="call_work">Aarbecht uruffen</string> + <string name="call_fax_work">Fax op der Aarbecht uruffen</string> + <string name="call_fax_home">Fax doheem uruffen</string> + <string name="call_pager">Pager uruffen</string> + <string name="call_other">Uruffen</string> + <string name="call_callback">Réckruffnummer uruffen</string> + <string name="call_car">Auto uruffen</string> + <string name="call_company_main">Firmentelefon uruffen</string> + <string name="call_isdn">ISDN uruffen</string> + <string name="call_main">Haaptnummer uruffen</string> + <string name="call_other_fax">Fax uruffen</string> + <string name="call_radio">Radio uruffen</string> + <string name="call_telex">Telex uruffen</string> + <string name="call_tty_tdd">TTY/TDD uruffen</string> + <string name="call_work_mobile">Aarbechtshandy uruffen</string> + <string name="call_work_pager">Aarbechtspager uruffen</string> + <string name="call_assistant"><xliff:g id="assistant">%s</xliff:g> uruffen</string> + <string name="call_mms">MMS uruffen</string> + <string name="sms_custom"><xliff:g id="custom">%s</xliff:g> eng SMS schreiwen</string> + <string name="sms_home">SMS un déi privat Nummer schécken</string> + <string name="sms_mobile">SMS un den Handy schécken</string> + <string name="sms_work">SMS un d\'Aarbecht schécken</string> + <string name="sms_fax_work">SMS un den Aarbechtsfax schécken</string> + <string name="sms_fax_home">Fax un déi privat Nummer schécken</string> + <string name="sms_pager">SMS un de Pager schécken</string> + <string name="sms_other">SMS schécken</string> + <string name="sms_callback">SMS zréckschécken</string> + <string name="sms_car">SMS un den Auto schécken</string> + <string name="sms_company_main">SMS un d\'Haaptnummer vun der Firma schécken</string> + <string name="sms_isdn">SMS un d\'ISDN-Nummer schécken</string> + <string name="sms_main">SMS un d\'Haaptnummer schécken</string> + <string name="sms_other_fax">SMS un de Fax schécken</string> + <string name="sms_radio">SMS un de Radio schécken</string> + <string name="sms_telex">SMS un den Telex schécken</string> + <string name="sms_tty_tdd">SMS un den TTY/TDD schécken</string> + <string name="sms_work_mobile">SMS un den Aarbechtshandy schécken</string> + <string name="sms_work_pager">SMS un den Aarbechtspager schécken</string> + <string name="sms_assistant">Dem <xliff:g id="assistant">%s</xliff:g> eng SMS schécken</string> + <string name="sms_mms">MMS schécken</string> + <string name="description_video_call">Videouruff maachen</string> + <string name="clearFrequentsConfirmation_title">Dacks kontaktéiert eidel maachen?</string> + <string name="clearFrequentsConfirmation">Du läschs d\'Lëscht mat den dacks Kontaktéierten an den Appe \"Leit\" an \"Telefon\", an du forcéiers d\'Email-Appen d\'Adressastellungen nei ze léieren.</string> + <string name="clearFrequentsProgress_title">Dacks kontaktéiert gëtt eidel gemaach\u2026</string> + <string name="status_available">Disponibel</string> + <string name="status_away">Fort</string> + <string name="status_busy">Beschäftegt</string> + <string name="contactsList">Kontakter</string> + <string name="local_invisible_directory">Aner</string> + <string name="directory_search_label">Verzeechnes</string> + <string name="local_search_label">All d\'Kontakter</string> + <string name="user_profile_contacts_list_header" msgid="9154761216179882405">Ech</string> + <string name="search_results_searching">Gëtt gesicht\u2026</string> + <string name="foundTooManyContacts">Méi wéi <xliff:g id="count">%d</xliff:g> fonnt.</string> + <string name="listFoundAllContactsZero">Keng Kontakter</string> + <plurals name="searchFoundContacts"> + <item quantity="one">1 fonnt</item> + <item quantity="other"><xliff:g id="count">%d</xliff:g> fonnt</item> + </plurals> + <string name="description_quick_contact_for">Séiere Kontakt fir <xliff:g id="name">%1$s</xliff:g></string> + <string name="missing_name">(Keen Numm)</string> + <string name="favoritesFrequentCalled">Dacks ugeruff</string> + <string name="favoritesFrequentContacted">Dacks kontaktéiert</string> + <string name="description_view_contact_detail" msgid="2795575601596468581">Kontakt ukucken</string> + <string name="list_filter_phones">All d\'Kontakter mat Telefonsnummer</string> + <string name="view_updates_from_group">Aktualiséierungen uweisen</string> + <string name="account_phone" product="tablet">Just Tablet, onsynchroniséiert</string> + <string name="account_phone" product="default">Just Telefon, onsynchroniséiert</string> + <string name="nameLabelsGroup">Numm</string> + <string name="nicknameLabelsGroup">Spëtznumm</string> + <string name="full_name">Numm</string> + <string name="name_given">Virnumm</string> + <string name="name_family">Familljennumm</string> + <string name="name_prefix">Nummprefix</string> + <string name="name_middle">Zweete Virnumm</string> + <string name="name_suffix">Nummsuffix</string> + <string name="name_phonetic">Phoneteschen Numm</string> + <string name="name_phonetic_given">Phonetesche Virnumm</string> + <string name="name_phonetic_middle">Phoneteschen zweete VIrnumm</string> + <string name="name_phonetic_family">Phonetesche Familljennumm</string> + <string name="phoneLabelsGroup">Telefon</string> + <string name="emailLabelsGroup">E-Mail</string> + <string name="postalLabelsGroup">Adress</string> + <string name="imLabelsGroup">IM</string> + <string name="organizationLabelsGroup">Organisatioun</string> + <string name="relationLabelsGroup">Relatioun</string> + <string name="eventLabelsGroup">Speziell Daten</string> + <string name="sms">Text-Message</string> + <string name="postal_address">Adress</string> + <string name="ghostData_company">Firma</string> + <string name="ghostData_title">Titel</string> + <string name="label_notes">Notten</string> + <string name="label_sip_address">SIP</string> + <string name="websiteLabelsGroup">Websäit</string> + <string name="groupsLabel">Gruppen</string> + <string name="email_home">E-Mail un déi privat Adress schécken</string> + <string name="email_mobile">E-Mail un déi mobil Adress schécken</string> + <string name="email_work">E-Mail un d\'Aarbechtsadress schécken</string> + <string name="email_other">E-Mail schécken</string> + <string name="email_custom">E-Mail (<xliff:g id="custom">%s</xliff:g>)</string> + <string name="email">E-Mail</string> + <string name="postal_street">Strooss</string> + <string name="postal_pobox">Postfach</string> + <string name="postal_neighborhood">Noperschaft</string> + <string name="postal_city">Stad</string> + <string name="postal_region">Staat</string> + <string name="postal_postcode">Postleetzuel</string> + <string name="postal_country">Land</string> + <string name="map_home">Privatadress ukucken</string> + <string name="map_work">Aarbechtsadress ukucken</string> + <string name="map_other">Adress ukucken</string> + <string name="map_custom"><xliff:g id="custom">%s</xliff:g>-Adress ukucken</string> + <string name="chat_aim">Iwwer AIM chatten</string> + <string name="chat_msn">Iwwer Windows Live chatten</string> + <string name="chat_yahoo">Iwwer Yahoo chatten</string> + <string name="chat_skype">Iwwer Skype chatten</string> + <string name="chat_qq">Iwwer QQ chatten</string> + <string name="chat_gtalk">Iwwer Google Talk chatten</string> + <string name="chat_icq">Iwwer ICQ chatten</string> + <string name="chat_jabber">Iwwer Jabber chatten</string> + <string name="chat">Chatten</string> + <string name="description_minus_button">läschen</string> + <string name="expand_collapse_name_fields_description">Felder fir d\'Nimm ausklappen oder zesummeklappen</string> + <string name="list_filter_all_accounts">All d\'Kontakter</string> + <string name="list_filter_all_starred">Markéiert</string> + <string name="list_filter_customize">Personaliséieren</string> + <string name="list_filter_single">Kontakt</string> + <string name="display_ungrouped">All déi aner Kontakter</string> + <string name="display_all_contacts">All d\'Kontakter</string> + <string name="menu_sync_remove">Synchroniséierungsgrupp läschen</string> + <string name="dialog_sync_add">Synchroniséierungsgrupp dobäisetzen</string> + <string name="display_more_groups">Méi Gruppen\u2026</string> + <string name="display_warn_remove_ungrouped">Wann \"<xliff:g id="group" example="Starred">%s</xliff:g>\" aus der Synchroniséierung geläscht gëtt, ginn och all déi net gruppéiert Kontakter aus der Synchroniséierung geläscht.</string> + <string name="savingDisplayGroups">Uweisastellunge gi gespäichert\u2026</string> + <string name="menu_done">Fäerdeg</string> + <string name="menu_doNotSave">Ofbriechen</string> + <string name="listAllContactsInAccount">Kontakter am Kont <xliff:g id="name" example="abc@gmail.com">%s</xliff:g></string> + <string name="listCustomView">Kontakter an der personaliséierter Usiicht</string> + <string name="listSingleContact">Eenzelne Kontakt</string> + <string name="dialog_new_contact_account">Kontakt ënner dem Kont uleeën</string> + <string name="import_from_sim">Vun der SIM-Kaart importéieren</string> + <string name="import_from_sim_number">Vun der SIM-Kaart #<xliff:g id="sim_number" example="2">%d</xliff:g> importéieren</string> + <string name="import_from_sdcard" product="default">Aus dem Späicher importéieren</string> + <string name="cancel_import_confirmation_message">Import vum Fichier <xliff:g id="filename" example="import.vcf">%s</xliff:g> ofbriechen?</string> + <string name="cancel_export_confirmation_message">Export vum Fichier <xliff:g id="filename" example="import.vcf">%s</xliff:g> ofbriechen?</string> + <string name="cancel_vcard_import_or_export_failed">Konnt den Import/Export vun der vCard net ofbriechen</string> + <string name="fail_reason_unknown">Onbekannte Feeler.</string> + <string name="fail_reason_could_not_open_file">Konnt \"<xliff:g id="file_name">%s</xliff:g>" net opmaachen: <xliff:g id="exact_reason">%s</xliff:g>.</string> + <string name="fail_reason_could_not_initialize_exporter">Konnt den Exportéierprogramm net starten: \"<xliff:g id="exact_reason">%s</xliff:g>\".</string> + <string name="fail_reason_no_exportable_contact">Et gëtt kee Kontakt deen exportéiert ka ginn.</string> + <string name="fail_reason_error_occurred_during_export">Beim Exportéieren ass e Feeler opgetrueden: \"<xliff:g id="exact_reason">%s</xliff:g>\".</string> + <string name="fail_reason_too_long_filename">Den Numm vum Fichier ass ze laang (\"<xliff:g id="filename">%s</xliff:g>\").</string> + <string name="fail_reason_too_many_vcard" product="nosdcard">Et sinn ze vill vCard-Fichieren am Späicher.</string> + <string name="fail_reason_too_many_vcard" product="default">Et sinn ze vill vCard-Fichieren op der SD-Kaart.</string> + <string name="fail_reason_io_error">Lies-/Schreiffeeler</string> + <string name="fail_reason_low_memory_during_import">Net genuch Späicher. De Fichier kéint ze grouss ze sinn.</string> + <string name="fail_reason_vcard_parse_error">Konnt d\'vCard aus onerwaarte Grënn net liesen.</string> + <string name="fail_reason_not_supported">D\'Format ass net ënnerstëtzt.</string> + <string name="fail_reason_failed_to_collect_vcard_meta_info">Konnt d\'Metadate vun dëse vCard-Fichieren net liesen.</string> + <string name="fail_reason_failed_to_read_files">Een oder méi Fichiere konnten net importéiert ginn (%s).</string> + <string name="exporting_vcard_finished_title">Exportéierung vum Fichier <xliff:g id="filename" example="export.vcf">%s</xliff:g> ofgeschloss.</string> + <string name="exporting_vcard_canceled_title">Exportéierung vum Fichier <xliff:g id="filename" example="export.vcf">%s</xliff:g> ofgebrach.</string> + <string name="exporting_contact_list_title">Kontaktdate ginn exportéiert</string> + <string name="exporting_contact_list_message">Deng Kontaktdate ginn exportéiert als: <xliff:g id="file_name">%s</xliff:g>.</string> + <string name="composer_failed_to_get_database_infomation">Konnt d\'Datebankinformatiounen net lueden.</string> + <string name="composer_has_no_exportable_contact" product="tablet">Et gi keng Kontakter déi exportéiert kënne ginn. Wann s du keng Kontakter op dengem Tablet hues, kéinte verschidden Dateprovidere verbidden d\'Kontakter vum Tablet z\'exportéieren.</string> + <string name="composer_has_no_exportable_contact" product="default">Et gi keng Kontakter déi exportéiert kënne ginn. Wann s du keng Kontakter op dengem Telefon hues, kéinte verschidden Dateprovidere verbidden d\'Kontakter vum Telefon z\'exportéieren.</string> + <string name="composer_not_initialized">De vCard-Editor konnt net gestart ginn.</string> + <string name="exporting_contact_failed_title">Konnt net exportéieren</string> + <string name="exporting_contact_failed_message">D\'Kontaktdate goufen net exportéiert.\nGrond: \"<xliff:g id="fail_reason">%s</xliff:g>\"</string> + <string name="no_sdcard_message" product="nosdcard">De Späicher gouf net fonnt.</string> + <string name="no_sdcard_message" product="default">D\'SD-Kaart gouf net fonnt.</string> + <string name="confirm_export_message">Deng Kontaktlëscht gëtt an dëse Fichier exportéiert: <xliff:g id="vcard_filename">%s</xliff:g>.</string> + <string name="importing_vcard_description"><xliff:g id="name" example="Joe Due">%s</xliff:g> gëtt importéiert</string> + <string name="reading_vcard_failed_title">Konnt d\'vCard-Daten net liesen</string> + <string name="reading_vcard_canceled_title">D\'Liese vun de vCard-Date gouf ënnerbrach</string> + <string name="importing_vcard_finished_title">D\'vCard <xliff:g id="filename" example="import.vcf">%s</xliff:g> ass fäerdeg importéiert</string> + <string name="importing_vcard_canceled_title">Importéiere vum Fichier <xliff:g id="filename" example="export.vcf">%s</xliff:g> ofgebrach</string> + <string name="vcard_import_will_start_message"><xliff:g id="filename" example="import.vcf">%s</xliff:g> gëtt geschwënn importéiert.</string> + <string name="vcard_import_will_start_message_with_default_name">De Fichier gëtt geschwënn importéiert.</string> + <string name="vcard_import_request_rejected_message">D\'vCard-Importufro gouf rejetéiert. Probéier méi spéit nees.</string> + <string name="vcard_export_will_start_message"><xliff:g id="filename" example="import.vcf">%s</xliff:g> gëtt geschwënn exportéiert.</string> + <string name="vcard_export_request_rejected_message">D\'vCard-Exportufro gouf rejetéiert. Probéier méi spéit nees.</string> + <string name="vcard_unknown_filename">Kontakt</string> + <string name="caching_vcard_message">D\'vCard-Date ginn an den Tëschespäichere gelueden. Den Import fänkt geschwënn un.</string> + <string name="percentage"><xliff:g id="percentage" example="50">%s</xliff:g><xliff:g id="percentsign" example="%">%%</xliff:g></string> + <string name="vcard_import_failed">Konnt d\'vCard net importéieren.</string> + <string name="import_failure_no_vcard_file" product="nosdcard">Kee vCard-Fichier am Späicher fonnt.</string> + <string name="import_failure_no_vcard_file" product="default">Kee vCard-Fichier op der SD-Kaart fonnt.</string> + <string name="nfc_vcard_file_name">Kontakt iwwer NFC empfaangen</string> + <string name="confirm_export_title">Kontakter exportéieren?</string> + <string name="select_vcard_title">vCard-Fichier auswielen</string> + <string name="import_one_vcard_string">Ee vCard-Fichier importéieren</string> + <string name="import_multiple_vcard_string">Méi vCard-Fichieren importéieren</string> + <string name="import_all_vcard_string">All vCard-Fichieren importéieren</string> + <string name="searching_vcard_message" product="nosdcard">Sichen no vCard-Daten am Späicher\u2026</string> + <string name="searching_vcard_message" product="default">Sichen no vCard-Daten op der SD-Kaart\u2026</string> + <string name="caching_vcard_title">Tëschespäicher gëtt gefëllt</string> + <string name="scanning_sdcard_failed_message" product="nosdcard">De Späicher konnt net duerchsicht ginn. (Grond: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + <string name="scanning_sdcard_failed_message" product="default">D\'SD-Kaart konnt net duerchsicht ginn. (Grond: \"<xliff:g id="fail_reason">%s</xliff:g>\")</string> + <string name="progress_notifier_message"><xliff:g id="current_number">%s</xliff:g>/<xliff:g id="total_number">%s</xliff:g>: <xliff:g id="name" example="Joe Due">%s</xliff:g> gëtt importéiert</string> + <string name="export_to_sdcard" product="default">An de Späicher exportéieren</string> + <string name="display_options_sort_list_by">Zortéieren no</string> + <string name="display_options_sort_by_given_name">Virnumm</string> + <string name="display_options_sort_by_family_name">Familljennumm</string> + <string name="display_options_view_names_as">Format vum Numm</string> + <string name="display_options_view_given_name_first">Virnumm fir d\'éischt</string> + <string name="display_options_view_family_name_first">Familljennumm fir d\'éischt</string> + <string name="share_visible_contacts">Siichtbar Kontakter deelen</string> + <string name="dialog_import_export">Kontakter importéieren/exportéieren</string> + <string name="dialog_import">Kontakter importéieren</string> + <string name="share_error">Dëse Kontakt kann net gedeelt ginn.</string> + <string name="menu_search">Sichen</string> + <string name="menu_contacts_filter">Kontakter fir unzeweisen</string> + <string name="activity_title_contacts_filter">Kontakter fir unzeweisen</string> + <string name="custom_list_filter">Personaliséiert Usiicht definéieren</string> + <string name="hint_findContacts">Kontakter fannen</string> + <string name="contactsFavoritesLabel">Favoritten</string> + <string name="listTotalAllContactsZero">Keng Kontakter.</string> + <string name="listTotalAllContactsZeroCustom">Keng siichtbar Kontakter.</string> + <string name="listTotalAllContactsZeroStarred">Keng Favoritten.</string> + <string name="listTotalAllContactsZeroGroup">Keng Kontakter an der Grupp <xliff:g id="name" example="Friends">%s</xliff:g></string> + <string name="menu_clear_frequents">Dacks kontaktéiert eidel maachen</string> + <string name="menu_select_sim">SIM-Kaart auswielen</string> + <string name="menu_accounts">Konten</string> + <string name="menu_import_export">Import/Export</string> + <string name="contact_status_update_attribution">iwwer <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string> + <string name="contact_status_update_attribution_with_date"><xliff:g id="date" example="3 hours ago">%1$s</xliff:g> iwwer <xliff:g id="source" example="Google Talk">%2$s</xliff:g></string> + <string name="action_menu_back_from_search">Ophale mat Sichen</string> + <string name="description_clear_search">Sich läschen</string> + <string name="settings_contact_display_options_title">Uweisoptioune vun de Kontakter</string> +</resources> diff --git a/res/values-lt/cm_strings.xml b/res/values-lt/cm_strings.xml new file mode 100644 index 00000000..8bf96c6c --- /dev/null +++ b/res/values-lt/cm_strings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Vietinė planšetinio kompiuterio paskyra</string> + <string name="local_storage_account" product="default">Vietinė telefono paskyra</string> + <string name="import_contacts_sim">Importuoti kontaktus iš SIM kortelės?</string> + <string name="manage_sim_contacts">Tvarkyti SIM kortelės kontaktus</string> + <string name="export_to_sim">Eksportuoti į SIM kortelę</string> + <string name="fail_reason_import_vcard">„<xliff:g id="name">%s</xliff:g>“ negali būti importuota, dėl I / O klaidos</string> + <string name="contact_share_failed_toast">Ne daugiau kaip <xliff:g id="count">%d</xliff:g> kontaktų gali būti bendrinama</string> + <string name="label_groups">Grupė</string> + <string name="exporting">Eksportuojama\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> iš <xliff:g id="total_number">%2$s</xliff:g> failų</string> + <string name="export_failed">Eksportavimas nepavyko</string> + <string name="sim_card_full">SIM kortelė yra pilna</string> + <string name="export_finished">Eksportavimas baigtas</string> + <string name="tag_too_long">Kontakto vardas yra per ilgas</string> + <string name="sim_contacts_not_loaded">Nepavyko įkelti SIM kontaktų</string> + <plurals name="export_cancelled"> + <item quantity="one">Eksportavimas buvo atšauktas, %d elementas buvo eksportuotas</item> + <item quantity="few">Eksportavimas buvo atšauktas, %d elementai buvo eksportuoti</item> + <item quantity="other">Eksportavimas buvo atšauktas, %d elementų buvo eksportuota</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> neturi telefono numerio arba el. pašto</string> + <string name="import_from_sim_select">Pasirinkite kortelę importuoti</string> + <string name="no_sdcard_title" product="nosdcard">Saugykla nepasiekiama</string> + <string name="no_sdcard_title" product="default">Nėras SD kortelės</string> + <string name="deleteConfirmation_title">Ištrinti kontaktą?</string> + <string name="deleteConfirmation">Šis kontaktas bus ištrintas.</string> + <string name="copy_done">Kontaktas buvo sėkmingai nukopijuotas</string> + <string name="copy_failure">Nepavyko nukopijuoti kontakto</string> + <string name="card_no_space">Nukopijuoti kontakto nepavyko, SIM kortelė yra pilna</string> + <string name="settings_contact_display_options_description">Konfigūruoti kaip jūsų kontaktai yra rodomi ir rūšiuojami.</string> + <string name="ip_call_by_slot">IP skambutis per <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nėra IP numerio</string> + <string name="no_ip_number_on_sim_card">IP numerio SIM kortelėje nėra</string> + <string name="set_ip_number">Nustatyti IP numerį</string> + <string name="ipcall_dialog_title">IP skambučio nustatymai</string> + <string name="ipcall_dialog_edit_hint">Prašome įvesti IP priešdėlį</string> + <string name="import_contacts_from_all_cards">Importuoti kontaktus iš visų SIM kortelių</string> + <string name="select_path">Pasirinkti kelią</string> + <string name="select_sim">Pasirinkti SIM</string> +</resources> diff --git a/res/values-lv/cm_strings.xml b/res/values-lv/cm_strings.xml new file mode 100644 index 00000000..f9a00afd --- /dev/null +++ b/res/values-lv/cm_strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Vietējais planšetes konts</string> + <string name="local_storage_account" product="default">Vietējais telefona konts</string> + <string name="export_to_sim">Eksportēt uz SIM karti</string> + <string name="label_groups">Grupa</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> no <xliff:g id="total_number">%2$s</xliff:g> failiem</string> + <string name="export_failed">Eksports neizdevās</string> + <string name="export_finished">Eksports pabeigts</string> + <string name="import_from_sim_select">Izvēlēties karti, kurā importēt</string> + <string name="no_sdcard_title" product="nosdcard">Krātuve nav pieejama</string> + <string name="no_sdcard_title" product="default">Nav SD kartes</string> + <string name="deleteConfirmation_title">Dzēst kontaktu?</string> + <string name="deleteConfirmation">Šī kontakts tiks dzēsts.</string> + <string name="no_ip_number">Nav IP numura</string> + <string name="no_ip_number_on_sim_card">SIM kartē nav IP numura</string> + <string name="ipcall_dialog_edit_hint">Lūdzu ievadiet IP priedēkli</string> + <string name="select_sim">Izvēlieties SIM</string> +</resources> diff --git a/res/values-nb/cm_strings.xml b/res/values-nb/cm_strings.xml new file mode 100644 index 00000000..6b7035a6 --- /dev/null +++ b/res/values-nb/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokal tablet konto</string> + <string name="local_storage_account" product="default">Lokal mobilkonto</string> + <string name="import_contacts_sim">Importere kontakter fra SIM-kortet?</string> + <string name="manage_sim_contacts">Administrere SIM-kortkontakter</string> + <string name="export_to_sim">Eksportere til SIM-kortet</string> + <string name="fail_reason_import_vcard">\' <xliff:g id="name">%s\' </xliff:g> kan ikke importeres pga I/O feil</string> + <string name="contact_share_failed_toast">Ikke mer enn <xliff:g id="count">%d</xliff:g> kontakter kan bli delt</string> + <string name="label_groups">Gruppe</string> + <string name="exporting">Eksporterer\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> <xliff:g id="total_number">%2$s</xliff:g> filer</string> + <string name="export_failed">Eksporteringen mislyktes</string> + <string name="sim_card_full">SIM-kortet er fullt</string> + <string name="export_finished">Eksporten er ferdig</string> + <string name="tag_too_long">Navn på kontakt er for langt</string> + <string name="sim_contacts_not_loaded">Kan ikke laste inn SIM-kontakter</string> + <plurals name="export_cancelled"> + <item quantity="one">Eksporten ble avbrutt, %d element ble eksportert</item> + <item quantity="other">Eksporten ble avbrutt, %d elementer ble eksportert</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> har ikke ett telefonnummer eller e-postadresse</string> + <string name="import_from_sim_select">Velg kort å importere</string> + <string name="no_sdcard_title" product="nosdcard">Lagring utilgjengelig</string> + <string name="no_sdcard_title" product="default">Ingen SD-kort</string> + <string name="deleteConfirmation_title">Slette kontakt?</string> + <string name="deleteConfirmation">Denne kontakten vil bli slettet.</string> + <string name="copy_done">Kontakten ble vellykket kopiert</string> + <string name="copy_failure">Kopiering av kontakten mislyktes</string> + <string name="card_no_space">Kopiering av kontakten mislyktes, SIM-kortet er fullt</string> + <string name="settings_contact_display_options_description">Konfigurer hvordan kontaktene skal vises og sorteres.</string> + <string name="ip_call_by_slot">IP-samtale med <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Ingen IP-nummer</string> + <string name="no_ip_number_on_sim_card">Ingen IP-nummeret på SIM-kortet</string> + <string name="set_ip_number">Angi IP-nummeret</string> + <string name="ipcall_dialog_title">IP Samtaleinnstillinger</string> + <string name="ipcall_dialog_edit_hint">Skriv inn IP prefiks</string> + <string name="import_contacts_from_all_cards">Importere kontakter fra alle SIM-kort</string> + <string name="select_path">Velg bane</string> + <string name="select_sim">Velg SIM</string> +</resources> diff --git a/res/values-nl/cm_strings.xml b/res/values-nl/cm_strings.xml new file mode 100644 index 00000000..74ffc1c1 --- /dev/null +++ b/res/values-nl/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokaal tabletaccount</string> + <string name="local_storage_account" product="default">Lokaal telefoonaccount</string> + <string name="import_contacts_sim">Contacten van simkaart importeren?</string> + <string name="manage_sim_contacts">Contacten op simkaart beheren</string> + <string name="export_to_sim">Exporteren naar simkaart</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' kon niet worden geïmporteerd door een lees-/schrijffout</string> + <string name="contact_share_failed_toast">Er kunnen niet meer dan <xliff:g id="count">%d</xliff:g> contacten worden gedeeld</string> + <string name="label_groups">Groep</string> + <string name="exporting">Exporteren\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> van <xliff:g id="total_number">%2$s</xliff:g> bestanden</string> + <string name="export_failed">Exporteren mislukt</string> + <string name="sim_card_full">Simkaart is vol</string> + <string name="export_finished">Exporteren voltooid</string> + <string name="tag_too_long">Naam van contact is te lang</string> + <string name="sim_contacts_not_loaded">Kan SIM-contacten niet laden</string> + <plurals name="export_cancelled"> + <item quantity="one">Exporteren geannuleerd, %d item geëxporteerd</item> + <item quantity="other">Exporteren geannuleerd, %d items geëxporteerd</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> beschikt niet over een telefoonnummer of e-mailadres</string> + <string name="import_from_sim_select">Kies kaart om te importeren</string> + <string name="no_sdcard_title" product="nosdcard">Opslag niet beschikbaar</string> + <string name="no_sdcard_title" product="default">Geen SD-kaart</string> + <string name="deleteConfirmation_title">Contact verwijderen?</string> + <string name="deleteConfirmation">Dit contact wordt verwijderd.</string> + <string name="copy_done">Contact kopiëren gelukt</string> + <string name="copy_failure">Contact kopiëren mislukt</string> + <string name="card_no_space">Kopiëren van contact mislukt, simkaart is vol</string> + <string name="settings_contact_display_options_description">Instellen hoe uw contacten worden weergegeven en gesorteerd.</string> + <string name="ip_call_by_slot">IP-oproep via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Geen IP-nummer</string> + <string name="no_ip_number_on_sim_card">Geen IP-nummer op simkaart</string> + <string name="set_ip_number">IP-nummer instellen</string> + <string name="ipcall_dialog_title">Instellingen IP-oproep</string> + <string name="ipcall_dialog_edit_hint">Voer IP-voorvoegsel in</string> + <string name="import_contacts_from_all_cards">Contacten van alle simkaarten importeren</string> + <string name="select_path">Pad selecteren</string> + <string name="select_sim">Simkaart selecteren</string> +</resources> diff --git a/res/values-pl/cm_strings.xml b/res/values-pl/cm_strings.xml new file mode 100644 index 00000000..ee771d5b --- /dev/null +++ b/res/values-pl/cm_strings.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokalne konto tabletu</string> + <string name="local_storage_account" product="default">Lokalne konto telefonu</string> + <string name="import_contacts_sim">Importować kontakty z karty SIM?</string> + <string name="manage_sim_contacts">Zarządzaj kontaktami z karty SIM</string> + <string name="export_to_sim">Eksportuj do karty SIM</string> + <string name="fail_reason_import_vcard"><xliff:g id="name">%s</xliff:g> nie może zostać importowany z powodu błędu we/wy</string> + <string name="contact_share_failed_toast">Nie więcej niż <xliff:g id="count">%d</xliff:g> kontaktów może zostać udostępnionych</string> + <string name="label_groups">Grupa</string> + <string name="exporting">Eksportowanie\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> z <xliff:g id="total_number">%2$s</xliff:g> plików</string> + <string name="export_failed">Eksport nie powiódł się</string> + <string name="sim_card_full">Karta SIM jest pełna</string> + <string name="export_finished">Eksport zakończony</string> + <string name="tag_too_long">Nazwa kontaktu jest zbyt długa</string> + <string name="sim_contacts_not_loaded">Nie można załadować kontaktów z SIM</string> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> nie ma numeru telefonu ani adresu e-mail</string> + <string name="import_from_sim_select">Wybierz kartę do zimportowania</string> + <string name="no_sdcard_title" product="nosdcard">Pamięć niedostępna</string> + <string name="no_sdcard_title" product="default">Brak karty SD</string> + <string name="deleteConfirmation_title">Usunąć kontakt?</string> + <string name="deleteConfirmation">Ten kontakt zostanie usunięty.</string> + <string name="copy_done">Kontakt został skopiowany pomyślnie</string> + <string name="copy_failure">Kopiowanie kontaktu nie powiodło się</string> + <string name="card_no_space">Kopiowanie kontaktu nie powiodło się, karta SIM jest pełna</string> + <string name="settings_contact_display_options_description">Skonfiguruj jak wyświetlane i sortowane mają być twoje kontakty.</string> + <string name="ip_call_by_slot">Połączenie IP przez <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Brak numeru IP</string> + <string name="no_ip_number_on_sim_card">Brak numeru IP na karcie SIM</string> + <string name="set_ip_number">Ustaw numer IP</string> + <string name="ipcall_dialog_title">Ustawienia połączeń IP</string> + <string name="ipcall_dialog_edit_hint">Proszę wpisać prefiks IP</string> + <string name="import_contacts_from_all_cards">Import kontaktów z wszystkich kart SIM</string> + <string name="select_path">Wybierz ścieżkę</string> + <string name="select_sim">Wybierz SIM</string> +</resources> diff --git a/res/values-pt-rBR/cm_strings.xml b/res/values-pt-rBR/cm_strings.xml new file mode 100644 index 00000000..07c3698d --- /dev/null +++ b/res/values-pt-rBR/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Conta local de tablet</string> + <string name="local_storage_account" product="default">Conta local de telefone</string> + <string name="import_contacts_sim">Importar contatos do cartão SIM?</string> + <string name="manage_sim_contacts">Gerenciar contatos do cartão SIM</string> + <string name="export_to_sim">Exportar para o cartão SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' não pôde ser importado devido a um erro</string> + <string name="contact_share_failed_toast">Não podem ser compartilhados mais que <xliff:g id="count">%d</xliff:g> contatos</string> + <string name="label_groups">Grupo</string> + <string name="exporting">Exportando\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> de <xliff:g id="total_number">%2$s</xliff:g> arquivos</string> + <string name="export_failed">Falha na exportação</string> + <string name="sim_card_full">O cartão SIM está cheio</string> + <string name="export_finished">Exportação concluída</string> + <string name="tag_too_long">O nome do contato é muito longo</string> + <string name="sim_contacts_not_loaded">Não é possível carregar os contatos do cartão SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">A exportação foi cancelada, %d item foi exportado</item> + <item quantity="other">A exportação foi cancelada, %d itens foram exportados</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> não tem um número de telefone ou endereço de e-mail</string> + <string name="import_from_sim_select">Escolha o cartão para importar</string> + <string name="no_sdcard_title" product="nosdcard">Cartão SD indisponível</string> + <string name="no_sdcard_title" product="default">Nenhum cartão SD</string> + <string name="deleteConfirmation_title">Apagar contato?</string> + <string name="deleteConfirmation">Este contato será apagado.</string> + <string name="copy_done">Contato foi copiado com sucesso</string> + <string name="copy_failure">Falha ao copiar o contato</string> + <string name="card_no_space">Falha ao copiar o contato, o cartão SIM está cheio</string> + <string name="settings_contact_display_options_description">Defina como os seus contatos são exibidos e classificados.</string> + <string name="ip_call_by_slot">Chamada IP por <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nenhum número IP</string> + <string name="no_ip_number_on_sim_card">Nenhum número IP no cartão SIM</string> + <string name="set_ip_number">Definir número IP</string> + <string name="ipcall_dialog_title">Configurações de chamadas IP</string> + <string name="ipcall_dialog_edit_hint">Por favor, insira o prefixo IP</string> + <string name="import_contacts_from_all_cards">Importar contatos de todos os cartões SIM</string> + <string name="select_path">Selecionar caminho</string> + <string name="select_sim">Selecione o SIM</string> +</resources> diff --git a/res/values-pt-rPT/cm_strings.xml b/res/values-pt-rPT/cm_strings.xml new file mode 100644 index 00000000..7799beb8 --- /dev/null +++ b/res/values-pt-rPT/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Conta local do tablet</string> + <string name="local_storage_account" product="default">Conta local do telefone</string> + <string name="import_contacts_sim">Importar contactos do cartão SIM?</string> + <string name="manage_sim_contacts">Gerir os contactos do cartão SIM</string> + <string name="export_to_sim">Exportar para o cartão SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' não pôde ser importado devido a um erro</string> + <string name="contact_share_failed_toast">Não podem ser partilhados mais que <xliff:g id="count">%d</xliff:g> contactos</string> + <string name="label_groups">Grupo</string> + <string name="exporting">A exportar\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> de <xliff:g id="total_number">%2$s</xliff:g> ficheiros</string> + <string name="export_failed">A exportação falhou</string> + <string name="sim_card_full">O cartão SIM está cheio</string> + <string name="export_finished">Exportação terminada</string> + <string name="tag_too_long">O nome do contacto é muito longo</string> + <string name="sim_contacts_not_loaded">Não é possível carregar os contactos do SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">A exportação foi cancelada, %d item foi exportado</item> + <item quantity="other">A exportação foi cancelada, %d itens foram exportados</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> não tem um número de telefone ou endereço de e-mail</string> + <string name="import_from_sim_select">Escolher o cartão a importar</string> + <string name="no_sdcard_title" product="nosdcard">Armazenamento indisponível</string> + <string name="no_sdcard_title" product="default">Sem cartão SD</string> + <string name="deleteConfirmation_title">Apagar contacto?</string> + <string name="deleteConfirmation">Este contacto será apagado.</string> + <string name="copy_done">O contacto foi copiado com sucesso</string> + <string name="copy_failure">Falhou a cópia do contacto</string> + <string name="card_no_space">A cópia do contacto falhou, o cartão SIM está cheio</string> + <string name="settings_contact_display_options_description">Defina como os seus contactos são exibidos e classificados.</string> + <string name="ip_call_by_slot">Chamada IP com <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Nenhum número IP</string> + <string name="no_ip_number_on_sim_card">Nenhum número IP no cartão SIM</string> + <string name="set_ip_number">Colocar o número IP</string> + <string name="ipcall_dialog_title">Definições de chamada por IP</string> + <string name="ipcall_dialog_edit_hint">Por favor, insira o prefixo IP</string> + <string name="import_contacts_from_all_cards">Importar contactos de todos os cartões SIM</string> + <string name="select_path">Selecionar o caminho</string> + <string name="select_sim">Selecionar SIM</string> +</resources> diff --git a/res/values-ro/cm_strings.xml b/res/values-ro/cm_strings.xml new file mode 100644 index 00000000..ca5787de --- /dev/null +++ b/res/values-ro/cm_strings.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Cont local tabletă</string> + <string name="local_storage_account" product="default">Cont local telefon</string> + <string name="export_to_sim">Export în cartela SIM</string> + <string name="label_groups">Grup</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> din <xliff:g id="total_number">%2$s</xliff:g> fişiere</string> + <string name="export_failed">Exportul a eșuat</string> + <string name="sim_card_full">Cartela SIM este plină</string> + <string name="export_finished">Exportul s-a terminat</string> + <string name="tag_too_long">Numele contactului este prea lung</string> + <string name="import_from_sim_select">Alege cardul ce se va importa</string> + <string name="no_sdcard_title" product="nosdcard">Stocare indisponibilă</string> + <string name="no_sdcard_title" product="default">Nu există card SD</string> + <string name="deleteConfirmation_title">Ştergeţi persoana de contact?</string> + <string name="deleteConfirmation">Acest contact va fi şters.</string> + <string name="copy_failure">Copierea contactului a eșuat</string> + <string name="ip_call_by_slot">Apel IP prin <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Niciun număr de IP</string> + <string name="no_ip_number_on_sim_card">Niciun număr de IP pe cartela SIM</string> + <string name="ipcall_dialog_edit_hint">Introduceți prefixul IP</string> + <string name="select_sim">Selectaţi SIM</string> +</resources> diff --git a/res/values-ru/cm_strings.xml b/res/values-ru/cm_strings.xml new file mode 100644 index 00000000..9c81f10b --- /dev/null +++ b/res/values-ru/cm_strings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Локальная учётная запись планшета</string> + <string name="local_storage_account" product="default">Локальная учётная запись телефона</string> + <string name="import_contacts_sim">Импортировать контакты с SIM-карты?</string> + <string name="manage_sim_contacts">Управление контактами SIM-карты</string> + <string name="export_to_sim">Экспорт на SIM-карту</string> + <string name="fail_reason_import_vcard">Не удалось импортировать файл «<xliff:g id="name">%s</xliff:g>» из-за ошибки ввода-вывода</string> + <string name="contact_share_failed_toast">Можно отправить не более <xliff:g id="count">%d</xliff:g> контактов</string> + <string name="label_groups">Группа</string> + <string name="exporting">Экспорт\u2026</string> + <string name="reading_vcard_files">Обработка: <xliff:g id="current_number">%1$s</xliff:g> из <xliff:g id="total_number">%2$s</xliff:g></string> + <string name="export_failed">Не удалось выполнить экспорт</string> + <string name="sim_card_full">SIM-карта заполнена</string> + <string name="export_finished">Экспорт завершён</string> + <string name="tag_too_long">Слишком длинное имя контакта</string> + <string name="sim_contacts_not_loaded">Не удалось загрузить контакты SIM-карты</string> + <plurals name="export_cancelled"> + <item quantity="one">Экспорт отменён, экспортирован %d элемент</item> + <item quantity="few">Экспорт отменён, экспортировано %d элемента</item> + <item quantity="other">Экспорт отменён, экспортировано %d элементов</item> + </plurals> + <string name="export_no_phone_or_email">У контакта «<xliff:g id="name">%s</xliff:g>» нет номера телефона или адреса электронной почты</string> + <string name="import_from_sim_select">Выберите карту для импорта</string> + <string name="no_sdcard_title" product="nosdcard">Внешний накопитель недоступен</string> + <string name="no_sdcard_title" product="default">SD-карта не подключена</string> + <string name="deleteConfirmation_title">Удалить контакт?</string> + <string name="deleteConfirmation">Этот контакт будет удалён.</string> + <string name="copy_done">Контакт успешно скопирован</string> + <string name="copy_failure">Копирование контакта не удалось</string> + <string name="card_no_space">Копирование контакта не удалось, SIM-карта заполнена</string> + <string name="settings_contact_display_options_description">Настройка параметров отображения и сортировки контактов.</string> + <string name="ip_call_by_slot">IP-вызов через <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Нет IP-номера</string> + <string name="no_ip_number_on_sim_card">На SIM-карте нет IP-номера</string> + <string name="set_ip_number">Задать IP-номер</string> + <string name="ipcall_dialog_title">Настройки IP-телефонии</string> + <string name="ipcall_dialog_edit_hint">Введите IP-префикс</string> + <string name="import_contacts_from_all_cards">Импорт контактов со всех SIM-карт</string> + <string name="select_path">Выбрать путь</string> + <string name="select_sim">Выберите SIM-карту</string> +</resources> diff --git a/res/values-si-rLK/cm_strings.xml b/res/values-si-rLK/cm_strings.xml new file mode 100644 index 00000000..1f3da679 --- /dev/null +++ b/res/values-si-rLK/cm_strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">ස්ථානීය ටැබ්ලට් ගිණුම</string> + <string name="local_storage_account" product="default">ස්ථානීය දුරකථන ගිණුම</string> + <string name="export_to_sim">සිම් කාඩ්පතට නිර්යාත කරන්න</string> + <string name="label_groups">කාණ්ඩය</string> + <string name="reading_vcard_files">ගොනු <xliff:g id="total_number">%2$s</xliff:g> න් <xliff:g id="current_number">%1$s</xliff:g></string> + <string name="export_failed">නිර්යාතය අසමත්විය</string> + <string name="export_finished">නිර්යාතය නිමාවුනි</string> + <string name="import_from_sim_select">ආයාත කිරීමට කාඩ්පත තෝරන්න</string> + <string name="no_sdcard_title" product="nosdcard">ආචයනය ලබාගත නොහැක</string> + <string name="no_sdcard_title" product="default">SD කාඩ්පතක් නොමැත</string> + <string name="deleteConfirmation_title">සම්බන්ධතාව මකන්නද?</string> + <string name="deleteConfirmation">මෙම සම්බන්ධතාව මකා දැමෙනු ඇත.</string> + <string name="no_ip_number">IP අංකයක් නැත</string> + <string name="no_ip_number_on_sim_card">සිම් පතෙහි IP අංකයක් නැත</string> + <string name="ipcall_dialog_edit_hint">කරුණාකර IP උපසර්ගය ආදානය කරන්න</string> + <string name="select_sim">සිම්පත තෝරන්න</string> +</resources> diff --git a/res/values-sk/cm_strings.xml b/res/values-sk/cm_strings.xml new file mode 100644 index 00000000..9416257a --- /dev/null +++ b/res/values-sk/cm_strings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Miestny účet tabletu</string> + <string name="local_storage_account" product="default">Miestny účet telefónu</string> + <string name="import_contacts_sim">Importovať kontakty z karty SIM?</string> + <string name="manage_sim_contacts">Spravovať kontakty na karte SIM</string> + <string name="export_to_sim">Exportovať na kartu SIM</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' nie je možné importovať kvôli vstupno-výstupnej chybe</string> + <string name="contact_share_failed_toast">Nie viac ako <xliff:g id="count">%d</xliff:g> kontaktov môže byť zdieľaných</string> + <string name="label_groups">Skupina</string> + <string name="exporting">Exportovanie\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> z <xliff:g id="total_number">%2$s</xliff:g> súborov</string> + <string name="export_failed">Export zlyhal</string> + <string name="sim_card_full">Karta SIM je plná</string> + <string name="export_finished">Export sa dokončil</string> + <string name="tag_too_long">Meno kontaktu je príliš dlhé</string> + <string name="sim_contacts_not_loaded">Nepodarilo sa načítať kontakty zo SIM</string> + <plurals name="export_cancelled"> + <item quantity="one">Export bol zrušený, %d položka bola exportovaná</item> + <item quantity="few">Export bol zrušený, %d položky boli exportované</item> + <item quantity="other">Export bol zrušený, %d položiek bolo exportovaných</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> nemá svoje telefónne číslo alebo e-mailovú adresu</string> + <string name="import_from_sim_select">Vyberte kartu na importovanie</string> + <string name="no_sdcard_title" product="nosdcard">Nedostupné úložisko</string> + <string name="no_sdcard_title" product="default">Žiadna karta SD</string> + <string name="deleteConfirmation_title">Vymazať kontakt?</string> + <string name="deleteConfirmation">Tento kontakt sa odstráni.</string> + <string name="copy_done">Kontakt bol úspešne skopírovaný</string> + <string name="copy_failure">Kopírovanie kontaktu zlyhalo</string> + <string name="card_no_space">Kopírovanie kontaktu zlyhalo, karta SIM je plná</string> + <string name="settings_contact_display_options_description">Nastaviť, ako sa majú kontakty zobrazovať a zoraďovať.</string> + <string name="ip_call_by_slot">IP hovor cez <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Žiadne IP číslo</string> + <string name="no_ip_number_on_sim_card">Žiadne IP číslo na karte SIM</string> + <string name="set_ip_number">Nastaviť IP číslo</string> + <string name="ipcall_dialog_title">Nastavenia IP hovoru</string> + <string name="ipcall_dialog_edit_hint">Prosím, zadajte predčíslie IP</string> + <string name="import_contacts_from_all_cards">Importovať kontakty zo všetkých kariet SIM</string> + <string name="select_path">Vyberte cestu</string> + <string name="select_sim">Vyberte SIM</string> +</resources> diff --git a/res/values-sr/cm_strings.xml b/res/values-sr/cm_strings.xml new file mode 100644 index 00000000..e587fd97 --- /dev/null +++ b/res/values-sr/cm_strings.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Локални налог таблета</string> + <string name="local_storage_account" product="default">Локални налог телефона</string> + <string name="import_contacts_sim">Увези контакте са SIM картице?</string> + <string name="manage_sim_contacts">Управљај контактима са SIM картице</string> + <string name="export_to_sim">Извези на SIM картицу</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' неможе бити увезен због I/O грешке</string> + <string name="contact_share_failed_toast">Не више од <xliff:g id="count">%d</xliff:g> контаката може бити дељено</string> + <string name="label_groups">Група</string> + <string name="exporting">Извоз\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> од <xliff:g id="total_number">%2$s</xliff:g> фајлова</string> + <string name="export_failed">Извоз није успео</string> + <string name="sim_card_full">SIM картица је пуна</string> + <string name="export_finished">Извоз завршен</string> + <string name="tag_too_long">Име контакта је предуго</string> + <string name="sim_contacts_not_loaded">Не могу учитати SIM контакте</string> + <plurals name="export_cancelled"> + <item quantity="one">Извоз је отказан. %d ставка је извежена</item> + <item quantity="few">Извоз је отказан. %d ставки је извежено</item> + <item quantity="many">Извоз је отказан. %d ставки је извежено</item> + <item quantity="other">Извоз је отказан. %d ставки је извежено</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> нема број телефона или адресу е-поште</string> + <string name="import_from_sim_select">Изабери картицу за увоз</string> + <string name="no_sdcard_title" product="nosdcard">Складиште недоступно</string> + <string name="no_sdcard_title" product="default">Нема SD картице</string> + <string name="deleteConfirmation_title">Избриши контакт?</string> + <string name="deleteConfirmation">Овај контакт ће бити избрисан.</string> + <string name="copy_done">Контакт је копиран успешно</string> + <string name="copy_failure">Копирање контакта није успело</string> + <string name="card_no_space">Копирање контакта није успело, SIM картица је пуна</string> + <string name="settings_contact_display_options_description">Конфигуриши како су твоји контакти приказани и сортирани.</string> + <string name="ip_call_by_slot">IP позив преко <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Нема IP броја</string> + <string name="no_ip_number_on_sim_card">Нема IP броја на SIM картици</string> + <string name="set_ip_number">Постави IP број</string> + <string name="ipcall_dialog_title">Подешавања IP позива</string> + <string name="ipcall_dialog_edit_hint">Унеси IP префикс</string> + <string name="import_contacts_from_all_cards">Увези контакте са свих SIM картица</string> + <string name="select_path">Изабери путању</string> + <string name="select_sim">Изабери SIM</string> +</resources> diff --git a/res/values-sv/cm_strings.xml b/res/values-sv/cm_strings.xml new file mode 100644 index 00000000..97340c7b --- /dev/null +++ b/res/values-sv/cm_strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Lokalt surfplattekonto</string> + <string name="local_storage_account" product="default">Lokalt telefonkonto</string> + <string name="export_to_sim">Exportera till SIM-kort</string> + <string name="label_groups">Grupp</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> av <xliff:g id="total_number">%2$s</xliff:g> filer</string> + <string name="export_failed">Exporten misslyckades</string> + <string name="export_finished">Export slutförd</string> + <string name="import_from_sim_select">Välj kort att importera</string> + <string name="no_sdcard_title" product="nosdcard">Lagring ej tillgänglig</string> + <string name="no_sdcard_title" product="default">Inget SD-kort</string> + <string name="deleteConfirmation_title">Ta bort kontakt?</string> + <string name="deleteConfirmation">Denna kontakt kommer tas bort.</string> + <string name="no_ip_number">Inget IP-nummer</string> + <string name="no_ip_number_on_sim_card">Inget IP-nummer på SIM-kort</string> + <string name="ipcall_dialog_edit_hint">Skriv in IP-prefixet</string> + <string name="select_sim">Välj SIM</string> +</resources> diff --git a/res/values-th/cm_strings.xml b/res/values-th/cm_strings.xml new file mode 100644 index 00000000..64f6603d --- /dev/null +++ b/res/values-th/cm_strings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">บัญชีภายในแท็บเล็ต</string> + <string name="local_storage_account" product="default">บัญชีภายในโทรศัพท์</string> + <string name="export_to_sim">ส่งออกไปยังซิมการ์ด</string> + <string name="label_groups">กลุ่ม</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> จาก <xliff:g id="total_number">%2$s</xliff:g> ไฟล์</string> + <string name="export_failed">ส่งออกล้มเหลว</string> + <string name="export_finished">ส่งออกเสร็จสมบูรณ์</string> + <string name="import_from_sim_select">เลือกบัตรที่จะนำเข้า</string> + <string name="no_sdcard_title" product="nosdcard">ไม่มีที่เก็บข้อมูล</string> + <string name="no_sdcard_title" product="default">ไม่มี SD card</string> + <string name="deleteConfirmation_title">ลบรายชื่อ?</string> + <string name="deleteConfirmation">รายชื่อนี้จะถูกลบออก</string> + <string name="no_ip_number">ไม่มีหมายเลข IP</string> + <string name="no_ip_number_on_sim_card">ไม่มีหมายเลข IP ในซิมการ์ด</string> + <string name="ipcall_dialog_edit_hint">กรุณากรอกเลขนำหน้า IP</string> + <string name="select_sim">เลือกซิมการ์ด</string> +</resources> diff --git a/res/values-tr/cm_strings.xml b/res/values-tr/cm_strings.xml new file mode 100644 index 00000000..de4b6b66 --- /dev/null +++ b/res/values-tr/cm_strings.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Yerel tablet hesabı</string> + <string name="local_storage_account" product="default">Yerel telefon hesabı</string> + <string name="import_contacts_sim">Kişiler SIM karttan alınsın mı?</string> + <string name="manage_sim_contacts">SIM kart kişilerini yönet</string> + <string name="export_to_sim">SIM karta aktar</string> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' bir G/Ç hatasından dolayı alınamadı</string> + <string name="contact_share_failed_toast"><xliff:g id="count">%d</xliff:g> \'den fazla kişi paylaşılamaz</string> + <string name="label_groups">Grup</string> + <string name="exporting">Dışa aktarılıyor\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> / <xliff:g id="total_number">%2$s</xliff:g> dosya</string> + <string name="export_failed">Aktarım başarısız</string> + <string name="sim_card_full">SIM kart dolu</string> + <string name="export_finished">Dışa aktarım bitti</string> + <string name="tag_too_long">Kişi adı çok uzun</string> + <string name="sim_contacts_not_loaded">SIM kişileri yüklenemedi</string> + <plurals name="export_cancelled"> + <item quantity="one">Aktarma iptal edildi, %d öge aktarıldı</item> + <item quantity="other">Aktarma iptal edildi, %d öge aktarıldı</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> bir telefon numarasına veya e-posta adresine sahip değil</string> + <string name="import_from_sim_select">Alınacak kartı seç</string> + <string name="no_sdcard_title" product="nosdcard">Depolama kullanılabilir değil</string> + <string name="no_sdcard_title" product="default">SD kart yok</string> + <string name="deleteConfirmation_title">Kişi silinsin mi?</string> + <string name="deleteConfirmation">Bu kişi silinecek.</string> + <string name="copy_done">Kişi başarıyla kopyalandı</string> + <string name="copy_failure">Kişi kopyalanamadı</string> + <string name="card_no_space">Kişi kopyalanamadı, SIM kart dolu</string> + <string name="settings_contact_display_options_description">Kişilerinizin nasıl görüntüleneceğini ve sıralanacağını yapılandırın.</string> + <string name="ip_call_by_slot"><xliff:g id="subName">%s</xliff:g> ile IP araması</string> + <string name="no_ip_number">IP numarası yok</string> + <string name="no_ip_number_on_sim_card">SIM kartta IP numarası yok</string> + <string name="set_ip_number">IP numarasını ayarla</string> + <string name="ipcall_dialog_title">IP arama ayarları</string> + <string name="ipcall_dialog_edit_hint">Lütfen IP önekini girin</string> + <string name="import_contacts_from_all_cards">Tüm SIM kartlardan kişileri al</string> + <string name="select_path">Konumu seçin</string> + <string name="select_sim">SIM seç</string> +</resources> diff --git a/res/values-ug/cm_strings.xml b/res/values-ug/cm_strings.xml new file mode 100644 index 00000000..d989a42f --- /dev/null +++ b/res/values-ug/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">يەرلىك تاختا كومپيۇتېر ھېساباتى</string> + <string name="local_storage_account" product="default">يەرلىك تېلېفون ھېساباتى</string> + <string name="import_contacts_sim">ئالاقەداشلارنى SIM كارتىدىن ئەكىرەمدۇ؟</string> + <string name="manage_sim_contacts">SIM كارتىدىكى ئالاقەداشلارنى باشقۇرۇش</string> + <string name="export_to_sim">SIM كارتىغا چىقار</string> + <string name="fail_reason_import_vcard">بىر كىرگۈزۈش چىقىرىش خاتالىقى سەۋەبىدىن <xliff:g id="name">%s</xliff:g> نى ئەكىرەلمىدى</string> + <string name="contact_share_failed_toast">ھەمبەھىرلەيدىغان ئالاقەداش <xliff:g id="count">%d</xliff:g> دىن ئاشمايدۇ</string> + <string name="label_groups">گۇرۇپپا</string> + <string name="exporting">چىقىرىۋاتىدۇ\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g>/<xliff:g id="total_number">%2$s</xliff:g> ھۆججەت</string> + <string name="export_failed">چىقىرالمىدى</string> + <string name="sim_card_full">SIM كارتا لىق</string> + <string name="export_finished">چىقىرىش تامام</string> + <string name="tag_too_long">ئالاقەداش ئىسمى بەك ئۇزۇن</string> + <string name="sim_contacts_not_loaded">SIM كارتىدىكى ئالاقەداشلارنى يۈكلىيەلمىدى</string> + <plurals name="export_cancelled"> + <item quantity="other">چىقىرىشتىن ۋاز كەچتى، %d تۈر چىقىرىلدى</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g>نىڭ تېلېفون نومۇرى ياكى تورخەت ئادرېسى يوق</string> + <string name="import_from_sim_select">ئەكىرىدىغان كارتىنى تاللاڭ</string> + <string name="no_sdcard_title" product="nosdcard">ساقلىغۇچنى ئىشلەتكىلى بولمايدۇ</string> + <string name="no_sdcard_title" product="default">SD كارتا يوق</string> + <string name="deleteConfirmation_title">ئالاقەداش ئۆچۈرەمدۇ؟</string> + <string name="deleteConfirmation">بۇ ئالاقەداش ئۆچۈرۈلىدۇ.</string> + <string name="copy_done">ئالاقەداش مۇۋەپپەقىيەتلىك كۆچۈرۈلدى</string> + <string name="copy_failure">ئالاقەداشنى كۆچۈرەلمىدى</string> + <string name="card_no_space">ئالاقەداشنى كۆچۈرەلمىدى، SIM كارتا لىق</string> + <string name="settings_contact_display_options_description">ئالاقەداشلىرىڭىزنى كۆرسىتىش ۋە تەرتىپلەش ئۇسۇلىنى سەپلەڭ.</string> + <string name="ip_call_by_slot"><xliff:g id="subName">%s</xliff:g> بىلەن IP چاقىرىش</string> + <string name="no_ip_number">IP نومۇر يوق</string> + <string name="no_ip_number_on_sim_card">SIM كارتىدا IP نومۇر يوق</string> + <string name="set_ip_number">IP نومۇر تەڭشەك</string> + <string name="ipcall_dialog_title">IP چاقىرىش تەڭشەكلىرى</string> + <string name="ipcall_dialog_edit_hint">IP ئالدى قوشۇلغۇچىسىنى كىرگۈزۈڭ</string> + <string name="import_contacts_from_all_cards">ھەممە SIM كارتىدىن ئالاقەداشلارنى ئەكىر</string> + <string name="select_path">يول تاللاڭ</string> + <string name="select_sim">SIM كارتا تاللا</string> +</resources> diff --git a/res/values-ug/strings.xml b/res/values-ug/strings.xml new file mode 100644 index 00000000..d25a8bca --- /dev/null +++ b/res/values-ug/strings.xml @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + ~ Copyright (C) 2012 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License + --> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="toast_text_copied">تېكىست كۆچۈرۈلدى</string> + <string name="call_custom"><xliff:g id="CUSTOM">%s</xliff:g> نى چاقىر</string> + <string name="call_home">ئۆي تېلېفوننى چاقىر</string> + <string name="call_mobile">تېلېفوننى چاقىر</string> + <string name="call_work">خىزمەت تېلېفوننى چاقىر</string> + <string name="call_fax_work">خىزمەت فاكىسنى چاقىر</string> + <string name="call_fax_home">ئۆي فاكىسنى چاقىر</string> + <string name="call_pager">چاقىرغۇنى چاقىر</string> + <string name="call_other">چاقىر</string> + <string name="call_callback">قايتا چاقىرىلغان نومۇرنى چاقىر</string> + <string name="call_car">ماشىنا تېلېفونىنى چاقىر</string> + <string name="call_company_main">شىركەت باش ئاپپاراتىنى چاقىر</string> + <string name="call_isdn">ISDN چاقىر</string> + <string name="call_main">باش ئاپپاراتنى چاقىر</string> + <string name="call_other_fax">فاكىسنى چاقىر</string> + <string name="call_radio">رادىيو چاقىر</string> + <string name="call_telex">تېلېگرامما چاقىر</string> + <string name="call_tty_tdd">TTY/TDD چاقىر</string> + <string name="call_work_mobile">خىزمەت تېلېفوننى چاقىر</string> + <string name="call_work_pager">خىزمەت چاقىرغۇنى چاقىر</string> + <string name="call_assistant"><xliff:g id="ASSISTANT">%s</xliff:g> نى چاقىر</string> + <string name="call_mms">MMS چاقىر</string> + <string name="sms_custom"><xliff:g id="CUSTOM">%s</xliff:g> غا قىسقا ئۇچۇر يوللا</string> + <string name="sms_home">ئۆي تېلېفونغا ئۇچۇر يوللا</string> + <string name="sms_mobile">تېلېفونغا ئۇچۇر يوللا</string> + <string name="sms_work">خىزمەت تېلېفونغا ئۇچۇر يوللا</string> + <string name="sms_fax_work">خىزمەت فاكىسقا ئۇچۇر يوللا</string> + <string name="sms_fax_home">ئۆي فاكىسقا ئۇچۇر يوللا</string> + <string name="sms_pager">چاقىرغۇغا ئۇچۇر يوللا</string> + <string name="sms_other">قىسقا ئۇچۇر</string> + <string name="sms_callback">قايتا چاقىرىلغان نومۇرغا ئۇچۇر يوللا</string> + <string name="sms_car">ماشىنا تېلېفونىغا ئۇچۇر يوللا</string> + <string name="sms_company_main">شىركەت باش ئاپپاراتىغا ئۇچۇر يوللا</string> + <string name="sms_isdn">ISDN گە ئۇچۇر يوللا</string> + <string name="sms_main">باش ئاپپاراتقا ئۇچۇر يوللا</string> + <string name="sms_other_fax">فاكىسقا قىسقا ئۇچۇر يوللا</string> + <string name="sms_radio">رادىيوغا ئۇچۇر يوللا</string> + <string name="sms_telex">تېلېگراممىغا ئۇچۇر يوللا</string> + <string name="sms_tty_tdd">TTY/TDD غا ئۇچۇر يوللا</string> + <string name="sms_work_mobile">خىزمەت تېلېفونغا ئۇچۇر يوللا</string> + <string name="sms_work_pager">خىزمەت چاقىرغۇغا ئۇچۇر يوللا</string> + <string name="sms_assistant"><xliff:g id="ASSISTANT">%s</xliff:g> غا قىسقا ئۇچۇر يوللا</string> + <string name="sms_mms">MMS كە ئۇچۇر يوللا</string> + <string name="clearFrequentsConfirmation_title">دائىملىق ئالاقەداشلارنى تازىلامدۇ؟</string> + <string name="clearFrequentsConfirmation">بۇ مەشغۇلات ئالاقەداشلار ۋە نومۇر بۇرايدىغان ئەپتىكى دائىملىق ئالاقەداشلار تىزىمىنى تازىلايدۇ ھەمدە ئېلخەت ئەپتىن مەجبۇرىي ھالدا دائىملىق ئالاقەداشلىرىڭىزنىڭ ئادرېسىغا قايتىدىن ئېرىشىدۇ.</string> + <string name="clearFrequentsProgress_title">دائىملىق ئالاقەداشلارنى تازىلاۋاتىدۇ…</string> + <string name="status_available">ئىشلىتىلىشچان</string> + <string name="status_away">ئايرىلدى</string> + <string name="status_busy">ئالدىراش</string> + <string name="contactsList">ئالاقەداشلار</string> + <string name="local_invisible_directory">باشقا</string> + <string name="directory_search_label">مۇندەرىجە</string> + <string name="local_search_label">ھەممە ئالاقەداشلار</string> + <string name="user_profile_contacts_list_header" msgid="9154761216179882405">مەن</string> + <string name="search_results_searching">ئىزدەۋاتىدۇ…</string> + <string name="foundTooManyContacts"><xliff:g id="COUNT">%d</xliff:g> دىن كۆپ تاپتى.</string> + <string name="listFoundAllContactsZero">ئالاقەداش يوق</string> + <plurals name="searchFoundContacts"> + <item quantity="other">1 نى تاپتى</item> + </plurals> + <string name="description_quick_contact_for"><xliff:g id="NAME">%1$s</xliff:g> نىڭ تېز ئالاقەداشلىرى</string> + <string name="missing_name">(ئاتسىز)</string> + <string name="favoritesFrequentCalled">دائىملىق چاقىرىلىش</string> + <string name="favoritesFrequentContacted">دائىملىق ئالاقەداشلار</string> + <string name="description_view_contact_detail" msgid="2795575601596468581">ئالاقەداشنى كۆرسەت</string> + <string name="list_filter_phones">تېلېفون نومۇرى بار ھەممە ئالاقەداشلار</string> + <string name="view_updates_from_group">يېڭىلانمىلارنى كۆرسەت</string> + <string name="account_phone" product="tablet">تاختا كومپيۇتېرلا، قەدەمداشلانمىغان</string> + <string name="account_phone" product="default">تېلېفوندىلا، قەدەمداشلانمىغان</string> + <string name="nameLabelsGroup">ئاتى</string> + <string name="nicknameLabelsGroup">تەخەللۇس</string> + <string name="full_name">ئاتى</string> + <string name="name_prefix">ئات ئالدى قوشۇلغۇچىسى</string> + <string name="name_middle">ئوتتۇرا ئاتى</string> + <string name="name_suffix">ئات ئارقا قوشۇلغۇچىسى</string> + <string name="name_phonetic">تاۋۇشلۇق ئات</string> + <string name="name_phonetic_middle">تاۋۇشلۇق ئوتتۇرا ئات</string> + <string name="phoneLabelsGroup">تېلېفون</string> + <string name="emailLabelsGroup">ئېلخەت</string> + <string name="postalLabelsGroup">ئادرېس</string> + <string name="imLabelsGroup">پەيتلىك ئۇچۇر</string> + <string name="organizationLabelsGroup">تەشكىل</string> + <string name="relationLabelsGroup">مۇناسىۋەت</string> + <string name="eventLabelsGroup">پائالىيەتلەر</string> + <string name="sms">تېكىست ئۇچۇر</string> + <string name="postal_address">ئادرېس</string> + <string name="ghostData_company">شىركەت</string> + <string name="ghostData_title">ماۋزۇ</string> + <string name="label_notes">ئىزاھاتلار</string> + <string name="websiteLabelsGroup">تور بېكەت</string> + <string name="groupsLabel">گۇرۇپپا</string> + <string name="email_home">ئۆيگە ئېلخەت يوللا</string> + <string name="email_mobile">تېلېفونغا ئېلخەت يوللا</string> + <string name="email_work">خىزمەت تېلېفونغا ئېلخەت يوللا</string> + <string name="email_other">ئېلخەت</string> + <string name="email_custom"><xliff:g id="CUSTOM">%s</xliff:g> غا ئېلخەت يوللا</string> + <string name="email">ئېلخەت</string> + <string name="postal_street">كوچا</string> + <string name="postal_pobox">خەت ساندۇق</string> + <string name="postal_neighborhood">قوشنا</string> + <string name="postal_city">شەھەر</string> + <string name="postal_region">دۆلەت</string> + <string name="postal_postcode">پوچتا نومۇر</string> + <string name="postal_country">دۆلەت</string> + <string name="map_home">ئۆي ئادرېسىنى كۆرسەت</string> + <string name="map_work">خىزمەت ئادرېسىنى كۆرسەت</string> + <string name="map_other">ئادرېسنى كۆرسەت</string> + <string name="map_custom"><xliff:g id="CUSTOM">%s</xliff:g> ئادرېسنى كۆرسەت</string> + <string name="chat_aim">AIM دا مۇڭداش</string> + <string name="chat_msn">Windows Live دا مۇڭداش</string> + <string name="chat_yahoo">Yahoo دا مۇڭداش</string> + <string name="chat_skype">Skype دا مۇڭداش</string> + <string name="chat_qq">QQ دا مۇڭداش</string> + <string name="chat_gtalk">Google Talk تا مۇڭداش</string> + <string name="chat_icq">ICQ دا مۇڭداش</string> + <string name="chat_jabber">Jabber دا مۇڭداش</string> + <string name="chat">مۇڭداش</string> + <string name="description_minus_button">ئۆچۈر</string> + <string name="expand_collapse_name_fields_description">ئىسىم سۆز بۆلىكىنى ياي ياكى قاتلا</string> + <string name="list_filter_all_accounts">ھەممە ئالاقەداشلار</string> + <string name="list_filter_all_starred">يۇلتۇزلۇق</string> + <string name="list_filter_customize">ئىختىيارىي</string> + <string name="list_filter_single">ئالاقەداش</string> + <string name="display_ungrouped">بارلىق باشقا ئالاقەداشلار</string> + <string name="display_all_contacts">ھەممە ئالاقەداشلار</string> + <string name="menu_sync_remove">قەدەمداش گۇرۇپپىنى چىقىرىۋەت</string> + <string name="dialog_sync_add">قەدەمداش گۇرۇپپا قوش</string> + <string name="display_more_groups">تېخىمۇ كۆپ گۇرۇپپا…</string> + <string name="display_warn_remove_ungrouped">ئەگەر قەدەمداشتىن \"<xliff:g id="GROUP">%s</xliff:g>\" گۇرۇپپا چىقىرىۋېتىلسە ئۇنداقتا گۇرۇپپىغا ئايرىلمىغان باشقا ھەممە ئالاقەداشلارمۇ بىللە چىقىرىۋېتىلىدۇ.</string> + <string name="savingDisplayGroups">كۆرسىتىش تاللانمىسى ساقلاۋاتىدۇ…</string> + <string name="menu_done">تامام</string> + <string name="menu_doNotSave">ۋاز كەچ</string> + <string name="listAllContactsInAccount"><xliff:g id="NAME">%s</xliff:g> دىكى ئالاقەداشلار</string> + <string name="listCustomView">ئۆزلەشتۈرگەن كۆرۈنۈشتىكى ئالاقەداشلار</string> + <string name="listSingleContact">يەككە ئالاقەداش</string> + <string name="dialog_new_contact_account">ھېساباتقا ئالاقەداش قۇر</string> + <string name="import_from_sim">SIM كارتىدىن ئەكىر</string> + <string name="import_from_sdcard" product="default">ساقلىغۇچتىن ئەكىر</string> + <string name="cancel_import_confirmation_message"><xliff:g id="FILENAME">%S</xliff:g> ئەكىرىشتىن ۋاز كېچەمسىز؟</string> + <string name="cancel_export_confirmation_message"><xliff:g id="FILENAME">%S</xliff:g> چىقىرىشتىن ۋاز كېچەمسىز؟</string> + <string name="cancel_vcard_import_or_export_failed">vCard ئەكىر/چىقاردىن ۋاز كېچەلمەيدۇ</string> + <string name="fail_reason_unknown">يوچۇن خاتالىق.</string> + <string name="fail_reason_could_not_open_file"><xliff:g id="FILE_NAME">%s</xliff:g> ئاچالمايدۇ: <xliff:g id="EXACT_REASON">%s</xliff:g>.</string> + <string name="fail_reason_could_not_initialize_exporter">چىقارغۇچنى قوزغىتالمايدۇ: <xliff:g id="EXACT_REASON">%s</xliff:g>.</string> + <string name="fail_reason_no_exportable_contact">چىقىرىشقا بولىدىغان ئالاقەداش يوق.</string> + <string name="fail_reason_error_occurred_during_export">چىقىرىۋاتقاندا خاتالىق كۆرۈلدى: <xliff:g id="EXACT_REASON">%s</xliff:g>.</string> + <string name="fail_reason_too_long_filename">\"لازىملىق ھۆججەت ئاتى بەك ئۇزۇن (\"%s\").\"<xliff:g id="FILENAME"/></string> + <string name="fail_reason_too_many_vcard" product="nosdcard">ساقلىغۇچتا vCard ھۆججىتى بەك كۆپ.</string> + <string name="fail_reason_too_many_vcard" product="default">SD كارتىدا vCard ھۆججىتى بەك كۆپ.</string> + <string name="fail_reason_io_error">I/O خاتالىقى</string> + <string name="fail_reason_low_memory_during_import">ئەسلەك بوشلۇقى يېتىشمىدى. ھۆججەت بەك چوڭ بولۇشى مۇمكىن.</string> + <string name="fail_reason_vcard_parse_error"> ئويلاشمىغان سەۋەپ تۈپەيلىدىن vCard نى يېشەلمىدى</string> + <string name="fail_reason_not_supported">بۇ پىچىمنى قوللىمايدۇ.</string> + <string name="fail_reason_failed_to_collect_vcard_meta_info">بېرىلگەن vCard ھۆججەت(لەر)نىڭ مېتا سانلىق مەلۇماتىنى توپلىيالمىدى.</string> + <string name="fail_reason_failed_to_read_files">بىر ياكى بىر قانچە ھۆججەتنى ئەكىرەلمىدى (%s).</string> + <string name="exporting_vcard_finished_title"><xliff:g id="FILENAME">%s</xliff:g> چىقىرىش تاماملاندى.</string> + <string name="exporting_vcard_canceled_title"><xliff:g id="FILENAME">%s</xliff:g> نى چىقىرىشتىن ۋاز كەچتى</string> + <string name="exporting_contact_list_title">ئالاقەداش سانلىق مەلۇماتلىرىنى چىقىرىۋاتىدۇ</string> + <string name="exporting_contact_list_message">ئالاقەداش سانلىق مەلۇماتىڭىز ھۆججەتكە چىقىرىلىدۇ: <xliff:g id="FILE_NAME">%s</xliff:g>.</string> + <string name="composer_failed_to_get_database_infomation">ساندان ئۇچۇرىغا ئېرىشەلمەيدۇ.</string> + <string name="composer_has_no_exportable_contact" product="tablet">چىقىرىدىغان ئالاقەداشلار يوق. ئەگەر تاختا كومپيۇتېرىڭىزدا ئالاقەداشلارىڭىز بولسا ئۇنداقتا مەلۇم سانلىق مەلۇمات تەمىنلەش پىروگراممىسى تېلېفونىڭىزدىن ھەر قانداق ئالاقەداش چىقىرىشنى چەكلىگەن بولۇشى مۇمكىن.</string> + <string name="composer_has_no_exportable_contact" product="default">چىقىرىدىغان ئالاقەداشلار يوق. ئەگەر تېلېفونىڭىزدا ئالاقەداشلارىڭىز بولسا ئۇنداقتا مەلۇم سانلىق مەلۇمات تەمىنلەش پىروگراممىسى تېلېفونىڭىزدىن ھەر قانداق ئالاقەداش چىقىرىشنى چەكلىگەن بولۇشى مۇمكىن.</string> + <string name="composer_not_initialized">vCard ياساش پىروگراممىسى توغرا قوزغىتالمىدى.</string> + <string name="exporting_contact_failed_title">چىقىرالمايدۇ</string> + <string name="exporting_contact_failed_message">ئالاقەداش سانلىق مەلۇماتىنى چىقىرالمىدى.\"\n\"سەۋەبى: <xliff:g id="FAIL_REASON">%s</xliff:g></string> + <string name="no_sdcard_message" product="nosdcard">ھېچقانداق ساقلىغۇچ تېپىلمىدى.</string> + <string name="no_sdcard_message" product="default">SD كارتا تېپىلمىدى.</string> + <string name="confirm_export_message">ئالاقەداش تىزىمىڭىز ھۆججەتكە چىقىرىلىدۇ: <xliff:g id="VCARD_FILENAME">%s</xliff:g>.</string> + <string name="importing_vcard_description"> <xliff:g id="NAME">%s</xliff:g>ئەكىرىۋاتىدۇ</string> + <string name="reading_vcard_failed_title">vCard سانلىق مەلۇماتىنى ئوقۇيالمايدۇ</string> + <string name="reading_vcard_canceled_title">vCard سانلىق مەلۇماتىنى ئوقۇشتىن ۋاز كەچتى</string> + <string name="importing_vcard_finished_title">vCard <xliff:g id="FILENAME">%s</xliff:g> نى ئېلىپ كىرىش تاماملاندى</string> + <string name="importing_vcard_canceled_title"><xliff:g id="FILENAME">%s</xliff:g> ئېلىپ كىرىشتىن ۋاز كەچتى</string> + <string name="vcard_import_will_start_message"><xliff:g id="FILENAME">%s</xliff:g> نى تېزلا ئېلىپ كىرىدۇ.</string> + <string name="vcard_import_will_start_message_with_default_name">بۇ ھۆججەتنى تېزلا ئېلىپ كىرىدۇ.</string> + <string name="vcard_import_request_rejected_message">vCard ئېلىپ كىرىش ئىلتىماسى رەت قىلىندى. سەل تۇرۇپ قايتا سىناڭ.</string> + <string name="vcard_export_will_start_message"><xliff:g id="FILENAME">%s</xliff:g> نى تېزلا چىقىرىدۇ.</string> + <string name="vcard_export_request_rejected_message">vCard چىقىرىش ئىلتىماسى رەت قىلىندى. سەل تۇرۇپ قايتا سىناڭ.</string> + <string name="vcard_unknown_filename">ئالاقەداش</string> + <string name="caching_vcard_message">vCard نى يەرلىك ۋاقىتلىق ساقلىغۇچقا غەملەۋاتىدۇ. ناھايىتى تېزلا ھەقىقىي ئەكىرىشنى باشلايدۇ.</string> + <string name="percentage"><xliff:g id="PERCENTAGE">%s</xliff:g><xliff:g id="PERCENTSIGN">%%</xliff:g></string> + <string name="vcard_import_failed">vCard نى ئەكىرەلمەيدۇ</string> + <string name="import_failure_no_vcard_file" product="nosdcard">بۇ ساقلىغۇچتىن vCard ھۆججىتىنى تاپالمىدى</string> + <string name="import_failure_no_vcard_file" product="default">SD كارتىدىن vCard ھۆججىتىنى تاپالمىدى.</string> + <string name="nfc_vcard_file_name">NFC ئارقىلىق ئالاقەداش قوبۇللىدى</string> + <string name="confirm_export_title">ئالاقەداشلارنى چىقار؟</string> + <string name="select_vcard_title">vCard ھۆججەت تاللاڭ</string> + <string name="import_one_vcard_string">بىر vCard ھۆججەت ئەكىر</string> + <string name="import_multiple_vcard_string">كۆپ vCard ھۆججەت ئەكىر</string> + <string name="import_all_vcard_string">ھەممە vCard ھۆججەتنى ئەكىر</string> + <string name="searching_vcard_message" product="nosdcard">ساقلىغۇچتىن vCard سانلىق مەلۇماتىنى ئىزدەۋاتىدۇ…</string> + <string name="searching_vcard_message" product="default">SD كارتىدىن vCard سانلىق مەلۇماتىنى ئىزدەۋاتىدۇ</string> + <string name="caching_vcard_title">غەملەۋاتىدۇ</string> + <string name="scanning_sdcard_failed_message" product="nosdcard">ساقلىغۇچنى تەكشۈرەلمىدى. (سەۋەبى: <xliff:g id="FAIL_REASON">%s</xliff:g>)</string> + <string name="scanning_sdcard_failed_message" product="default">SD كارتا تەكشۈرەلمىدى(سەۋەبى: <xliff:g id="FAIL_REASON">%s</xliff:g>)</string> + <string name="progress_notifier_message">ئەكىرىۋاتىدۇ <xliff:g id="CURRENT_NUMBER">%s</xliff:g>/<xliff:g id="TOTAL_NUMBER">%s</xliff:g>: <xliff:g id="NAME">%s</xliff:g></string> + <string name="export_to_sdcard" product="default">ساقلىغۇچقا چىقار</string> + <string name="share_visible_contacts">كۆرۈنىدىغان ئالاقەداش ھەمبەھىر</string> + <string name="dialog_import_export">ئالاقەداش ئەكىر/چىقار</string> + <string name="dialog_import">ئالاقەداش ئەكىر</string> + <string name="share_error">بۇ ئالاقەداشنى ھەمبەھىرلىگىلى بولمايدۇ.</string> + <string name="menu_search">ئىزدە</string> + <string name="menu_contacts_filter">كۆرسىتىدىغان ئالاقەداشلار</string> + <string name="activity_title_contacts_filter">كۆرسىتىدىغان ئالاقەداشلار</string> + <string name="custom_list_filter">ئۆزلەشتۈرگەن كۆرۈنۈش بەلگىلەش</string> + <string name="hint_findContacts">ئالاقەداش ئىزدە</string> + <string name="contactsFavoritesLabel">يىغقۇچ</string> + <string name="listTotalAllContactsZero">ئالاقەداشلار يوق.</string> + <string name="listTotalAllContactsZeroCustom">كۆرسىتىدىغان ئالاقەداش يوق.</string> + <string name="listTotalAllContactsZeroStarred">ياقتۇرىدىغانلار يوق.</string> + <string name="listTotalAllContactsZeroGroup"><xliff:g id="NAME">%s</xliff:g> دا ئالاقەداش يوق</string> + <string name="menu_clear_frequents">دائىملىق ئالاقەداشلارنى تازىلا</string> + <string name="menu_accounts">ھېساباتلار</string> + <string name="menu_import_export">ئەكىر/چىقار</string> + <string name="contact_status_update_attribution">via <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string> + <string name="contact_status_update_attribution_with_date"><xliff:g id="source" example="Google Talk">%2$s</xliff:g> ئارقىلىق <xliff:g id="date" example="3 hours ago">%1$s</xliff:g></string> +</resources> diff --git a/res/values-uk/cm_strings.xml b/res/values-uk/cm_strings.xml new file mode 100644 index 00000000..72c7e8fa --- /dev/null +++ b/res/values-uk/cm_strings.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">Локальний обліковий запис планшета</string> + <string name="local_storage_account" product="default">Локальний обліковий запис телефону</string> + <string name="import_contacts_sim">Імпорт контактів з SIM-карти?</string> + <string name="manage_sim_contacts">Керування контактами SIM-карти</string> + <string name="export_to_sim">Експорт до SIM-картки</string> + <string name="fail_reason_import_vcard">Не вдалося імпортувати \'<xliff:g id="name">%s</xliff:g>\' через помилку вводу/виводу</string> + <string name="contact_share_failed_toast">Можливо відправити не більш ніж <xliff:g id="count">%d</xliff:g> контактів</string> + <string name="label_groups">Група</string> + <string name="exporting">Експорт\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> із <xliff:g id="total_number">%2$s</xliff:g> файлів</string> + <string name="export_failed">Помилка експорту</string> + <string name="sim_card_full">SIM-карта заповнена</string> + <string name="export_finished">Експорт завершено</string> + <string name="tag_too_long">Ім`я контакта занадто довге</string> + <string name="sim_contacts_not_loaded">Не вдається завантажити контакти SIM-карти</string> + <plurals name="export_cancelled"> + <item quantity="one">Експорт було скасовано, експортовано %d елемент</item> + <item quantity="few">Експорт було скасовано, експортовано %d елемента</item> + <item quantity="other">Експорт було скасовано, експортовано %d елементів</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> не мае телефонного номеру чи електронної пошти</string> + <string name="import_from_sim_select">Виберіть карту для імпорту</string> + <string name="no_sdcard_title" product="nosdcard">Носій недоступний</string> + <string name="no_sdcard_title" product="default">Немає SD-карти</string> + <string name="deleteConfirmation_title">Видалити контакт?</string> + <string name="deleteConfirmation">Цей контакт буде видалено.</string> + <string name="copy_done">Контакт був скопійован успішно</string> + <string name="copy_failure">Не вдалося скопіювати контакт</string> + <string name="card_no_space">Копіювання контактів не вдалося, SIM-карта заповнена</string> + <string name="settings_contact_display_options_description">Налаштувати відображання та сортування контактів.</string> + <string name="ip_call_by_slot">IP-виклик за допомогою <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">Немає IP номера</string> + <string name="no_ip_number_on_sim_card">Немає IP номера на SIM-картці</string> + <string name="set_ip_number">Задати IP-номер</string> + <string name="ipcall_dialog_title">Налаштування IP-телефонії</string> + <string name="ipcall_dialog_edit_hint">Будь ласка, введіть префікс IP</string> + <string name="import_contacts_from_all_cards">Імпорт контактів із усіх SIM-карт</string> + <string name="select_path">Оберіть шлях</string> + <string name="select_sim">Виберіть SIM-картку</string> +</resources> diff --git a/res/values-zh-rCN/cm_strings.xml b/res/values-zh-rCN/cm_strings.xml new file mode 100644 index 00000000..3134001a --- /dev/null +++ b/res/values-zh-rCN/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">本地平板电脑帐户</string> + <string name="local_storage_account" product="default">本地手机帐户</string> + <string name="import_contacts_sim">从 SIM 卡导入联系人吗?</string> + <string name="manage_sim_contacts">管理 SIM 卡联系人</string> + <string name="export_to_sim">导出到 SIM 卡</string> + <string name="fail_reason_import_vcard">“<xliff:g id="name">%s</xliff:g>” 由于读写错误无法导入</string> + <string name="contact_share_failed_toast">可以共享不超过 <xliff:g id="count">%d</xliff:g> 个联系人</string> + <string name="label_groups">群组</string> + <string name="exporting">正在导出\u2026</string> + <string name="reading_vcard_files"><xliff:g id="current_number">%2$s</xliff:g> 个中的 <xliff:g id="total_number">%1$s</xliff:g> 个文件</string> + <string name="export_failed">导出失败</string> + <string name="sim_card_full">SIM 卡空间已满</string> + <string name="export_finished">导出完成</string> + <string name="tag_too_long">联系人名称过长</string> + <string name="sim_contacts_not_loaded">无法加载 SIM 卡联系人</string> + <plurals name="export_cancelled"> + <item quantity="other">导出已取消,%d 个项目已被导出</item> + </plurals> + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> 没有电话号码或电子邮件地址</string> + <string name="import_from_sim_select">选择要导入的卡</string> + <string name="no_sdcard_title" product="nosdcard">存储不可用</string> + <string name="no_sdcard_title" product="default">无 SD 卡</string> + <string name="deleteConfirmation_title">删除联系人?</string> + <string name="deleteConfirmation">此联系人将被删除。</string> + <string name="copy_done">已成功复制联系人</string> + <string name="copy_failure">复制联系人失败</string> + <string name="card_no_space">复制联系人失败,SIM 卡已满</string> + <string name="settings_contact_display_options_description">设置您的联系人的显示和排序方式。</string> + <string name="ip_call_by_slot">IP 呼叫由 <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">没有 IP 号码</string> + <string name="no_ip_number_on_sim_card">在 SIM 卡上没有 IP 号码</string> + <string name="set_ip_number">设置 IP 号码</string> + <string name="ipcall_dialog_title">IP 呼叫设置</string> + <string name="ipcall_dialog_edit_hint">请输入 IP 前缀</string> + <string name="import_contacts_from_all_cards">从所有 SIM 卡导入联系人</string> + <string name="select_path">选择路径</string> + <string name="select_sim">选择 SIM 卡</string> +</resources> diff --git a/res/values-zh-rHK/cm_strings.xml b/res/values-zh-rHK/cm_strings.xml new file mode 100644 index 00000000..3eaca935 --- /dev/null +++ b/res/values-zh-rHK/cm_strings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">本機平板電腦帳戶</string> + <string name="local_storage_account" product="default">本機電話帳戶</string> + <string name="export_to_sim">匯出至 SIM 咭</string> + <string name="select_sim">選擇 SIM 咭</string> +</resources> diff --git a/res/values-zh-rTW/cm_strings.xml b/res/values-zh-rTW/cm_strings.xml new file mode 100644 index 00000000..4c307079 --- /dev/null +++ b/res/values-zh-rTW/cm_strings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.com--> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="local_storage_account" product="tablet">本機平板電腦帳戶</string> + <string name="local_storage_account" product="default">本機手機帳戶</string> + <string name="import_contacts_sim">從 SIM 卡匯入聯絡人嗎?</string> + <string name="manage_sim_contacts">管理 SIM 卡聯絡人</string> + <string name="export_to_sim">匯出至 SIM 卡</string> + <string name="fail_reason_import_vcard">由於 I/O 錯誤導致無法匯入「<xliff:g id="name">%s</xliff:g>」</string> + <string name="contact_share_failed_toast">無法分享超過 <xliff:g id="count">%d</xliff:g> 個聯絡人</string> + <string name="label_groups">群組</string> + <string name="exporting">正在匯出\u2026</string> + <string name="reading_vcard_files"><xliff:g id="total_number">%2$s</xliff:g> 個檔案中的 <xliff:g id="current_number">%1$s</xliff:g> 個</string> + <string name="export_failed">匯出失敗</string> + <string name="sim_card_full">SIM 卡已滿</string> + <string name="export_finished">已完成匯出</string> + <string name="tag_too_long">聯絡人名稱過長</string> + <string name="sim_contacts_not_loaded">無法載入 SIM 卡聯絡人</string> + <plurals name="export_cancelled"> + <item quantity="other">已取消匯出,已匯出 %d 個項目</item> + </plurals> + <string name="export_no_phone_or_email">「<xliff:g id="name">%s</xliff:g>」沒有電話號碼或電子郵件地址</string> + <string name="import_from_sim_select">選取要匯入的 SIM 卡</string> + <string name="no_sdcard_title" product="nosdcard">無法使用儲存空間</string> + <string name="no_sdcard_title" product="default">沒有 SD 卡</string> + <string name="deleteConfirmation_title">刪除聯絡人?</string> + <string name="deleteConfirmation">此聯絡人將被刪除。</string> + <string name="copy_done">已成功複製聯絡人</string> + <string name="copy_failure">複製聯絡人失敗</string> + <string name="card_no_space">複製聯絡人失敗,SIM 卡已滿</string> + <string name="settings_contact_display_options_description">配置您的聯絡人顯示及分類的方式。</string> + <string name="ip_call_by_slot">來自「<xliff:g id="subName">%s</xliff:g>」的網路通話</string> + <string name="no_ip_number">無 IP 號碼</string> + <string name="no_ip_number_on_sim_card">SIM 卡上沒有 IP 號碼</string> + <string name="set_ip_number">設定 IP 號碼</string> + <string name="ipcall_dialog_title">IP 通話設定</string> + <string name="ipcall_dialog_edit_hint">請輸入 IP 地區號碼</string> + <string name="import_contacts_from_all_cards">從所有 SIM 卡匯入聯絡人</string> + <string name="select_path">選取路徑</string> + <string name="select_sim">選取 SIM 卡</string> +</resources> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 64397caf..921469ff 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -17,6 +17,7 @@ <resources> <declare-styleable name="Theme"> <attr name="android:textColorSecondary" /> + <attr name="android:colorPrimary" /> </declare-styleable> <declare-styleable name="ContactsDataKind"> @@ -62,6 +63,9 @@ <attr name="list_item_text_offset_top" format="dimension"/> <attr name="list_item_data_width_weight" format="integer"/> <attr name="list_item_label_width_weight" format="integer"/> + <attr name="list_item_quick_call_view_source" format="reference" /> + <attr name="list_item_quick_call_view_background" format="reference" /> + <attr name="list_item_quick_call_size" format="dimension" /> </declare-styleable> <declare-styleable name="ContactBrowser"> diff --git a/res/values/cm_colors.xml b/res/values/cm_colors.xml new file mode 100755 index 00000000..53e920ab --- /dev/null +++ b/res/values/cm_colors.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <color name="contact_tile_text_color">#ff202020</color> + <color name="frequent_contact_text_color">#ff000000</color> +</resources> diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml new file mode 100644 index 00000000..52958407 --- /dev/null +++ b/res/values/cm_strings.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Virtual local storage account name --> + <string name="local_storage_account" product="tablet">Local tablet account</string> + <string name="local_storage_account" product="default">Local phone account</string> + + <!-- CMCC --> + <string name="import_contacts_sim">Import contacts from SIM card?</string> + + <!-- CAF --> + <!-- Action string for managing SIM contacts --> + <string name="manage_sim_contacts">Manage SIM card contacts</string> + + <!-- Action that exports all contacts to SIM --> + <string name="export_to_sim">Export to SIM card</string> + + <!--The failed reason shown when importing a vCard file --> + <string name="fail_reason_import_vcard">\'<xliff:g id="name">%s</xliff:g>\' could not be imported due to an I/O error</string> + + <!-- Toast indicating that sharing too many contact has failed. [CHAR LIMIT=NONE] --> + <string name="contact_share_failed_toast">No more than <xliff:g id="count">%d</xliff:g> contacts can be shared</string> + + <string name="label_groups">Group</string> + <string name="exporting">Exporting\u2026</string> + + <!-- Message while reading multiple vCard files "(current number) of (total number) files" + The order of "current number" and "total number" cannot be changed --> + <string name="reading_vcard_files"><xliff:g id="current_number">%1$s</xliff:g> of <xliff:g id="total_number">%2$s</xliff:g> files</string> + + <string name="export_failed">Export failed</string> + <string name="sim_card_full">SIM card is full</string> + <string name="export_finished">Export finished</string> + <string name="tag_too_long">Contact name is too long</string> + <string name="sim_contacts_not_loaded">Unable to load SIM contacts</string> + + <plurals name="export_cancelled"> + <item quantity="one">Export was cancelled, %d item was exported</item> + <item quantity="other">Export was cancelled, %d items were exported</item> + </plurals> + + <string name="export_no_phone_or_email"><xliff:g id="name">%s</xliff:g> does not have a phone number or email address</string> + + <string name="import_from_sim_select">Choose card to import</string> + + <!-- Dialog title shown when (USB) storage does not exist [CHAR LIMIT=25] --> + <string name="no_sdcard_title" product="nosdcard">Storage unavailable</string> + <!-- Dialog title shown when SD Card does not exist --> + <string name="no_sdcard_title" product="default">No SD card</string> + + <!-- Confirmation dialog title after users selects to delete a contact. [CHAR LIMIT=25]--> + <string name="deleteConfirmation_title">Delete contact?</string> + + <!-- Confirmation dialog contents after users selects to delete a Writable contact. --> + <string name="deleteConfirmation">This contact will be deleted.</string> + + <string name="copy_done">Contact was copied successfully</string> + <string name="copy_failure">Copying the contact failed</string> + <string name="card_no_space">Copying the contact failed, SIM card is full</string> + + <!-- Detailed description of the preference section that allows users to configure how they + want their contacts to be displayed. [CHAR LIMIT=128] --> + <string name="settings_contact_display_options_description">Configure how your contacts are displayed and sorted.</string> + + <!-- Menu item used to initiate ip call --> + <string name="ip_call_by_slot">IP call via <xliff:g id="subName">%s</xliff:g></string> + <string name="no_ip_number">No IP number</string> + <string name="no_ip_number_on_sim_card">No IP number on SIM card</string> + <string name="set_ip_number">Set IP number</string> + <string name="ipcall_dialog_title">IP call settings</string> + <string name="ipcall_dialog_edit_hint">Please input the IP prefix</string> + + <string name="import_contacts_from_all_cards">Import contacts from all SIM cards</string> + <string name="select_path">Select path</string> + <string name="select_sim">Select SIM</string> + +</resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index 376fd3f0..8f5d5387 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -118,6 +118,8 @@ <color name="letter_tile_font_color">#ffffff</color> + <color name="text_highlight_color">#3B77E7</color> + <!-- Background color of action bars. Ensure this stays in sync with packages/Telephony actionbar_background_color. --> <color name="actionbar_background_color">#0fc6dc</color> diff --git a/res/values/donottranslate_config.xml b/res/values/donottranslate_config.xml index fe690ada..06c7f5d3 100644 --- a/res/values/donottranslate_config.xml +++ b/res/values/donottranslate_config.xml @@ -84,4 +84,12 @@ <!-- Flag indicating whether Contacts app is allowed to share contacts with devices outside --> <bool name="config_allow_share_visible_contacts">true</bool> + <!-- configuration for set CG option --> + <bool name="config_set_CG_option">false</bool> + + <!-- configuration for set search call logs in SmartDial --> + <bool name="config_smart_search">false</bool> + + <!-- configuration for set operator show in dialpad or calllog --> + <bool name="config_show_operator">false</bool> </resources> diff --git a/res/values/ids.xml b/res/values/ids.xml index 093901ba..0b7d3a2c 100644 --- a/res/values/ids.xml +++ b/res/values/ids.xml @@ -40,6 +40,8 @@ <item type="id" name="cliv_phoneticname_textview"/> <item type="id" name="cliv_label_textview"/> <item type="id" name="cliv_data_view"/> + <!-- For ContactDeletionInteraction --> + <item type="id" name="dialog_delete_contact_confirmation"/> <!-- For tag ids used by ContactPhotoManager to tag views with contact details --> <item type="id" name="tag_display_name"/> diff --git a/src/com/android/contacts/common/CallUtil.java b/src/com/android/contacts/common/CallUtil.java index 3a932abe..3d5f7eab 100644 --- a/src/com/android/contacts/common/CallUtil.java +++ b/src/com/android/contacts/common/CallUtil.java @@ -19,14 +19,18 @@ package com.android.contacts.common; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.os.SystemProperties; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telecom.VideoProfile; +import android.telephony.PhoneNumberUtils; import com.android.contacts.common.util.PhoneNumberHelper; import com.android.phone.common.PhoneConstants; +import java.util.List; + /** * Utilities related to calls. */ @@ -90,6 +94,27 @@ public class CallUtil { } /** + * get intent to start csvt. + */ + public static Intent getCSVTCallIntent(String number) { + Intent intent = new Intent("com.borqs.videocall.action.LaunchVideoCallScreen"); + intent.addCategory(Intent.CATEGORY_DEFAULT); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + intent.putExtra("IsCallOrAnswer", true); + intent.putExtra("LaunchMode", 1); + intent.putExtra("call_number_key", number); + return intent; + } + + /** + * if true, csvt is enabled. + */ + public static boolean isCSVTEnabled() { + boolean CSVTSupported = SystemProperties.getBoolean("persist.radio.csvt.enabled", false); + return CSVTSupported; + } + + /** * A variant of {@link #getCallIntent(String, String)} for starting a video call. */ public static Intent getVideoCallIntent(String number, String callOrigin) { @@ -143,6 +168,46 @@ public class CallUtil { /** * Return Uri with an appropriate scheme, accepting both SIP and usual phone call + * Checks whether two phone numbers resolve to the same phone. + */ + public static boolean phoneNumbersEqual(String number1, String number2) { + if (PhoneNumberUtils.isUriNumber(number1) || PhoneNumberUtils.isUriNumber(number2)) { + return sipAddressesEqual(number1, number2); + } else { + return PhoneNumberUtils.compare(number1, number2); + } + } + + private static boolean sipAddressesEqual(String number1, String number2) { + if (number1 == null || number2 == null) return number1 == number2; + + int index1 = number1.indexOf('@'); + final String userinfo1; + final String rest1; + if (index1 != -1) { + userinfo1 = number1.substring(0, index1); + rest1 = number1.substring(index1); + } else { + userinfo1 = number1; + rest1 = ""; + } + + int index2 = number2.indexOf('@'); + final String userinfo2; + final String rest2; + if (index2 != -1) { + userinfo2 = number2.substring(0, index2); + rest2 = number2.substring(index2); + } else { + userinfo2 = number2; + rest2 = ""; + } + + return userinfo1.equals(userinfo2) && rest1.equalsIgnoreCase(rest2); + } + + /** + * Return Uri with an appropriate scheme, accepting Voicemail, SIP, and usual phone call * numbers. */ public static Uri getCallUri(String number) { @@ -152,15 +217,24 @@ public class CallUtil { return Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null); } + private static boolean hasCapability(PhoneAccount phoneAccount, int capability) { + return (phoneAccount != null) && + ((phoneAccount.getCapabilities() & capability) == capability); + } + public static boolean isVideoEnabled(Context context) { TelecomManager telecommMgr = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); if (telecommMgr == null) { return false; } - - // TODO: Check telecommManager for value instead. - // return telecommMgr.isVideoEnabled(); + List<PhoneAccountHandle> phoneAccountHandles = telecommMgr.getCallCapablePhoneAccounts(); + for (PhoneAccountHandle handle : phoneAccountHandles) { + final PhoneAccount phoneAccount = telecommMgr.getPhoneAccount(handle); + if (hasCapability(phoneAccount, PhoneAccount.CAPABILITY_VIDEO_CALLING)) { + return true; + } + } return false; } } diff --git a/src/com/android/contacts/common/ContactPhotoManager.java b/src/com/android/contacts/common/ContactPhotoManager.java index 12faadb0..f700fd8a 100644 --- a/src/com/android/contacts/common/ContactPhotoManager.java +++ b/src/com/android/contacts/common/ContactPhotoManager.java @@ -16,6 +16,7 @@ package com.android.contacts.common; +import android.accounts.Account; import android.app.ActivityManager; import android.content.ComponentCallbacks2; import android.content.ContentResolver; @@ -113,19 +114,24 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { * draw a letter tile avatar based on the request parameters defined in the * {@link DefaultImageRequest}. */ - public static Drawable getDefaultAvatarDrawableForContact(Resources resources, boolean hires, + public static Drawable getDefaultAvatarDrawableForContact(Context context, boolean hires, DefaultImageRequest defaultImageRequest) { + return getDefaultAvatarDrawableForContact(context, hires, defaultImageRequest, null); + } + + public static Drawable getDefaultAvatarDrawableForContact(Context context, boolean hires, + DefaultImageRequest defaultImageRequest, Account account) { if (defaultImageRequest == null) { if (sDefaultLetterAvatar == null) { // Cache and return the letter tile drawable that is created by a null request, // so that it doesn't have to be recreated every time it is requested again. sDefaultLetterAvatar = LetterTileDefaultImageProvider.getDefaultImageForContact( - resources, null); + context, null, account); } return sDefaultLetterAvatar; } - return LetterTileDefaultImageProvider.getDefaultImageForContact(resources, - defaultImageRequest); + return LetterTileDefaultImageProvider.getDefaultImageForContact(context, + defaultImageRequest, account); } /** @@ -365,8 +371,8 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { * @param defaultImageRequest {@link DefaultImageRequest} object that specifies how a * default letter tile avatar should be drawn. */ - public abstract void applyDefaultImage(ImageView view, int extent, boolean darkTheme, - DefaultImageRequest defaultImageRequest); + public abstract void applyDefaultImage(ImageView view, Account account, + int extent, boolean darkTheme, DefaultImageRequest defaultImageRequest); } /** @@ -376,16 +382,17 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { */ private static class LetterTileDefaultImageProvider extends DefaultImageProvider { @Override - public void applyDefaultImage(ImageView view, int extent, boolean darkTheme, - DefaultImageRequest defaultImageRequest) { - final Drawable drawable = getDefaultImageForContact(view.getResources(), - defaultImageRequest); + public void applyDefaultImage(ImageView view, Account account, int extent, + boolean darkTheme, DefaultImageRequest defaultImageRequest) { + final Drawable drawable = getDefaultImageForContact(view.getContext(), + defaultImageRequest, account); view.setImageDrawable(drawable); } - public static Drawable getDefaultImageForContact(Resources resources, - DefaultImageRequest defaultImageRequest) { - final LetterTileDrawable drawable = new LetterTileDrawable(resources); + public static Drawable getDefaultImageForContact(Context context, + DefaultImageRequest defaultImageRequest, Account account) { + final LetterTileDrawable drawable = new LetterTileDrawable( + context, account); if (defaultImageRequest != null) { // If the contact identifier is null or empty, fallback to the // displayName. In that case, use {@code null} for the contact's @@ -410,8 +417,8 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { private static Drawable sDrawable; @Override - public void applyDefaultImage(ImageView view, int extent, boolean darkTheme, - DefaultImageRequest defaultImageRequest) { + public void applyDefaultImage(ImageView view, Account account, int extent, + boolean darkTheme, DefaultImageRequest defaultImageRequest) { if (sDrawable == null) { Context context = view.getContext(); sDrawable = new ColorDrawable(context.getResources().getColor( @@ -440,13 +447,15 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { return new ContactPhotoManagerImpl(context); } + public abstract void clear(); + /** * Load thumbnail image into the supplied image view. If the photo is already cached, * it is displayed immediately. Otherwise a request is sent to load the photo * from the database. */ - public abstract void loadThumbnail(ImageView view, long photoId, boolean darkTheme, - boolean isCircular, DefaultImageRequest defaultImageRequest, + public abstract void loadThumbnail(ImageView view, long photoId, Account account, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider); /** @@ -454,10 +463,23 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { * DefaultImageProvider)} using the {@link DefaultImageProvider} {@link #DEFAULT_AVATAR}. */ public final void loadThumbnail(ImageView view, long photoId, boolean darkTheme, - boolean isCircular, DefaultImageRequest defaultImageRequest) { - loadThumbnail(view, photoId, darkTheme, isCircular, defaultImageRequest, DEFAULT_AVATAR); + boolean isCircular, DefaultImageRequest defaultImageRequest) { + loadThumbnail(view, photoId, null, darkTheme, isCircular, + defaultImageRequest, DEFAULT_AVATAR); } + public final void loadThumbnail(ImageView view, long photoId, Account account, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest) { + loadThumbnail(view, photoId, account, darkTheme, isCircular, + defaultImageRequest, DEFAULT_AVATAR); + } + + public final void loadThumbnail(ImageView view, long photoId, boolean darkTheme, + boolean isCircular, DefaultImageRequest defaultImageRequest, + DefaultImageProvider defaultProvider) { + loadThumbnail(view, photoId, null, darkTheme, isCircular, + defaultImageRequest, defaultProvider); + } /** * Load photo into the supplied image view. If the photo is already cached, @@ -476,8 +498,9 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { * @param defaultProvider The provider of default avatars (this is used if photoUri doesn't * refer to an existing image) */ - public abstract void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, - boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest, + public abstract void loadPhoto(ImageView view, Uri photoUri, + Account account, int requestedExtent, boolean darkTheme, + boolean isCircular, DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider); /** @@ -488,12 +511,26 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { * @param defaultImageRequest {@link DefaultImageRequest} object that specifies how a default * letter tile avatar should be drawn. */ + public final void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest) { - loadPhoto(view, photoUri, requestedExtent, darkTheme, isCircular, + loadPhoto(view, photoUri, null, requestedExtent, darkTheme, isCircular, defaultImageRequest, DEFAULT_AVATAR); } + public final void loadPhoto(ImageView view, Uri photoUri, Account account, int requestedExtent, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest) { + loadPhoto(view, photoUri, account, requestedExtent, darkTheme, isCircular, + defaultImageRequest, DEFAULT_AVATAR); + } + + public final void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest, + DefaultImageProvider defaultProvider) { + loadPhoto(view, photoUri, null, requestedExtent, darkTheme, isCircular, + defaultImageRequest, defaultProvider); + } + /** * Calls {@link #loadPhoto(ImageView, Uri, boolean, boolean, DefaultImageRequest, * DefaultImageProvider)} with {@link #DEFAULT_AVATAR} and with the assumption, that @@ -504,7 +541,15 @@ public abstract class ContactPhotoManager implements ComponentCallbacks2 { */ public final void loadDirectoryPhoto(ImageView view, Uri photoUri, boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest) { - loadPhoto(view, photoUri, -1, darkTheme, isCircular, defaultImageRequest, DEFAULT_AVATAR); + loadPhoto(view, photoUri, null, -1, darkTheme, isCircular, + defaultImageRequest, DEFAULT_AVATAR); + } + + public final void loadDirectoryPhoto(ImageView view, Uri photoUri, + Account account, boolean darkTheme, boolean isCircular, + DefaultImageRequest defaultImageRequest) { + loadPhoto(view, photoUri, account, -1, darkTheme, isCircular, + defaultImageRequest, DEFAULT_AVATAR); } /** @@ -784,11 +829,12 @@ class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback { } @Override - public void loadThumbnail(ImageView view, long photoId, boolean darkTheme, boolean isCircular, - DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider) { + public void loadThumbnail(ImageView view, long photoId, Account account, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest, + DefaultImageProvider defaultProvider) { if (photoId == 0) { // No photo is needed - defaultProvider.applyDefaultImage(view, -1, darkTheme, defaultImageRequest); + defaultProvider.applyDefaultImage(view, account, -1, darkTheme, defaultImageRequest); mPendingRequests.remove(view); } else { if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoId); @@ -798,19 +844,19 @@ class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback { } @Override - public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme, - boolean isCircular, DefaultImageRequest defaultImageRequest, + public void loadPhoto(ImageView view, Uri photoUri, Account account, int requestedExtent, + boolean darkTheme, boolean isCircular, DefaultImageRequest defaultImageRequest, DefaultImageProvider defaultProvider) { if (photoUri == null) { // No photo is needed - defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme, + defaultProvider.applyDefaultImage(view, account, requestedExtent, darkTheme, defaultImageRequest); mPendingRequests.remove(view); } else { if (DEBUG) Log.d(TAG, "loadPhoto request: " + photoUri); if (isDefaultImageUri(photoUri)) { - createAndApplyDefaultImageForUri(view, photoUri, requestedExtent, darkTheme, - isCircular, defaultProvider); + createAndApplyDefaultImageForUri(view, account, photoUri, requestedExtent, + darkTheme, isCircular, defaultProvider); } else { loadPhotoByIdOrUri(view, Request.createFromUri(photoUri, requestedExtent, darkTheme, isCircular, defaultProvider)); @@ -818,11 +864,12 @@ class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback { } } - private void createAndApplyDefaultImageForUri(ImageView view, Uri uri, int requestedExtent, - boolean darkTheme, boolean isCircular, DefaultImageProvider defaultProvider) { + private void createAndApplyDefaultImageForUri(ImageView view, + Account account, Uri uri, int requestedExtent, boolean darkTheme, + boolean isCircular, DefaultImageProvider defaultProvider) { DefaultImageRequest request = getDefaultImageRequestFromUri(uri); request.isCircular = isCircular; - defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme, request); + defaultProvider.applyDefaultImage(view, account, requestedExtent, darkTheme, request); } private void loadPhotoByIdOrUri(ImageView view, Request request) { @@ -1646,7 +1693,7 @@ class ContactPhotoManagerImpl extends ContactPhotoManager implements Callback { ? DefaultImageRequest.EMPTY_DEFAULT_BUSINESS_IMAGE_REQUEST : DefaultImageRequest.EMPTY_DEFAULT_IMAGE_REQUEST; } - mDefaultProvider.applyDefaultImage(view, mRequestedExtent, mDarkTheme, request); + mDefaultProvider.applyDefaultImage(view, null, mRequestedExtent, mDarkTheme, request); } } } diff --git a/src/com/android/contacts/common/ContactTileLoaderFactory.java b/src/com/android/contacts/common/ContactTileLoaderFactory.java index f8b0c359..ee9a2bf1 100644 --- a/src/com/android/contacts/common/ContactTileLoaderFactory.java +++ b/src/com/android/contacts/common/ContactTileLoaderFactory.java @@ -23,6 +23,8 @@ import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.RawContacts; +import android.text.TextUtils; /** * Used to create {@link CursorLoader}s to load different groups of @@ -35,19 +37,23 @@ public final class ContactTileLoaderFactory { public final static int STARRED = 2; public final static int PHOTO_URI = 3; public final static int LOOKUP_KEY = 4; - public final static int CONTACT_PRESENCE = 5; - public final static int CONTACT_STATUS = 6; + public final static int ACCOUNT_TYPE = 5; + public final static int ACCOUNT_NAME = 6; + + public final static int CONTACT_PRESENCE = 7; + public final static int CONTACT_STATUS = 8; + public final static int PHOTO_ID = 9; // Only used for StrequentPhoneOnlyLoader - public final static int PHONE_NUMBER = 5; - public final static int PHONE_NUMBER_TYPE = 6; - public final static int PHONE_NUMBER_LABEL = 7; - public final static int IS_DEFAULT_NUMBER = 8; - public final static int PINNED = 9; + public final static int PHONE_NUMBER = 7; + public final static int PHONE_NUMBER_TYPE = 8; + public final static int PHONE_NUMBER_LABEL = 9; + public final static int IS_DEFAULT_NUMBER = 10; + public final static int PINNED = 11; // The _ID field returned for strequent items actually contains data._id instead of // contacts._id because the query is performed on the data table. In order to obtain the // contact id for strequent items, we thus have to use Phone.contact_id instead. - public final static int CONTACT_ID_FOR_DATA = 10; + public final static int CONTACT_ID_FOR_DATA = 12; private static final String[] COLUMNS = new String[] { Contacts._ID, // ..........................................0 @@ -55,8 +61,11 @@ public final class ContactTileLoaderFactory { Contacts.STARRED, // ......................................2 Contacts.PHOTO_URI, // ....................................3 Contacts.LOOKUP_KEY, // ...................................4 - Contacts.CONTACT_PRESENCE, // .............................5 - Contacts.CONTACT_STATUS, // ...............................6 + RawContacts.ACCOUNT_TYPE, // 5 + RawContacts.ACCOUNT_NAME, // 6 + Contacts.CONTACT_PRESENCE, // .............................7 + Contacts.CONTACT_STATUS, // ...............................8 + Contacts.PHOTO_ID, // .....................................9 }; /** @@ -72,12 +81,14 @@ public final class ContactTileLoaderFactory { Contacts.STARRED, // ......................................2 Contacts.PHOTO_URI, // ....................................3 Contacts.LOOKUP_KEY, // ...................................4 - Phone.NUMBER, // ..........................................5 - Phone.TYPE, // ............................................6 - Phone.LABEL, // ...........................................7 - Phone.IS_SUPER_PRIMARY, //.................................8 - Contacts.PINNED, // .......................................9 - Phone.CONTACT_ID //........................................10 + RawContacts.ACCOUNT_TYPE, // 5 + RawContacts.ACCOUNT_NAME, // 6 + Phone.NUMBER, // ..........................................7 + Phone.TYPE, // ............................................8 + Phone.LABEL, // ............................................9 + Phone.IS_SUPER_PRIMARY, //.................................10 + Contacts.PINNED, // .......................................11 + Phone.CONTACT_ID //........................................12 }; private static final String STARRED_ORDER = Contacts.DISPLAY_NAME+" COLLATE NOCASE ASC"; @@ -88,10 +99,16 @@ public final class ContactTileLoaderFactory { } public static CursorLoader createStrequentPhoneOnlyLoader(Context context) { - Uri uri = Contacts.CONTENT_STREQUENT_URI.buildUpon() - .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build(); - - return new CursorLoader(context, uri, COLUMNS_PHONE_ONLY, null, null, null); + Uri.Builder builder = Contacts.CONTENT_STREQUENT_URI.buildUpon(); + builder.appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true"); + // Do not show contacts in disabled SIM card + String disabledSimFilter = MoreContactUtils.getDisabledSimFilter(); + if (!TextUtils.isEmpty(disabledSimFilter)) { + builder.appendQueryParameter(RawContacts.ACCOUNT_NAME, disabledSimFilter); + builder.appendQueryParameter(SimContactsConstants + .WITHOUT_SIM_FLAG, "true"); + } + return new CursorLoader(context, builder.build(), COLUMNS_PHONE_ONLY, null, null, null); } public static CursorLoader createStarredLoader(Context context) { diff --git a/src/com/android/contacts/common/MoreContactUtils.java b/src/com/android/contacts/common/MoreContactUtils.java index 16b4e8d9..7e96c62a 100644 --- a/src/com/android/contacts/common/MoreContactUtils.java +++ b/src/com/android/contacts/common/MoreContactUtils.java @@ -1,6 +1,10 @@ /* + * Copyright (C) 2013-2014, The Linux Foundation. All Rights Reserved. + * Not a Contribution. + * * Copyright (C) 2012 The Android Open Source Project * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,20 +20,59 @@ package com.android.contacts.common; +import android.accounts.Account; + import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.ComponentName; +import android.content.DialogInterface; import android.content.Intent; +import android.content.OperationApplicationException; +import android.content.res.Resources; +import android.database.Cursor; import android.graphics.Rect; import android.net.Uri; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.storage.StorageManager; +import android.os.storage.StorageVolume; import android.provider.ContactsContract; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.provider.ContactsContract.Data; +import android.provider.ContactsContract.RawContacts; +import android.provider.Settings; +import android.telephony.SubscriptionManager; import android.telephony.PhoneNumberUtils; +import android.telecom.PhoneAccountHandle; +import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.view.LayoutInflater; +import android.util.Log; import android.view.View; +import android.widget.EditText; import android.widget.TextView; import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.SimAccountType; +import com.android.internal.telephony.uicc.AdnRecord; +import com.android.internal.telephony.uicc.IccConstants; +import com.android.internal.telephony.IIccPhoneBook; + +import java.util.ArrayList; +import java.util.List; /** * Shared static contact utility methods. @@ -37,7 +80,30 @@ import com.android.contacts.common.model.account.AccountType; public class MoreContactUtils { private static final String WAIT_SYMBOL_AS_STRING = String.valueOf(PhoneNumberUtils.WAIT); + private static final boolean DBG = true; + private static final String TAG = "MoreContactUtils"; + public static final int MAX_LENGTH_NAME_IN_SIM = 14; + public static final int MAX_LENGTH_NAME_WITH_CHINESE_IN_SIM = 6; + public static final int MAX_LENGTH_NUMBER_IN_SIM = 20; + public static final int MAX_LENGTH_EMAIL_IN_SIM = 40; + private static final int NAME_POS = 0; + private static final int NUMBER_POS = 1; + private static final int EMAIL_POS = 2; + private static final int ANR_POS = 3; + private static final String PHONEBOOK = "simphonebook"; + public static final String[] MULTI_SIM_NAME = { "perferred_name_sub1", + "perferred_name_sub2" }; + public static final String PREFERRED_SIM_ICON_INDEX = "preferred_sim_icon_index"; + public static final String[] IPCALL_PREFIX = { "ip_call_prefix_sub1", + "ip_call_prefix_sub2" }; + public final static int[] IC_SIM_PICTURE = { + R.drawable.ic_contact_picture_sim_1, + R.drawable.ic_contact_picture_sim_2, + R.drawable.ic_contact_picture_sim_personal, + R.drawable.ic_contact_picture_sim_business, + R.drawable.ic_contact_picture_sim_primary + }; /** * Returns true if two data with mimetypes which represent values in contact entries are * considered equal for collapsing in the GUI. For caller-id, use @@ -232,4 +298,600 @@ public class MoreContactUtils { intent.setData(lookupUri); return intent; } + + /** get disabled SIM card's name */ + public static String getDisabledSimFilter() { + int count = TelephonyManager.getDefault().getPhoneCount(); + StringBuilder simFilter = new StringBuilder(""); + + for (int i = 0; i < count; i++) { + if (TelephonyManager.SIM_STATE_UNKNOWN == TelephonyManager + .getDefault().getSimState(i)) { + simFilter.append(getSimAccountName(i) + ','); + } + } + + return simFilter.toString(); + } + + public static boolean isShowOperator(Context context) { + return context.getResources().getBoolean(R.bool.config_show_operator); + } + + public static boolean isShowOperator(Resources resources) { + return resources.getBoolean(R.bool.config_show_operator); + } + + public static boolean sdCardExist(Context context) { + String sdcardPath = getSDPath(context); + if (sdcardPath == null) { + return false; + } + StorageManager mStorageManager = (StorageManager) context + .getSystemService(Context.STORAGE_SERVICE); + return mStorageManager.getVolumeState(sdcardPath).equals( + android.os.Environment.MEDIA_MOUNTED); + } + + public static String getSDPath(Context context) { + StorageManager mStorageManager = (StorageManager) context + .getSystemService(Context.STORAGE_SERVICE); + StorageVolume[] volumes = mStorageManager.getVolumeList(); + for (int i = 0; i < volumes.length; i++) { + if (volumes[i].isRemovable() && volumes[i].allowMassStorage() + && volumes[i].getDescription(context).contains("SD")) { + return volumes[i].getPath(); + } + } + return null; + } + + public static boolean isAPMOnAndSIMPowerDown(Context context) { + if (context == null) { + return false; + } + boolean isAirPlaneMode = Settings.System.getInt(context.getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, 0) == 1; + boolean isSIMPowerDown = SystemProperties.getInt( + "persist.radio.apm_sim_not_pwdn", 0) == 0; + return isAirPlaneMode && isSIMPowerDown; + } + + /** + * Get SIM card account name + */ + public static String getSimAccountName(int subscription) { + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + return SimContactsConstants.SIM_NAME + (subscription + 1); + } else { + return SimContactsConstants.SIM_NAME; + } + } + + public static int getSubscription(String accountType, String accountName) { + int subscription = SimContactsConstants.SUB_INVALID; + if (accountType == null || accountName == null) + return subscription; + if (accountType.equals(SimContactsConstants.ACCOUNT_TYPE_SIM)) { + if (accountName.equals(SimContactsConstants.SIM_NAME) + || accountName.equals(SimContactsConstants.SIM_NAME_1)) { + subscription = SimContactsConstants.SUB_1; + } else if (accountName.equals(SimContactsConstants.SIM_NAME_2)) { + subscription = SimContactsConstants.SUB_2; + } + } + return subscription; + } + + public static int getAnrCount(int slot) { + int anrCount = 0; + int[] subId = SubscriptionManager.getSubId(slot); + try { + IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( + ServiceManager.getService("simphonebook")); + + if (iccIpb != null) { + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + anrCount = iccIpb.getAnrCountUsingSubId(subId[0]); + } else { + anrCount = iccIpb.getAnrCount(); + } + } + } catch (RemoteException ex) { + // ignore it + } + + return anrCount; + } + + public static int getSpareAnrCount(int slot) { + int anrCount = 0; + int[] subId = SubscriptionManager.getSubId(slot); + try { + IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( + ServiceManager.getService("simphonebook")); + + if (iccIpb != null) { + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + anrCount = iccIpb.getSpareAnrCountUsingSubId(subId[0]); + } else { + anrCount = iccIpb.getSpareAnrCount(); + } + } + } catch (RemoteException ex) { + // ignore it + } + + return anrCount; + } + + public static int getAdnCount(int slot) { + int adnCount = 0; + int[] subId = SubscriptionManager.getSubId(slot); + try { + IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( + ServiceManager.getService("simphonebook")); + + if (iccIpb != null) { + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + adnCount = iccIpb.getAdnCountUsingSubId(subId[0]); + } else { + adnCount = iccIpb.getAdnCount(); + } + } + } catch (RemoteException ex) { + // ignore it + } + + return adnCount; + } + + public static int getEmailCount(int slot) { + int emailCount = 0; + int[] subId = SubscriptionManager.getSubId(slot); + try { + IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( + ServiceManager.getService("simphonebook")); + + if (iccIpb != null) { + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + emailCount = iccIpb.getEmailCountUsingSubId(subId[0]); + } else { + emailCount = iccIpb.getEmailCount(); + } + } + } catch (RemoteException ex) { + // ignore it + } + + return emailCount; + } + + public static int getSpareEmailCount(int slot) { + int emailCount = 0; + int[] subId = SubscriptionManager.getSubId(slot); + try { + IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface( + ServiceManager.getService("simphonebook")); + + if (iccIpb != null) { + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + emailCount = iccIpb.getSpareEmailCountUsingSubId(subId[0]); + } else { + emailCount = iccIpb.getSpareEmailCount(); + } + } + } catch (RemoteException ex) { + // ignore it + } + + return emailCount; + } + + /** + * Returns the subscription's card can save anr or not. + */ + public static boolean canSaveAnr(int slot) { + return getAnrCount(slot) > 0 ? true : false; + } + + /** + * Returns the subscription's card can save email or not. + */ + public static boolean canSaveEmail(int slot) { + return getEmailCount(slot) > 0 ? true : false; + } + + public static int getOneSimAnrCount(int slot) { + int count = 0; + int anrCount = getAnrCount(slot); + int adnCount = getAdnCount(slot); + if (adnCount > 0) { + count = anrCount % adnCount != 0 ? (anrCount / adnCount + 1) + : (anrCount / adnCount); + } + return count; + } + + public static int getOneSimEmailCount(int slot) { + int count = 0; + int emailCount = getEmailCount(slot); + int adnCount = getAdnCount(slot); + if (adnCount > 0) { + count = emailCount % adnCount != 0 ? (emailCount + / adnCount + 1) + : (emailCount / adnCount); + } + return count; + } + + public static boolean insertToPhone(String[] values, final ContentResolver resolver,int sub) { + Account account = getAcount(sub); + final String name = values[NAME_POS]; + final String phoneNumber = values[NUMBER_POS]; + final String emailAddresses = values[EMAIL_POS]; + final String anrs = values[ANR_POS]; + + final String[] emailAddressArray; + final String[] anrArray; + boolean success = true; + if (!TextUtils.isEmpty(emailAddresses)) { + emailAddressArray = emailAddresses.split(","); + } else { + emailAddressArray = null; + } + if (!TextUtils.isEmpty(anrs)) { + anrArray = anrs.split(","); + } else { + anrArray = null; + } + if (DBG) { + Log.d(TAG, "insertToPhone: name= " + name + ", phoneNumber= " + phoneNumber + + ", emails= " + emailAddresses + ", anrs= " + anrs + ", account= " + account); + } + final ArrayList<ContentProviderOperation> operationList = + new ArrayList<ContentProviderOperation>(); + ContentProviderOperation.Builder builder = ContentProviderOperation + .newInsert(RawContacts.CONTENT_URI); + builder.withValue(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED); + + if (account != null) { + builder.withValue(RawContacts.ACCOUNT_NAME, account.name); + builder.withValue(RawContacts.ACCOUNT_TYPE, account.type); + } + operationList.add(builder.build()); + + // do not allow empty value insert into database. + if (!TextUtils.isEmpty(name)) { + builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); + builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); + builder.withValue(StructuredName.DISPLAY_NAME, name); + operationList.add(builder.build()); + } + + if (!TextUtils.isEmpty(phoneNumber)) { + builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); + builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); + builder.withValue(Phone.TYPE, Phone.TYPE_MOBILE); + builder.withValue(Phone.NUMBER, phoneNumber); + builder.withValue(Data.IS_PRIMARY, 1); + operationList.add(builder.build()); + } + + if (anrArray != null) { + for (String anr : anrArray) { + if (!TextUtils.isEmpty(anr)) { + builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); + builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); + builder.withValue(Phone.TYPE, Phone.TYPE_HOME); + builder.withValue(Phone.NUMBER, anr); + operationList.add(builder.build()); + } + } + } + + if (emailAddressArray != null) { + for (String emailAddress : emailAddressArray) { + if (!TextUtils.isEmpty(emailAddress)) { + builder = ContentProviderOperation.newInsert(Data.CONTENT_URI); + builder.withValueBackReference(Email.RAW_CONTACT_ID, 0); + builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE); + builder.withValue(Email.TYPE, Email.TYPE_MOBILE); + builder.withValue(Email.ADDRESS, emailAddress); + operationList.add(builder.build()); + } + } + } + + try { + ContentProviderResult[] results = + resolver.applyBatch(ContactsContract.AUTHORITY, operationList); + for (ContentProviderResult result: results) { + if (result.uri == null) { + success = false; + break; + } + } + return success; + } catch (RemoteException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + return false; + } catch (OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + return false; + } + } + + public static Uri insertToCard(Context context, String name, String number, String emails, + String anrNumber, int subscription) { + // add the max count limit of Chinese code or not + if (!TextUtils.isEmpty(name)) { + final int maxLen = hasChinese(name) ? MAX_LENGTH_NAME_WITH_CHINESE_IN_SIM + : MAX_LENGTH_NAME_IN_SIM; + if (name.length() > maxLen) { + name = name.substring(0, maxLen); + } + } + Uri result; + ContentValues mValues = new ContentValues(); + mValues.clear(); + mValues.put(SimContactsConstants.STR_TAG, name); + if (!TextUtils.isEmpty(number)) { + number = PhoneNumberUtils.stripSeparators(number); + if (number.length() > MAX_LENGTH_NUMBER_IN_SIM) { + number = number.substring(0, MAX_LENGTH_NUMBER_IN_SIM); + } + + mValues.put(SimContactsConstants.STR_NUMBER, number); + } + if (!TextUtils.isEmpty(emails)) { + mValues.put(SimContactsConstants.STR_EMAILS, emails); + } + if (!TextUtils.isEmpty(anrNumber)) { + anrNumber = PhoneNumberUtils.stripSeparators(anrNumber); + mValues.put(SimContactsConstants.STR_ANRS, anrNumber); + } + + SimContactsOperation mSimContactsOperation = new SimContactsOperation(context); + result = mSimContactsOperation.insert(mValues, subscription); + + if (result != null) { + // we should import the contact to the sim account at the same time. + String[] value = new String[] { + name, number, emails, anrNumber + }; + insertToPhone(value, context.getContentResolver(),subscription); + } else { + Log.e(TAG, "export contact: [" + name + ", " + number + ", " + emails + "] to slot " + + subscription + " failed"); + } + return result; + } + + public static Account getAcount(int sub) { + Account account = null; + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + if (sub == SimContactsConstants.SUB_1) { + account = new Account(SimContactsConstants.SIM_NAME_1, + SimContactsConstants.ACCOUNT_TYPE_SIM); + } else if (sub == SimContactsConstants.SUB_2) { + account = new Account(SimContactsConstants.SIM_NAME_2, + SimContactsConstants.ACCOUNT_TYPE_SIM); + } + } else { + if (sub == SimContactsConstants.SUB_1) { + account = new Account(SimContactsConstants.SIM_NAME, + SimContactsConstants.ACCOUNT_TYPE_SIM); + } + } + if (account == null) { + account = new Account(SimContactsConstants.PHONE_NAME, + SimContactsConstants.ACCOUNT_TYPE_PHONE); + } + return account; + } + + public static int getEnabledSimCount() { + int mPhoneCount = TelephonyManager.getDefault().getPhoneCount(); + int enabledSimCount = 0; + for (int i = 0; i < mPhoneCount; i++) { + if (TelephonyManager.SIM_STATE_READY == TelephonyManager + .getDefault().getSimState(i)) { + enabledSimCount++; + } + } + return enabledSimCount; + } + + public static int getSimFreeCount(Context context, int sub) { + String accountName = getAcount(sub).name; + int count = 0; + + if (context == null) { + return 0; + } + + Cursor queryCursor = context.getContentResolver().query( + RawContacts.CONTENT_URI, + new String[] { + RawContacts._ID + }, + RawContacts.ACCOUNT_NAME + " = '" + accountName + "' AND " + RawContacts.DELETED + + " = 0", null, null); + if (queryCursor != null) { + try { + count = queryCursor.getCount(); + } finally { + queryCursor.close(); + } + } + return getAdnCount(sub) - count; + } + + private static boolean hasChinese(String name) { + return name != null && name.getBytes().length > name.length(); + } + + /** + * Get SIM card aliases name, which defined in Settings + */ + public static String getMultiSimAliasesName(Context context, int subscription) { + if (context == null || subscription < 0) { + return null; + } + String name = ""; + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + name = Settings.System.getString(context.getContentResolver(), + MULTI_SIM_NAME[subscription]); + } + if (TextUtils.isEmpty(name)) { + name = getSimAccountName(subscription); + } + return name; + } + + /** + * Get SIM card icon index by slot + */ + public static int getCurrentSimIconIndex(Context context, int slot) { + if (context == null || slot < SimContactsConstants.SUB_1 + || slot >= TelephonyManager.getDefault().getPhoneCount()) { + return -1; + } + + String simIconIndex = Settings.System.getString(context.getContentResolver(), + PREFERRED_SIM_ICON_INDEX); + if (TextUtils.isEmpty(simIconIndex)) { + return slot; + } else { + String[] indexs = simIconIndex.split(","); + if (slot >= indexs.length) { + return -1; + } + return Integer.parseInt(indexs[slot]); + } + } + + /** + * Get Network SPN name, e.g. China Unicom + */ + public static String getNetworkSpnName(Context context, int subscription) { + TelephonyManager tm = (TelephonyManager) + context.getSystemService(Context.TELEPHONY_SERVICE); + String netSpnName = ""; + netSpnName = tm.getNetworkOperatorName(subscription); + if (TextUtils.isEmpty(netSpnName)) { + // if could not get the operator name, use account name instead of + netSpnName = getSimAccountName(subscription); + } + return toUpperCaseFirstOne(netSpnName); + } + + public static String toUpperCaseFirstOne(String s) { + if (Character.isUpperCase(s.charAt(0))) { + return s; + } else { + return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))) + .append(s.substring(1)).toString(); + } + } + + /** + * Display IP call setting dialog + */ + public static void showNoIPNumberDialog(final Context mContext, final int subscription) { + try { + new AlertDialog.Builder(mContext) + .setTitle(R.string.no_ip_number) + .setMessage(R.string.no_ip_number_on_sim_card) + .setPositiveButton(R.string.set_ip_number, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + setIPNumber(mContext, subscription); + } + }).setNegativeButton(android.R.string.cancel, null).show(); + } catch (Exception e) { + } + } + + /** + * Setting IP Call number + */ + public static void setIPNumber(final Context mContext, final int subscription) { + try { + LayoutInflater mInflater = LayoutInflater.from(mContext); + View v = mInflater.inflate(R.layout.ip_prefix_dialog, null); + final EditText edit = (EditText) v.findViewById(R.id.ip_prefix_dialog_edit); + String ip_prefix = Settings.System.getString(mContext.getContentResolver(), + IPCALL_PREFIX[subscription]); + edit.setText(ip_prefix); + + new AlertDialog.Builder(mContext).setTitle(R.string.ipcall_dialog_title) + .setIcon(android.R.drawable.ic_dialog_info).setView(v) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String ip_prefix = edit.getText().toString(); + Settings.System.putString(mContext.getContentResolver(), + IPCALL_PREFIX[subscription], ip_prefix); + } + }).setNegativeButton(android.R.string.cancel, null).show(); + } catch (Exception e) { + } + } + + /** + * Check one SIM card is enabled + */ + public static boolean isMultiSimEnable(Context context, int slotId) { + if (Settings.System.getInt(context.getContentResolver(), + Settings.Global.AIRPLANE_MODE_ON, 0) != 0 + || TelephonyManager.SIM_STATE_READY != TelephonyManager + .getDefault() + .getSimState(slotId)) { + return false; + } + return true; + } + + /** + * Get IP Call prefix + */ + public static String getIPCallPrefix(Context context, int slot) { + String ipCallPrefix = ""; + ipCallPrefix = Settings.System.getString(context.getContentResolver(), + IPCALL_PREFIX[slot]); + return ipCallPrefix; + } + + public static PhoneAccountHandle getAccount(int slot) { + ComponentName serviceName = new ComponentName("com.android.phone", + "com.android.services.telephony.TelephonyConnectionService"); + int[] subId = SubscriptionManager.getSubId(slot); + return new PhoneAccountHandle(serviceName, String.valueOf(subId[0])); + } + + public static boolean shouldSearchCallLogsInSmartDial(Context context) { + return context.getResources().getBoolean(R.bool.config_smart_search); + } + + public static boolean isCAndGOption(Context context) { + return context.getResources().getBoolean(R.bool.config_set_CG_option); + } + + public static boolean isCAndGState(Context context) { + int SelectSmartfrenState = Settings.Global.getInt(context.getContentResolver(), + "smartfren_voice_sms_selection", 1); + return SelectSmartfrenState == 1 ? true : false; + } + } diff --git a/src/com/android/contacts/common/SimContactsConstants.java b/src/com/android/contacts/common/SimContactsConstants.java new file mode 100644 index 00000000..5928b1e6 --- /dev/null +++ b/src/com/android/contacts/common/SimContactsConstants.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014, The Linux Foundation. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ +package com.android.contacts.common; + +import android.telephony.SubscriptionManager; +import com.android.internal.telephony.PhoneConstants; + +public interface SimContactsConstants { + + public static final String SIM_NAME_1 = "SIM1"; + public static final String SIM_NAME_2 = "SIM2"; + public static final String SIM_NAME = "SIM"; + public static final String PHONE_NAME = "PHONE"; + public static final String PASSWORD = ""; + public static final String ACCOUNT_TYPE_SIM = "com.android.sim"; + public static final String ACCOUNT_TYPE_PHONE = "com.android.localphone"; + public static final String SUB = PhoneConstants.SLOT_KEY; + public static final String ACCOUNT_TYPE = "account_type"; + public static final String ACCOUNT_NAME = "account_name"; + public static final String ACCOUNT_DATA = "data_set"; + public static final String STR_TAG = "tag"; + public static final String STR_NUMBER = "number"; + public static final String STR_EMAILS = "emails"; + public static final String STR_ANRS = "anrs"; + public static final String STR_NEW_TAG = "newTag"; + public static final String STR_NEW_NUMBER = "newNumber"; + public static final String STR_NEW_EMAILS = "newEmails"; + public static final String STR_NEW_ANRS = "newAnrs"; + public static final String INTENT_EXPORT_COMPLETE = + "com.android.sim.INTENT_EXPORT_COMPLETE"; + public static final String SIM_URI = "content://icc/adn"; + public static final String SIM_SUB_URI = "content://icc/adn/subId/"; + public static final String WITHOUT_SIM_FLAG ="no_sim"; + public static final String IS_CONTACT = "is_contact"; + public static final String RESULT_KEY = "result"; + public static final String ACTION_MULTI_PICK = + "com.android.contacts.action.MULTI_PICK"; + public static final String ACTION_MULTI_PICK_EMAIL = + "com.android.contacts.action.MULTI_PICK_EMAIL"; + public static final String ACTION_MULTI_PICK_CALL = + "com.android.contacts.action.MULTI_PICK_CALL"; + public static final String ACTION_MULTI_PICK_SIM = + "com.android.contacts.action.MULTI_PICK_SIM"; + public static final int SUB_1 = PhoneConstants.SUB1; + public static final int SUB_2 = PhoneConstants.SUB2; + public static final int SUB_INVALID = SubscriptionManager.INVALID_SIM_SLOT_INDEX; + +} + + diff --git a/src/com/android/contacts/common/SimContactsOperation.java b/src/com/android/contacts/common/SimContactsOperation.java new file mode 100644 index 00000000..60fc9f12 --- /dev/null +++ b/src/com/android/contacts/common/SimContactsOperation.java @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2014, The Linux Foundation. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +package com.android.contacts.common; + +import android.content.AsyncQueryHandler; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.provider.ContactsContract; +import android.provider.ContactsContract.Data; +import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.CommonDataKinds; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.provider.ContactsContract.RawContacts; +import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; +import android.telephony.SubscriptionManager; +import android.text.TextUtils; +import android.util.Log; + +import com.android.contacts.common.SimContactsConstants; + +public class SimContactsOperation { + + private static final String TAG = "SimContactsOperation"; + private static final boolean DBG = true; + private static final int QUERY_TOKEN = 0; + private static final int INSERT_TOKEN = 1; + private static final int UPDATE_TOKEN = 2; + private static final int DELETE_TOKEN = 3; + + public static final String[] ACCOUNT_PROJECTION = new String[] { + RawContacts._ID, + RawContacts.CONTACT_ID, + RawContacts.ACCOUNT_NAME, + RawContacts.ACCOUNT_TYPE, + }; + + + private static final int ACCOUNT_COLUMN_RAW_ID = 0; + private static final int ACCOUNT_COLUMN_CONTACT_ID = 1; + private static final int ACCOUNT_COLUMN_NAME = 2; + private static final int ACCOUNT_COLUMN_TYPE = 3; + private static final int ACCOUNT_COLUMN_PHONE_NAME = 4; + + + + private static Context mContext; + private ContentResolver mResolver; + private ContentValues mValues = new ContentValues(); + + + public SimContactsOperation(Context context) { + this.mContext = context; + this.mResolver = context.getContentResolver(); + } + + + public Uri insert(ContentValues values, int subscription) { + + Uri uri = getContentUri(subscription); + if (uri == null) { + return null; + } + String number = values.getAsString(SimContactsConstants.STR_NUMBER); + String anrs = values.getAsString(SimContactsConstants.STR_ANRS); + String emails = values.getAsString(SimContactsConstants.STR_EMAILS); + values.put(SimContactsConstants.STR_NUMBER,PhoneNumberUtils.stripSeparators(number)); + values.put(SimContactsConstants.STR_ANRS,PhoneNumberUtils.stripSeparators(anrs)); + values.put(SimContactsConstants.STR_EMAILS,emails); + + Uri resultUri; + resultUri = mResolver.insert(uri,values); + return resultUri; + } + + public int update(ContentValues values,int subscription) { + Uri uri = getContentUri(subscription); + if (uri == null) { + return -1; + } + int result; + String oldNumber = values.getAsString(SimContactsConstants.STR_NUMBER); + String newNumber = values.getAsString(SimContactsConstants.STR_NEW_NUMBER); + String oldAnrs = values.getAsString(SimContactsConstants.STR_ANRS); + String newAnrs = values.getAsString(SimContactsConstants.STR_NEW_ANRS); + values.put(SimContactsConstants.STR_NUMBER,PhoneNumberUtils.stripSeparators(oldNumber)); + values.put(SimContactsConstants.STR_NEW_NUMBER,PhoneNumberUtils.stripSeparators(newNumber)); + values.put(SimContactsConstants.STR_ANRS,PhoneNumberUtils.stripSeparators(oldAnrs)); + values.put(SimContactsConstants.STR_NEW_ANRS,PhoneNumberUtils.stripSeparators(newAnrs)); + + result = mResolver.update(uri,values,null,null); + return result; + + } + + public int delete(ContentValues values, int subscription) { + int result; + StringBuilder buf = new StringBuilder(); + String num = null; + String name = values.getAsString(SimContactsConstants.STR_TAG); + String number = values.getAsString(SimContactsConstants.STR_NUMBER); + String emails = values.getAsString(SimContactsConstants.STR_EMAILS); + String anrs = values.getAsString(SimContactsConstants.STR_ANRS); + if (number != null) + num = PhoneNumberUtils.stripSeparators(number); + if (anrs != null) + anrs = PhoneNumberUtils.stripSeparators(anrs); + Uri uri = getContentUri(subscription); + + if (uri == null) { + return -1; + } + + + if (!TextUtils.isEmpty(name)) { + buf.append("tag='"); + buf.append(name); + buf.append("'"); + } + if (!TextUtils.isEmpty(num)) { + buf.append(" AND number='"); + buf.append(num); + buf.append("'"); + } + if (!TextUtils.isEmpty(emails)) { + buf.append(" AND emails='"); + buf.append(emails); + buf.append("'"); + } + if (!TextUtils.isEmpty(anrs)) { + buf.append(" AND anrs='"); + buf.append(anrs); + buf.append("'"); + } + + result = mResolver.delete(uri,buf.toString(),null); + return result; + + } + + private Uri getContentUri(int subscription) { + Uri uri = null; + int[] subId = SubscriptionManager.getSubId(subscription); + + if (subId != null && TelephonyManager.getDefault().isMultiSimEnabled()) { + if (subId.length < 1 || subId[0] < 0) { + return null; + } + uri = Uri.parse(SimContactsConstants.SIM_SUB_URI + subId[0]); + } else { + uri = Uri.parse(SimContactsConstants.SIM_URI); + } + return uri; + } + + private static Cursor setupAccountCursor(long contactId) { + ContentResolver resolver = mContext.getContentResolver(); + + Cursor cursor = null; + try { + cursor = resolver.query(RawContacts.CONTENT_URI, + ACCOUNT_PROJECTION, + RawContacts.CONTACT_ID + "=" + + Long.toString(contactId), null, null); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } finally { + if (cursor != null && cursor.moveToFirst()) { + return cursor; + } + if (cursor != null) { + cursor.close(); + } + cursor = null; + return null; + } + } + + public static ContentValues getSimAccountValues(long contactId) { + ContentValues mValues = new ContentValues(); + Cursor cursor = setupAccountCursor(contactId); + if (cursor == null || cursor.getCount() == 0) { + mValues.clear(); + return mValues; + } + long rawContactId = cursor.getLong(cursor.getColumnIndex(RawContacts._ID)); + String accountName = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_NAME)); + String accountType = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE)); + cursor.close(); + if (SimContactsConstants.ACCOUNT_TYPE_SIM.equals(accountType)) { + mValues.clear(); + String name = getContactItems(rawContactId,StructuredName.CONTENT_ITEM_TYPE, + ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME); + mValues.put(SimContactsConstants.STR_TAG,name); + + String number = getContactPhoneNumber(rawContactId, + Phone.CONTENT_ITEM_TYPE, String.valueOf(Phone.TYPE_MOBILE), + ContactsContract.CommonDataKinds.Phone.DATA); + mValues.put(SimContactsConstants.STR_NUMBER,number); + + int sub = getSimSubscription(contactId); + + if (MoreContactUtils.canSaveAnr(sub)) { + String anrs = getContactPhoneNumber(rawContactId, + Phone.CONTENT_ITEM_TYPE, String.valueOf(Phone.TYPE_HOME), + ContactsContract.CommonDataKinds.Phone.DATA); + mValues.put(SimContactsConstants.STR_ANRS, anrs); + } + + if (MoreContactUtils.canSaveEmail(sub)) { + String emails = getContactItems(rawContactId, + Email.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Email.DATA); + mValues.put(SimContactsConstants.STR_EMAILS, emails); + } + } + return mValues; + } + + public static int getSimSubscription(long contactId) { + int subscription = SimContactsConstants.SUB_INVALID; + Cursor cursor = setupAccountCursor(contactId); + if (cursor == null || cursor.getCount() == 0) { + return subscription; + } + + String accountName = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_NAME)); + String accountType = cursor.getString(cursor.getColumnIndex(RawContacts.ACCOUNT_TYPE)); + if (accountType == null || accountName == null) { + return subscription; + } + if (SimContactsConstants.ACCOUNT_TYPE_SIM.equals(accountType)) { + subscription = MoreContactUtils.getSubscription(accountType, accountName); + } + cursor.close(); + return subscription; + } + + + private static String getContactItems(long rawContactId, String selectionArg, + String columnName) { + StringBuilder retval = new StringBuilder(); + Uri baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId); + Uri dataUri = Uri.withAppendedPath(baseUri, RawContacts.Data.CONTENT_DIRECTORY); + + Cursor c = null; + try { + c = mContext.getContentResolver().query(dataUri, null, + Data.MIMETYPE + "=?", new String[] {selectionArg}, null); + if (c == null || c.getCount() == 0) { + if(c != null) { + c.close(); + } + return null; + } + c.moveToPosition(-1); + + while (c.moveToNext()) { + if (!TextUtils.isEmpty(retval.toString())) { + retval.append(","); + } + retval.append(c.getString(c.getColumnIndex(columnName))); + } + + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } finally { + if (c != null) { + c.close(); + } + } + + return retval.toString(); + } + + private static + String getContactPhoneNumber(long rawContactId, String selectionArg1, + String selectionArg2, String columnName) { + StringBuilder retval = new StringBuilder(); + Uri baseUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId); + Uri dataUri = Uri.withAppendedPath(baseUri, RawContacts.Data.CONTENT_DIRECTORY); + + Cursor c = null; + try { + c = mContext.getContentResolver().query(dataUri, null, + Data.MIMETYPE + "=? AND " + Phone.TYPE + "=?", + new String[] {selectionArg1,selectionArg2}, null); + if (c == null || c.getCount() == 0) { + if(c != null) { + c.close(); + } + return null; + } + c.moveToPosition(-1); + + while (c.moveToNext()) { + if (!TextUtils.isEmpty(retval.toString())) { + retval.append(","); + } + retval.append(c.getString(c.getColumnIndex(columnName))); + } + + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } finally { + if (c != null) { + c.close(); + } + } + + return retval.toString(); + } + + + private void log(String msg) { + if (DBG) Log.d(TAG, msg); + } + +} diff --git a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java index c2ebbbfa..26fc7712 100644 --- a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java +++ b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java @@ -65,7 +65,7 @@ public final class SelectAccountDialogFragment extends DialogFragment { final SelectAccountDialogFragment instance = new SelectAccountDialogFragment(); instance.setArguments(args); instance.setTargetFragment(targetFragment, 0); - instance.show(fragmentManager, null); + instance.show(fragmentManager, SelectAccountDialogFragment.TAG); } @Override diff --git a/src/com/android/contacts/common/format/TextHighlighter.java b/src/com/android/contacts/common/format/TextHighlighter.java index 496dcdae..47b36e39 100644 --- a/src/com/android/contacts/common/format/TextHighlighter.java +++ b/src/com/android/contacts/common/format/TextHighlighter.java @@ -16,15 +16,12 @@ package com.android.contacts.common.format; -import android.graphics.Typeface; import android.text.SpannableString; import android.text.style.CharacterStyle; import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.widget.TextView; -import com.google.common.base.Preconditions; - /** * Highlights the text in a text field. */ @@ -33,12 +30,20 @@ public class TextHighlighter { private final static boolean DEBUG = false; private int mTextStyle; + private int mHighlightColor; private CharacterStyle mTextStyleSpan; + private CharacterStyle mTextColorStyleSpan; public TextHighlighter(int textStyle) { + this(textStyle, -1); + } + + public TextHighlighter(int textStyle, int highlightColor) { mTextStyle = textStyle; + mHighlightColor = highlightColor; mTextStyleSpan = getStyleSpan(); + mTextColorStyleSpan = getColorStyleSpan(); } /** @@ -56,6 +61,13 @@ public class TextHighlighter { return new StyleSpan(mTextStyle); } + private CharacterStyle getColorStyleSpan() { + if (mHighlightColor != -1) { + return new ForegroundColorSpan(mHighlightColor); + } + return null; + } + /** * Applies highlight span to the text. * @param text Text sequence to be highlighted. @@ -65,6 +77,9 @@ public class TextHighlighter { public void applyMaskingHighlight(SpannableString text, int start, int end) { /** Sets text color of the masked locations to be highlighted. */ text.setSpan(getStyleSpan(), start, end, 0); + if (mTextColorStyleSpan != null) { + text.setSpan(getColorStyleSpan(), start, end, 0); + } } /** @@ -90,6 +105,9 @@ public class TextHighlighter { if (index != -1) { final SpannableString result = new SpannableString(text); result.setSpan(mTextStyleSpan, index, index + trimmedPrefix.length(), 0 /* flags */); + if (mTextColorStyleSpan != null) { + result.setSpan(mTextColorStyleSpan, index, index + trimmedPrefix.length(), 0 /* flags */); + } return result; } else { return text; diff --git a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java index 6f002e45..68fb7df4 100644 --- a/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java +++ b/src/com/android/contacts/common/interactions/ImportExportDialogFragment.java @@ -1,5 +1,7 @@ /* * Copyright (C) 2010 The Android Open Source Project + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Not a Contribution. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,23 +18,45 @@ package com.android.contacts.common.interactions; +import android.accounts.Account; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.FragmentManager; +import android.app.ProgressDialog; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.ContentProviderOperation; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; import android.content.DialogInterface; +import android.content.DialogInterface.OnDismissListener; +import android.content.DialogInterface.OnCancelListener; import android.content.Intent; +import android.content.IntentFilter; import android.content.res.Resources; +import android.content.OperationApplicationException; import android.database.Cursor; +import android.text.TextUtils; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.RemoteException; +import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.RawContacts; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.Data; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.provider.Settings; import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; @@ -42,8 +66,13 @@ import android.widget.ArrayAdapter; import android.widget.TextView; import android.widget.Toast; +import com.android.contacts.common.MoreContactUtils; +import com.android.contacts.common.SimContactsOperation; +import com.android.contacts.common.SimContactsConstants; import com.android.contacts.common.R; import com.android.contacts.common.editor.SelectAccountDialogFragment; +import com.android.contacts.common.list.AccountFilterActivity; +import com.android.contacts.common.list.ContactListFilter; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.util.AccountSelectionUtil; @@ -54,6 +83,8 @@ import com.android.contacts.commonbind.analytics.AnalyticsUtil; import java.util.Collections; import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; /** * An dialog invoked to import/export contacts. @@ -65,11 +96,70 @@ public class ImportExportDialogFragment extends DialogFragment private static final String KEY_RES_ID = "resourceId"; private static final String KEY_SUBSCRIPTION_ID = "subscriptionId"; private static final String ARG_CONTACTS_ARE_AVAILABLE = "CONTACTS_ARE_AVAILABLE"; + private static int SIM_ID_INVALID = -1; + private static int mSelectedSim = SIM_ID_INVALID; + + private static final boolean DEBUG = true; + + public static final int SUBACTIVITY_EXPORT_CONTACTS = 100; + + // This values must be consistent with ImportExportDialogFragment.SUBACTIVITY_EXPORT_CONTACTS. + // This values is set 101,That is avoid to conflict with other new subactivity. + public static final int SUBACTIVITY_SHARE_VISILBLE_CONTACTS = 101; + public static final int MAX_COUNT_ALLOW_SHARE_CONTACT = 2000; private final String[] LOOKUP_PROJECTION = new String[] { Contacts.LOOKUP_KEY }; + static final int PHONE_ID_COLUMN_INDEX = 0; + static final int PHONE_TYPE_COLUMN_INDEX = 1; + static final int PHONE_LABEL_COLUMN_INDEX = 2; + static final int PHONE_NUMBER_COLUMN_INDEX = 3; + static final int PHONE_DISPLAY_NAME_COLUMN_INDEX = 4; + static final int PHONE_CONTACT_ID_COLUMN_INDEX = 5; + // This value needs to start at 7. See {@link PeopleActivity}. + public static final int SUBACTIVITY_MULTI_PICK_CONTACT = 7; + //TODO: we need to refactor the export code in future release. + // QRD enhancement: export subscription selected by user + public static int mExportSub; + //this flag is the same as defined in MultiPickContactActivit + private static final String EXT_NOT_SHOW_SIM_FLAG = "not_sim_show"; + // QRD enhancement: Toast handler for exporting concat to sim card + private static final int TOAST_EXPORT_FAILED = 0; + private static final int TOAST_EXPORT_FINISHED = 1; + // only for sim card is full + private static final int TOAST_SIM_CARD_FULL = 2; + // only for contact name too long + private static final int TOAST_CONTACT_NAME_TOO_LONG = 3; + // there is a case export is canceled by user + private static final int TOAST_EXPORT_CANCELED = 4; + // only for not have phone number or email address + private static final int TOAST_EXPORT_NO_PHONE_OR_EMAIL = 5; + // only for sim contacts haven't been loaded completely + private static final int TOAST_SIM_CARD_NOT_LOAD_COMPLETE = 6; + private SimContactsOperation mSimContactsOperation; + private ArrayAdapter<Integer> mAdapter; + private Activity mActivity; + private static boolean isExportingToSIM = false; + public static boolean isExportingToSIM(){ + return isExportingToSIM; + } + private static ExportToSimThread mExportThread = null; + public ExportToSimThread createExportToSimThread(int subscription, + ArrayList<String[]> contactList, Activity mActivity){ + if (mExportThread == null) + mExportThread = new ExportToSimThread(subscription, contactList, mActivity); + return mExportThread; + } + + public static void destroyExportToSimThread(){ + mExportThread = null; + } + public void showExportToSIMProgressDialog(Activity activity){ + mExportThread.showExportProgressDialog(activity); + } + private SubscriptionManager mSubscriptionManager; /** Preferred way to show this dialog */ @@ -92,6 +182,7 @@ public class ImportExportDialogFragment extends DialogFragment @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Wrap our context to inflate list items using the correct theme + mActivity = getActivity(); final Resources res = getActivity().getResources(); final LayoutInflater dialogInflater = (LayoutInflater)getActivity() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -112,6 +203,10 @@ public class ImportExportDialogFragment extends DialogFragment } }; + // Manually call notifyDataSetChanged() to refresh the list. + adapter.setNotifyOnChange(false); + loadData(contactsAreAvailable); + final TelephonyManager manager = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); @@ -162,71 +257,94 @@ public class ImportExportDialogFragment extends DialogFragment adapter.getItem(which).mSubscriptionId); break; } + case R.string.export_to_sim: { + handleExportToSimRequest(resId); + break; + } case R.string.export_to_sdcard: { - dismissDialog = true; - Intent exportIntent = new Intent(getActivity(), ExportVCardActivity.class); - exportIntent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY, - callingActivity); - getActivity().startActivity(exportIntent); + Intent exportIntent = new Intent(SimContactsConstants.ACTION_MULTI_PICK, + Contacts.CONTENT_URI); + exportIntent.putExtra(SimContactsConstants.IS_CONTACT, true); + getActivity().startActivityForResult(exportIntent, + SUBACTIVITY_EXPORT_CONTACTS); break; } case R.string.share_visible_contacts: { - dismissDialog = true; doShareVisibleContacts(); break; } default: { - dismissDialog = true; Log.e(TAG, "Unexpected resource: " + getActivity().getResources().getResourceEntryName(resId)); } } - if (dismissDialog) { dialog.dismiss(); - } } }; return new AlertDialog.Builder(getActivity()) .setTitle(contactsAreAvailable ? R.string.dialog_import_export : R.string.dialog_import) - .setSingleChoiceItems(adapter, -1, clickListener) + .setSingleChoiceItems(mAdapter, -1, clickListener) .create(); } - private void doShareVisibleContacts() { - // TODO move the query into a loader and do this in a background thread - final Cursor cursor = getActivity().getContentResolver().query(Contacts.CONTENT_URI, - LOOKUP_PROJECTION, Contacts.IN_VISIBLE_GROUP + "!=0", null, null); - if (cursor != null) { - try { - if (!cursor.moveToFirst()) { - Toast.makeText(getActivity(), R.string.share_error, Toast.LENGTH_SHORT).show(); - return; - } + /** + * Loading the menu list data. + * @param contactsAreAvailable + */ + private void loadData(boolean contactsAreAvailable) { + if (null == mActivity && null == mAdapter) { + return; + } - StringBuilder uriListBuilder = new StringBuilder(); - int index = 0; - do { - if (index != 0) - uriListBuilder.append(':'); - uriListBuilder.append(cursor.getString(0)); - index++; - } while (cursor.moveToNext()); - Uri uri = Uri.withAppendedPath( - Contacts.CONTENT_MULTI_VCARD_URI, - Uri.encode(uriListBuilder.toString())); - - final Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType(Contacts.CONTENT_VCARD_TYPE); - intent.putExtra(Intent.EXTRA_STREAM, uri); - getActivity().startActivity(intent); - } finally { - cursor.close(); + mAdapter.clear(); + final Resources res = mActivity.getResources(); + boolean hasIccCard = false; + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { + hasIccCard = TelephonyManager.getDefault().hasIccCard(i); + if (hasIccCard) { + break; + } + } + } else { + hasIccCard = TelephonyManager.getDefault().hasIccCard(); + } + + if (hasIccCard + && res.getBoolean(R.bool.config_allow_sim_import)) { + mAdapter.add(R.string.import_from_sim); + } + if (res.getBoolean(R.bool.config_allow_import_from_sdcard)) { + mAdapter.add(R.string.import_from_sdcard); + } + + if (hasIccCard) { + mAdapter.add(R.string.export_to_sim); + } + if (res.getBoolean(R.bool.config_allow_export_to_sdcard)) { + // If contacts are available and there is at least one contact in + // database, show "Export to SD card" menu item. Otherwise hide it + // because it makes no sense. + if (contactsAreAvailable) { + mAdapter.add(R.string.export_to_sdcard); + } + } + if (res.getBoolean(R.bool.config_allow_share_visible_contacts)) { + if (contactsAreAvailable) { + mAdapter.add(R.string.share_visible_contacts); } } } + private void doShareVisibleContacts() { + Intent intent = new Intent(SimContactsConstants.ACTION_MULTI_PICK); + intent.setType(Contacts.CONTENT_TYPE); + intent.putExtra(SimContactsConstants.IS_CONTACT,true); + getActivity().startActivityForResult(intent, SUBACTIVITY_SHARE_VISILBLE_CONTACTS); + } + /** * Handle "import from SIM" and "import from SD". * @@ -237,18 +355,18 @@ public class ImportExportDialogFragment extends DialogFragment // - more than one accounts -> ask the user // - just one account -> use the account without asking the user // - no account -> use phone-local storage without asking the user - final AccountTypeManager accountTypes = AccountTypeManager.getInstance(getActivity()); + final AccountTypeManager accountTypes = AccountTypeManager.getInstance(mActivity); final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true); final int size = accountList.size(); - if (size > 1) { + if (size > 0) { // Send over to the account selector final Bundle args = new Bundle(); args.putInt(KEY_RES_ID, resId); args.putInt(KEY_SUBSCRIPTION_ID, subscriptionId); SelectAccountDialogFragment.show( - getFragmentManager(), this, + mActivity.getFragmentManager(), this, R.string.dialog_new_contact_account, - AccountListFilter.ACCOUNTS_CONTACT_WRITABLE, args); + AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM, args); // In this case, because this DialogFragment is used as a target fragment to // SelectAccountDialogFragment, we can't close it yet. We close the dialog when @@ -280,6 +398,437 @@ public class ImportExportDialogFragment extends DialogFragment dismiss(); } + private class ExportToSimSelectListener implements DialogInterface.OnClickListener { + public void onClick(DialogInterface dialog, int which) { + if (which >= 0) { + mExportSub = which; + } else if (which == DialogInterface.BUTTON_POSITIVE) { + Intent pickPhoneIntent = new Intent( + SimContactsConstants.ACTION_MULTI_PICK, Contacts.CONTENT_URI); + // do not show the contacts in SIM card + pickPhoneIntent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER, + ContactListFilter + .createFilterWithType(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS)); + pickPhoneIntent.putExtra(EXT_NOT_SHOW_SIM_FLAG, true); + pickPhoneIntent.putExtra(SimContactsConstants.IS_CONTACT,true); + mActivity.startActivityForResult(pickPhoneIntent, SUBACTIVITY_MULTI_PICK_CONTACT); + } + } + } + + public class ImportFromSimSelectListener implements DialogInterface.OnClickListener { + public void onClick(DialogInterface dialog, int which) { + if (which >= 0) { + AccountSelectionUtil.setImportSubscription(which); + } else if (which == DialogInterface.BUTTON_POSITIVE) { + handleImportRequest(R.string.import_from_sim, which); + } + } + } + + /** + * A thread that export contacts to sim card + */ + public class ExportToSimThread extends Thread { + private int subscription; + private boolean canceled; + private ArrayList<String[]> contactList; + private ProgressDialog mExportProgressDlg; + private ContentValues mValues = new ContentValues(); + Activity mPeople; + private int freeSimCount = 0; + + public ExportToSimThread(int subscription, ArrayList<String[]> contactList, + Activity mActivity) { + super(); + this.subscription = subscription; + this.contactList = contactList; + canceled = false; + mPeople = mActivity; + showExportProgressDialog(mPeople); + } + + @Override + public void run() { + isExportingToSIM = true; + Account account = MoreContactUtils.getAcount(subscription); + boolean isAirplaneMode = false; + boolean isSimCardFull = false; + boolean isSimCardLoaded = true; + // GoogleSource.createMyContactsIfNotExist(account, getActivity()); + // in case export is stopped, record the count of inserted successfully + int insertCount = 0; + + mSimContactsOperation = new SimContactsOperation(mPeople); + Cursor cr = null; + // call query first, otherwise insert will fail if this insert is called + // without any query before + try{ + int[] subId = SubscriptionManager.getSubId(subscription); + if (subId != null + && TelephonyManager.getDefault().isMultiSimEnabled()) { + cr = mPeople.getContentResolver().query( + Uri.parse(SimContactsConstants.SIM_SUB_URI + + subId[0]), null, null, null, null); + } else { + cr = mPeople.getContentResolver().query( + Uri.parse(SimContactsConstants.SIM_URI), null, + null, null, null); + } + } catch (NullPointerException e) { + Log.e(TAG, "Exception:" + e); + } finally { + if (cr != null) { + cr.close(); + } + } + freeSimCount = MoreContactUtils.getSimFreeCount(mPeople,subscription); + boolean canSaveAnr = MoreContactUtils.canSaveAnr(subscription); + boolean canSaveEmail = MoreContactUtils.canSaveEmail(subscription); + int emptyAnr = MoreContactUtils.getSpareAnrCount(subscription); + int emptyEmail = MoreContactUtils + .getSpareEmailCount(subscription); + int emptyNumber = freeSimCount + emptyAnr; + + Log.d(TAG, "freeSimCount = " + freeSimCount); + String emails = null; + if (contactList != null) { + Iterator<String[]> iterator = contactList.iterator(); + while (iterator.hasNext() && !canceled && !isAirplaneMode && isSimCardLoaded) { + String[] contactInfo = iterator.next(); + String name = ""; + ArrayList<String> arrayNumber = new ArrayList<String>(); + ArrayList<String> arrayEmail = new ArrayList<String>(); + + Uri dataUri = Uri.withAppendedPath( + ContentUris.withAppendedId(Contacts.CONTENT_URI, + Long.parseLong(contactInfo[1])), + Contacts.Data.CONTENT_DIRECTORY); + final String[] projection = new String[] { + Contacts._ID, Contacts.Data.MIMETYPE, Contacts.Data.DATA1, + }; + Cursor c = mPeople.getContentResolver().query(dataUri, projection, null, + null, null); + + if (c != null && c.moveToFirst()) { + do { + String mimeType = c.getString(1); + if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) { + String number = c.getString(2); + if (!TextUtils.isEmpty(number) && emptyNumber-- >0) { + arrayNumber.add(number); + } + } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) { + name = c.getString(2); + } + if (canSaveEmail) { + if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) { + String email = c.getString(2); + if (!TextUtils.isEmpty(email) && emptyEmail-- > 0) { + arrayEmail.add(email); + } + } + } + } while (c.moveToNext()); + } + if (c != null) { + c.close(); + } + + if (freeSimCount > 0 && 0 == arrayNumber.size() + && 0 == arrayEmail.size()) { + mToastHandler.sendMessage(mToastHandler.obtainMessage( + TOAST_EXPORT_NO_PHONE_OR_EMAIL, name)); + continue; + } + + int phoneCountInOneSimContact = 1; + int emailCountInOneSimContact = 0; + if (canSaveAnr) { + int num = MoreContactUtils.getOneSimAnrCount(subscription); + phoneCountInOneSimContact = num > 1 ? (num + 1) : 2; + } + if (canSaveEmail) { + emailCountInOneSimContact = MoreContactUtils + .getOneSimEmailCount(subscription); + } + int nameCount = (name != null && !name.equals("")) ? 1 : 0; + int groupNumCount = (arrayNumber.size() % phoneCountInOneSimContact) != 0 ? + (arrayNumber.size() / phoneCountInOneSimContact + 1) + : (arrayNumber.size() / phoneCountInOneSimContact); + int groupEmailCount = emailCountInOneSimContact == 0 ? 0 + : ((arrayEmail.size() % emailCountInOneSimContact) != 0 ? ( + arrayEmail.size() / emailCountInOneSimContact + 1) + : (arrayEmail.size() / emailCountInOneSimContact)); + //recalute the group when spare anr is not enough + if (canSaveAnr && emptyAnr <= groupNumCount) { + groupNumCount = arrayNumber.size() - emptyAnr; + } + int groupCount = Math.max(groupEmailCount, + Math.max(nameCount, groupNumCount)); + + Uri result = null; + if (DEBUG) { + Log.d(TAG, "GroupCount = " + groupCount); + } + for (int i = 0; i < groupCount; i++) { + if (freeSimCount > 0) { + String num = arrayNumber.size() > 0 ? arrayNumber.remove(0) : null; + StringBuilder anrNum = new StringBuilder(); + StringBuilder email = new StringBuilder(); + if (canSaveAnr && emptyAnr-- > 0) { + for (int j = 1; j < phoneCountInOneSimContact; j++) { + if (arrayNumber.size() > 0 && emptyAnr-- > 0 ) { + String s = arrayNumber.remove(0); + if (s.length() > MoreContactUtils + .MAX_LENGTH_NUMBER_IN_SIM) { + s = s.substring(0, + MoreContactUtils.MAX_LENGTH_NUMBER_IN_SIM); + } + anrNum.append(s); + anrNum.append(","); + } + } + } + if (canSaveEmail) { + for (int j = 0; j < emailCountInOneSimContact; j++) { + if (arrayEmail.size() > 0) { + String s = arrayEmail.remove(0); + if (s.length() > MoreContactUtils + .MAX_LENGTH_EMAIL_IN_SIM) { + s = s.substring(0, + MoreContactUtils.MAX_LENGTH_EMAIL_IN_SIM); + } + email.append(s); + email.append(","); + } + } + } + + result = MoreContactUtils.insertToCard(mPeople, name, num, + email.toString(), anrNum.toString(), subscription); + + if (null == result) { + // add toast handler when sim card is full + if ((MoreContactUtils.getAdnCount(subscription) > 0) + && (MoreContactUtils.getSimFreeCount(mPeople, + subscription) == 0)) { + isSimCardFull = true; + mToastHandler.sendEmptyMessage(TOAST_SIM_CARD_FULL); + break; + } else { + isAirplaneMode = MoreContactUtils + .isAPMOnAndSIMPowerDown(mPeople); + if (isAirplaneMode) { + mToastHandler.sendEmptyMessage(TOAST_EXPORT_FAILED); + break; + } else { + continue; + } + } + } else { + if (DEBUG) { + Log.d(TAG, "Exported contact [" + name + ", " + + contactInfo[0] + ", " + contactInfo[1] + + "] to sub " + subscription); + } + insertCount++; + freeSimCount--; + } + } else { + if (MoreContactUtils.getAdnCount(subscription) == 0) { + isSimCardLoaded = false; + mToastHandler.sendEmptyMessage( + TOAST_SIM_CARD_NOT_LOAD_COMPLETE); + } else { + isSimCardFull = true; + mToastHandler.sendEmptyMessage(TOAST_SIM_CARD_FULL); + } + break; + } + } + + if (isSimCardFull) { + break; + } + } + } + if (mExportProgressDlg != null) { + mExportProgressDlg.dismiss(); + mExportProgressDlg = null; + } + + if (!isAirplaneMode && !isSimCardFull) { + // if canceled, show toast indicating export is interrupted. + if (canceled) { + mToastHandler.sendMessage(mToastHandler.obtainMessage(TOAST_EXPORT_CANCELED, + insertCount, 0)); + } else { + mToastHandler.sendEmptyMessage(TOAST_EXPORT_FINISHED); + } + } + isExportingToSIM = false; + Intent intent = new Intent(SimContactsConstants.INTENT_EXPORT_COMPLETE); + mPeople.sendBroadcast(intent); + } + + private Handler mToastHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case TOAST_EXPORT_FAILED: + Toast.makeText(mPeople, R.string.export_failed, Toast.LENGTH_SHORT).show(); + break; + case TOAST_EXPORT_FINISHED: + Toast.makeText(mPeople, R.string.export_finished, Toast.LENGTH_SHORT) + .show(); + break; + + // add toast handler when sim card is full + case TOAST_SIM_CARD_FULL: + Toast.makeText(mPeople, R.string.sim_card_full, Toast.LENGTH_SHORT).show(); + break; + + //add the max count limit of Chinese code or not + case TOAST_CONTACT_NAME_TOO_LONG: + Toast.makeText(mPeople, R.string.tag_too_long, Toast.LENGTH_SHORT).show(); + break; + + // add toast handler when export is canceled + case TOAST_EXPORT_CANCELED: + String text = mPeople.getResources().getQuantityString( + R.plurals.export_cancelled, msg.arg1, msg.arg1); + Toast.makeText(mPeople, text, Toast.LENGTH_SHORT).show(); + break; + + // add toast handler when no phone or email + case TOAST_EXPORT_NO_PHONE_OR_EMAIL: + String name = (String) msg.obj; + Toast.makeText(mPeople, + mPeople.getString(R.string.export_no_phone_or_email, name), + Toast.LENGTH_SHORT).show(); + break; + case TOAST_SIM_CARD_NOT_LOAD_COMPLETE: + Toast.makeText(mPeople, R.string.sim_contacts_not_loaded, + Toast.LENGTH_SHORT).show(); + break; + } + } + }; + + public void showExportProgressDialog(Activity activity){ + mPeople = activity; + mExportProgressDlg = new ProgressDialog(mPeople); + mExportProgressDlg.setTitle(R.string.export_to_sim); + mExportProgressDlg.setOnCancelListener(new OnCancelListener() { + public void onCancel(DialogInterface dialog) { + Log.d(TAG, "Cancel exporting contacts"); + canceled = true; + } + }); + mExportProgressDlg.setMessage(mPeople.getString(R.string.exporting)); + mExportProgressDlg.setProgressNumberFormat(mPeople.getString( + R.string.reading_vcard_files)); + mExportProgressDlg.setMax(contactList.size()); + //mExportProgressDlg.setProgress(insertCount); + + // set cancel dialog by touching outside disabled. + mExportProgressDlg.setCanceledOnTouchOutside(false); + + // add a cancel button to let user cancel explicitly. + mExportProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE, + mPeople.getString(android.R.string.cancel), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (DEBUG) { + Log.d(TAG, "Cancel exporting contacts by click button"); + } + canceled = true; + } + }); + + mExportProgressDlg.show(); + } + } + + public ImportFromSimSelectListener listener; + /** + * Create a {@link Dialog} that allows the user to pick from a bulk import + * or bulk export task across all contacts. + */ + private Dialog displayImportExportDialog(int id, Bundle bundle) { + Dialog diag; + switch (id) { + case R.string.import_from_sim_select: { + listener = new ImportFromSimSelectListener(); + showSimSelectDialog(); + break; + } + case R.string.export_to_sim: { + String[] items = new String[TelephonyManager.getDefault().getPhoneCount()]; + for (int i = 0; i < items.length; i++) { + items[i] = getString(R.string.export_to_sim) + ": " + + MoreContactUtils.getMultiSimAliasesName(mActivity, i); + } + mExportSub = SimContactsConstants.SUB_1; + ExportToSimSelectListener listener = new ExportToSimSelectListener(); + return new AlertDialog.Builder(getActivity()) + .setTitle(R.string.export_to_sim) + .setPositiveButton(android.R.string.ok, listener) + .setSingleChoiceItems(items, 0, listener).create(); + } + } + return null; + } + + public void showSimSelectDialog() { + AccountSelectionUtil.setImportSubscription(SimContactsConstants.SUB_1); + // item is for sim account to show + String[] items = new String[TelephonyManager.getDefault().getPhoneCount()]; + for (int i = 0; i < items.length; i++) { + items[i] = getString(R.string.import_from_sim) + ": " + + MoreContactUtils.getMultiSimAliasesName(mActivity, i); + } + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.import_from_sim) + .setPositiveButton(android.R.string.ok, listener) + .setSingleChoiceItems(items, 0, listener).create().show(); + } + + private void handleExportToSimRequest(int Id) { + if (MoreContactUtils.getEnabledSimCount() >1) { + //has two enalbed sim cards, prompt dialog to select one + displayImportExportDialog(Id, null).show(); + } else { + mExportSub = getEnabledIccCard(); + Intent pickPhoneIntent = new Intent( + SimContactsConstants.ACTION_MULTI_PICK, Contacts.CONTENT_URI); + // do not show the contacts in SIM card + pickPhoneIntent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER, + ContactListFilter + .createFilterWithType(ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS)); + pickPhoneIntent.putExtra(EXT_NOT_SHOW_SIM_FLAG, true); + pickPhoneIntent.putExtra(SimContactsConstants.IS_CONTACT,true); + mActivity.startActivityForResult(pickPhoneIntent, SUBACTIVITY_MULTI_PICK_CONTACT); + } + } + + private boolean hasEnabledIccCard(int subscription) { + return TelephonyManager.getDefault().hasIccCard(subscription) + && TelephonyManager.getDefault().getSimState(subscription) + == TelephonyManager.SIM_STATE_READY; + } + + private int getEnabledIccCard() { + for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { + if (hasEnabledIccCard(i)) { + return i; + } + } + return SimContactsConstants.SUB_1; + } + private CharSequence getSubDescription(SubscriptionInfo record) { CharSequence name = record.getDisplayName(); if (TextUtils.isEmpty(record.getNumber())) { diff --git a/src/com/android/contacts/common/interactions/ImportSIMContactsDialogFragment.java b/src/com/android/contacts/common/interactions/ImportSIMContactsDialogFragment.java new file mode 100644 index 00000000..a54f791a --- /dev/null +++ b/src/com/android/contacts/common/interactions/ImportSIMContactsDialogFragment.java @@ -0,0 +1,36 @@ +package com.android.contacts.common.interactions; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.os.Bundle; +import com.android.contacts.common.R; + +/** + * An dialog invoked to import/export contacts. + */ +public class ImportSIMContactsDialogFragment extends DialogFragment { + public static final String TAG = "ImportSIMContactsDialogFragment"; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Use the Builder class for convenient dialog construction + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(R.string.import_contacts_sim) + .setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + ImportExportDialogFragment.show(getFragmentManager(), + false, ImportSIMContactsDialogFragment.class); + }}) + .setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // Nothing to do + dismiss(); + }}); + // Create the AlertDialog object and return it + return builder.create(); + } +} diff --git a/src/com/android/contacts/common/lettertiles/LetterTileDrawable.java b/src/com/android/contacts/common/lettertiles/LetterTileDrawable.java index e62d4218..34d3d457 100644 --- a/src/com/android/contacts/common/lettertiles/LetterTileDrawable.java +++ b/src/com/android/contacts/common/lettertiles/LetterTileDrawable.java @@ -16,6 +16,8 @@ package com.android.contacts.common.lettertiles; +import android.accounts.Account; +import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; @@ -28,8 +30,11 @@ import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.text.TextUtils; +import android.telephony.TelephonyManager; import android.util.Log; +import com.android.contacts.common.MoreContactUtils; +import com.android.contacts.common.model.account.SimAccountType; import com.android.contacts.common.R; import com.android.contacts.common.util.BitmapUtil; @@ -53,6 +58,9 @@ public class LetterTileDrawable extends Drawable { private static Bitmap DEFAULT_PERSON_AVATAR; private static Bitmap DEFAULT_BUSINESS_AVATAR; private static Bitmap DEFAULT_VOICEMAIL_AVATAR; + private static Bitmap DEFAULT_SIM_PERSON_AVATAR; + private static Bitmap[] DEFAULT_CUSTOMIZE_SIM_PERSON_AVATAR = + new Bitmap[MoreContactUtils.IC_SIM_PICTURE.length]; /** Reusable components to avoid new allocations */ private static final Paint sPaint = new Paint(); @@ -71,11 +79,17 @@ public class LetterTileDrawable extends Drawable { private float mScale = 1.0f; private float mOffset = 0.0f; private boolean mIsCircle = false; + private Account mAccount; + private Context mContext; - public LetterTileDrawable(final Resources res) { + + public LetterTileDrawable(final Context context, final Account account) { mPaint = new Paint(); mPaint.setFilterBitmap(true); mPaint.setDither(true); + mAccount = account; + mContext = context; + Resources res = context.getResources(); if (sColors == null) { sColors = res.obtainTypedArray(R.array.letter_tile_colors); @@ -88,6 +102,13 @@ public class LetterTileDrawable extends Drawable { R.drawable.ic_business_white_120dp); DEFAULT_VOICEMAIL_AVATAR = BitmapFactory.decodeResource(res, R.drawable.ic_voicemail_avatar); + DEFAULT_SIM_PERSON_AVATAR = BitmapFactory.decodeResource(res, + R.drawable.ic_contact_picture_sim); + for (int i = 0; i < MoreContactUtils.IC_SIM_PICTURE.length; i++) { + DEFAULT_CUSTOMIZE_SIM_PERSON_AVATAR[i] = BitmapFactory + .decodeResource(res, MoreContactUtils.IC_SIM_PICTURE[i]); + } + sPaint.setTypeface(Typeface.create( res.getString(R.string.letter_tile_letter_font_family), Typeface.NORMAL)); sPaint.setTextAlign(Align.CENTER); @@ -143,7 +164,9 @@ public class LetterTileDrawable extends Drawable { } // Draw letter/digit only if the first character is an english letter - if (mDisplayName != null && isEnglishLetter(mDisplayName.charAt(0))) { + if (mDisplayName != null + && isEnglishLetter(mDisplayName.charAt(0)) + && (mAccount == null || (!mAccount.type.equals(SimAccountType.ACCOUNT_TYPE)))) { // Draw letter or digit. sFirstChar[0] = Character.toUpperCase(mDisplayName.charAt(0)); @@ -160,9 +183,9 @@ public class LetterTileDrawable extends Drawable { sPaint); } else { // Draw the default image if there is no letter/digit to be drawn - final Bitmap bitmap = getBitmapForContactType(mContactType); - drawBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), - canvas); + final Bitmap bitmap = getBitmapForContactType(mContactType, + mAccount, mContext); + drawBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), canvas); } } @@ -184,7 +207,21 @@ public class LetterTileDrawable extends Drawable { return sColors.getColor(color, sDefaultColor); } - private static Bitmap getBitmapForContactType(int contactType) { + private static Bitmap getBitmapForContactType(int contactType, + Account account, Context context) { + if (account != null && SimAccountType.ACCOUNT_TYPE.equals(account.type)) { + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + final int sub = MoreContactUtils.getSubscription( + SimAccountType.ACCOUNT_TYPE, account.name); + int index = MoreContactUtils.getCurrentSimIconIndex(context, sub); + if (index < 0) { + return DEFAULT_SIM_PERSON_AVATAR; + } + return DEFAULT_CUSTOMIZE_SIM_PERSON_AVATAR[index]; + } else { + return DEFAULT_SIM_PERSON_AVATAR; + } + } switch (contactType) { case TYPE_PERSON: return DEFAULT_PERSON_AVATAR; diff --git a/src/com/android/contacts/common/list/AccountFilterActivity.java b/src/com/android/contacts/common/list/AccountFilterActivity.java index 58450c65..9dba5362 100644..100755 --- a/src/com/android/contacts/common/list/AccountFilterActivity.java +++ b/src/com/android/contacts/common/list/AccountFilterActivity.java @@ -120,7 +120,8 @@ public class AccountFilterActivity extends Activity implements AdapterView.OnIte // Hide extensions with no raw_contacts. continue; } - Drawable icon = accountType != null ? accountType.getDisplayIcon(context) : null; + Drawable icon = accountType != null ? accountType.getDisplayIcon( + context, account.name) : null; accountFilters.add(ContactListFilter.createAccountFilter( account.type, account.name, account.dataSet, icon)); } diff --git a/src/com/android/contacts/common/list/ContactEntry.java b/src/com/android/contacts/common/list/ContactEntry.java index 43fc19dd..66ae50d1 100644 --- a/src/com/android/contacts/common/list/ContactEntry.java +++ b/src/com/android/contacts/common/list/ContactEntry.java @@ -16,6 +16,7 @@ package com.android.contacts.common.list; +import android.accounts.Account; import android.graphics.drawable.Drawable; import android.net.Uri; import android.provider.ContactsContract.PinnedPositions; @@ -36,6 +37,7 @@ public class ContactEntry { public int pinned = PinnedPositions.UNPINNED; public boolean isFavorite = false; public boolean isDefaultNumber = false; + public Account account; public static final ContactEntry BLANK_ENTRY = new ContactEntry(); }
\ No newline at end of file diff --git a/src/com/android/contacts/common/list/ContactEntryListAdapter.java b/src/com/android/contacts/common/list/ContactEntryListAdapter.java index 4d7eb197..26f13f3d 100644..100755 --- a/src/com/android/contacts/common/list/ContactEntryListAdapter.java +++ b/src/com/android/contacts/common/list/ContactEntryListAdapter.java @@ -15,6 +15,7 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.content.Context; import android.content.CursorLoader; import android.content.res.Resources; @@ -62,6 +63,7 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter { private boolean mCircularPhotos = true; private boolean mQuickContactEnabled; private boolean mAdjustSelectionBoundsEnabled; + private boolean mQuickCallButtonEnabled; /** * indicates if contact queries include profile @@ -346,6 +348,10 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter { return mQuickContactEnabled; } + public boolean isQuickCallButtonEnabled() { + return mQuickCallButtonEnabled; + } + public void setQuickContactEnabled(boolean quickContactEnabled) { mQuickContactEnabled = quickContactEnabled; } @@ -358,6 +364,10 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter { mAdjustSelectionBoundsEnabled = enabled; } + public void setQuickCallButtonEnabled(boolean quickCallButtonEnabled) { + mQuickCallButtonEnabled = quickCallButtonEnabled; + } + public boolean shouldIncludeProfile() { return mIncludeProfile; } @@ -710,22 +720,31 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter { * @param contactIdColumn Index of the contact id column * @param lookUpKeyColumn Index of the lookup key column * @param displayNameColumn Index of the display name column + * @param accountTypeColumn Index of the account type column + * @param accountNameColumn Index of the account name column */ protected void bindQuickContact(final ContactListItemView view, int partitionIndex, Cursor cursor, int photoIdColumn, int photoUriColumn, int contactIdColumn, - int lookUpKeyColumn, int displayNameColumn) { + int lookUpKeyColumn,int displayNameColumn, int accountTypeColumn, + int accountNameColumn) { long photoId = 0; if (!cursor.isNull(photoIdColumn)) { photoId = cursor.getLong(photoIdColumn); } + Account account = null; + if (!cursor.isNull(accountTypeColumn) && !cursor.isNull(accountNameColumn)) { + final String accountType = cursor.getString(accountTypeColumn); + final String accountName = cursor.getString(accountNameColumn); + account = new Account(accountName, accountType); + } QuickContactBadge quickContact = view.getQuickContact(); quickContact.assignContactUri( getContactUri(partitionIndex, cursor, contactIdColumn, lookUpKeyColumn)); if (photoId != 0 || photoUriColumn == -1) { - getPhotoLoader().loadThumbnail(quickContact, photoId, mDarkTheme, mCircularPhotos, - null); + getPhotoLoader().loadThumbnail(quickContact, photoId, account, + mDarkTheme, mCircularPhotos, null); } else { final String photoUriString = cursor.getString(photoUriColumn); final Uri photoUri = photoUriString == null ? null : Uri.parse(photoUriString); @@ -734,8 +753,8 @@ public abstract class ContactEntryListAdapter extends IndexerListAdapter { request = getDefaultImageRequestFromCursor(cursor, displayNameColumn, lookUpKeyColumn); } - getPhotoLoader().loadPhoto(quickContact, photoUri, -1, mDarkTheme, mCircularPhotos, - request); + getPhotoLoader().loadPhoto(quickContact, photoUri, account, -1, + mDarkTheme, mCircularPhotos, request); } } diff --git a/src/com/android/contacts/common/list/ContactEntryListFragment.java b/src/com/android/contacts/common/list/ContactEntryListFragment.java index c38e9693..c7204931 100644..100755 --- a/src/com/android/contacts/common/list/ContactEntryListFragment.java +++ b/src/com/android/contacts/common/list/ContactEntryListFragment.java @@ -20,9 +20,11 @@ import android.app.Activity; import android.app.Fragment; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.CursorLoader; import android.content.Intent; +import android.content.IntentFilter; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; @@ -48,6 +50,8 @@ import com.android.common.widget.CompositeCursorAdapter.Partition; import com.android.contacts.common.ContactPhotoManager; import com.android.contacts.common.preference.ContactsPreferences; import com.android.contacts.common.util.ContactListViewUtils; +import com.android.contacts.common.util.SchedulingUtils; +import com.android.internal.telephony.TelephonyIntents; import java.util.Locale; @@ -70,6 +74,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter private static final String KEY_QUICK_CONTACT_ENABLED = "quickContactEnabled"; private static final String KEY_ADJUST_SELECTION_BOUNDS_ENABLED = "adjustSelectionBoundsEnabled"; + private static final String KEY_QUICK_CALL_BUTTON_ENABLED = "quickCallButtonEnabled"; private static final String KEY_INCLUDE_PROFILE = "includeProfile"; private static final String KEY_SEARCH_MODE = "searchMode"; private static final String KEY_VISIBLE_SCROLLBAR_ENABLED = "visibleScrollbarEnabled"; @@ -95,6 +100,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter private boolean mPhotoLoaderEnabled; private boolean mQuickContactEnabled = true; private boolean mAdjustSelectionBoundsEnabled = true; + private boolean mQuickCallButtonEnabled = false; private boolean mIncludeProfile; private boolean mSearchMode; private boolean mVisibleScrollbarEnabled; @@ -145,6 +151,13 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter private LoaderManager mLoaderManager; + private BroadcastReceiver mSIMStateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context arg0, Intent arg1) { + reloadData(); + } + }; + private Handler mDelayedDirectorySearchHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -229,6 +242,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter outState.putBoolean(KEY_PHOTO_LOADER_ENABLED, mPhotoLoaderEnabled); outState.putBoolean(KEY_QUICK_CONTACT_ENABLED, mQuickContactEnabled); outState.putBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED, mAdjustSelectionBoundsEnabled); + outState.putBoolean(KEY_QUICK_CALL_BUTTON_ENABLED, mQuickCallButtonEnabled); outState.putBoolean(KEY_INCLUDE_PROFILE, mIncludeProfile); outState.putBoolean(KEY_SEARCH_MODE, mSearchMode); outState.putBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED, mVisibleScrollbarEnabled); @@ -251,6 +265,14 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter restoreSavedState(savedState); mAdapter = createListAdapter(); mContactsPrefs = new ContactsPreferences(mContext); + restoreSavedState(savedState); + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); + filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); + if (mContext != null) { + mContext.registerReceiver(mSIMStateReceiver, filter); + } } public void restoreSavedState(Bundle savedState) { @@ -262,6 +284,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter mPhotoLoaderEnabled = savedState.getBoolean(KEY_PHOTO_LOADER_ENABLED); mQuickContactEnabled = savedState.getBoolean(KEY_QUICK_CONTACT_ENABLED); mAdjustSelectionBoundsEnabled = savedState.getBoolean(KEY_ADJUST_SELECTION_BOUNDS_ENABLED); + mQuickCallButtonEnabled = savedState.getBoolean(KEY_QUICK_CALL_BUTTON_ENABLED); mIncludeProfile = savedState.getBoolean(KEY_INCLUDE_PROFILE); mSearchMode = savedState.getBoolean(KEY_SEARCH_MODE); mVisibleScrollbarEnabled = savedState.getBoolean(KEY_VISIBLE_SCROLLBAR_ENABLED); @@ -315,6 +338,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter // Next time this method is called, we should start loading non-priority directories mLoadPriorityDirectoriesOnly = false; + mAdapter.notifyDataSetChanged(); } @Override @@ -374,6 +398,9 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter protected void loadDirectoryPartition(int partitionIndex, DirectoryPartition partition) { Bundle args = new Bundle(); args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId()); + if (getLoaderManager().getLoader(partitionIndex) != null) { + getLoaderManager().destroyLoader(partitionIndex); + } getLoaderManager().restartLoader(partitionIndex, args, this); } @@ -415,6 +442,11 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter } public void onLoaderReset(Loader<Cursor> loader) { + if (loader.getId() >= 0) { + mAdapter.changeCursor(loader.getId(), null); + } else { + mAdapter.changeCursor(null); + } } protected void onPartitionLoaded(int partitionIndex, Cursor data) { @@ -457,6 +489,14 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter mAdapter.clearPartitions(); } + @Override + public void onDestroy() { + super.onDestroy(); + if (mContext != null) { + mContext.unregisterReceiver(mSIMStateReceiver); + } + } + protected void reloadData() { removePendingDirectorySearchRequests(); mAdapter.onDataReload(); @@ -551,6 +591,10 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter mAdjustSelectionBoundsEnabled = flag; } + public void setQuickCallButtonEnabled(boolean flag) { + this.mQuickCallButtonEnabled = flag; + } + public void setIncludeProfile(boolean flag) { mIncludeProfile = flag; if(mAdapter != null) { @@ -773,6 +817,7 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter mAdapter.setQuickContactEnabled(mQuickContactEnabled); mAdapter.setAdjustSelectionBoundsEnabled(mAdjustSelectionBoundsEnabled); + mAdapter.setQuickCallButtonEnabled(mQuickCallButtonEnabled); mAdapter.setIncludeProfile(mIncludeProfile); mAdapter.setQueryString(mQueryString); mAdapter.setDirectorySearchMode(mDirectorySearchMode); @@ -869,8 +914,9 @@ public abstract class ContactEntryListFragment<T extends ContactEntryListAdapter new ContactsPreferences.ChangeListener() { @Override public void onChange() { - loadPreferences(); - reloadData(); + if(loadPreferences()) { + reloadData(); + } } }; diff --git a/src/com/android/contacts/common/list/ContactListAdapter.java b/src/com/android/contacts/common/list/ContactListAdapter.java index 9107d044..ea2d8539 100644..100755 --- a/src/com/android/contacts/common/list/ContactListAdapter.java +++ b/src/com/android/contacts/common/list/ContactListAdapter.java @@ -15,22 +15,27 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.content.Context; +import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Directory; +import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.SearchSnippets; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; +import android.widget.Toast; import com.android.contacts.common.ContactPhotoManager; import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest; import com.android.contacts.common.R; import com.android.contacts.common.preference.ContactsPreferences; +import com.android.contacts.common.model.Contact; /** * A cursor adapter for the {@link ContactsContract.Contacts#CONTENT_TYPE} content type. @@ -49,6 +54,9 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { Contacts.PHOTO_THUMBNAIL_URI, // 5 Contacts.LOOKUP_KEY, // 6 Contacts.IS_USER_PROFILE, // 7 + RawContacts.ACCOUNT_TYPE, // 8 + RawContacts.ACCOUNT_NAME, // 9 + Contacts.HAS_PHONE_NUMBER, // 10 }; private static final String[] CONTACT_PROJECTION_ALTERNATIVE = new String[] { @@ -60,6 +68,9 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { Contacts.PHOTO_THUMBNAIL_URI, // 5 Contacts.LOOKUP_KEY, // 6 Contacts.IS_USER_PROFILE, // 7 + RawContacts.ACCOUNT_TYPE, // 8 + RawContacts.ACCOUNT_NAME, // 9 + Contacts.HAS_PHONE_NUMBER, // 10 }; private static final String[] FILTER_PROJECTION_PRIMARY = new String[] { @@ -71,7 +82,10 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { Contacts.PHOTO_THUMBNAIL_URI, // 5 Contacts.LOOKUP_KEY, // 6 Contacts.IS_USER_PROFILE, // 7 - SearchSnippets.SNIPPET, // 8 + RawContacts.ACCOUNT_TYPE, // 8 + RawContacts.ACCOUNT_NAME, // 9 + Contacts.HAS_PHONE_NUMBER, // 10 + SearchSnippets.SNIPPET, // 11 }; private static final String[] FILTER_PROJECTION_ALTERNATIVE = new String[] { @@ -83,7 +97,10 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { Contacts.PHOTO_THUMBNAIL_URI, // 5 Contacts.LOOKUP_KEY, // 6 Contacts.IS_USER_PROFILE, // 7 - SearchSnippets.SNIPPET, // 8 + RawContacts.ACCOUNT_TYPE, // 8 + RawContacts.ACCOUNT_NAME, // 9 + Contacts.HAS_PHONE_NUMBER, // 10 + SearchSnippets.SNIPPET, // 11 }; public static final int CONTACT_ID = 0; @@ -94,7 +111,10 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { public static final int CONTACT_PHOTO_URI = 5; public static final int CONTACT_LOOKUP_KEY = 6; public static final int CONTACT_IS_USER_PROFILE = 7; - public static final int CONTACT_SNIPPET = 8; + public static final int CONTACT_ACCOUNT_TYPE = 8; + public static final int CONTACT_ACCOUNT_NAME = 9; + public static final int CONTACT_HAS_NUMBER = 10; + public static final int CONTACT_SNIPPET = 11; } private CharSequence mUnknownNameText; @@ -200,6 +220,7 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { view.setUnknownNameText(mUnknownNameText); view.setQuickContactEnabled(isQuickContactEnabled()); view.setAdjustSelectionBoundsEnabled(isAdjustSelectionBoundsEnabled()); + view.setQuickCallButtonEnabled(isQuickCallButtonEnabled()); view.setActivatedStateSupported(isSelectionVisible()); if (mPhotoPosition != null) { view.setPhotoPosition(mPhotoPosition); @@ -207,6 +228,29 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { return view; } + private View.OnClickListener mClickListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + String lookup = ((ContactListItemView) view.getParent()).getQuickCallLookup(); + Cursor cursor = mContext.getContentResolver().query( + ContactsContract.CommonDataKinds.Phone.CONTENT_URI, + new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER, + ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY}, + ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY + "=?", + new String[] { lookup }, null); + + if (cursor != null) { + if (cursor.moveToNext()) { + String phoneNumber = cursor.getString(0); + Uri uri = Uri.parse("tel: " + phoneNumber); + Intent intent = new Intent(Intent.ACTION_CALL, uri); + mContext.startActivity(intent); + } + cursor.close(); + } + } + }; + protected void bindSectionHeaderAndDivider(ContactListItemView view, int position, Cursor cursor) { view.setIsSectionHeaderEnabled(isSectionHeaderDisplayEnabled()); @@ -230,8 +274,15 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { photoId = cursor.getLong(ContactQuery.CONTACT_PHOTO_ID); } + Account account = null; + if (!cursor.isNull(ContactQuery.CONTACT_ACCOUNT_TYPE) + && !cursor.isNull(ContactQuery.CONTACT_ACCOUNT_NAME)) { + final String accountType = cursor.getString(ContactQuery.CONTACT_ACCOUNT_TYPE); + final String accountName = cursor.getString(ContactQuery.CONTACT_ACCOUNT_NAME); + account = new Account(accountName, accountType); + } if (photoId != 0) { - getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false, + getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, account, false, getCircularPhotos(), null); } else { final String photoUriString = cursor.getString(ContactQuery.CONTACT_PHOTO_URI); @@ -242,7 +293,7 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { ContactQuery.CONTACT_DISPLAY_NAME, ContactQuery.CONTACT_LOOKUP_KEY); } - getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false, + getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, account, false, getCircularPhotos(), request); } } @@ -255,6 +306,12 @@ public abstract class ContactListAdapter extends ContactEntryListAdapter { bindViewId(view, cursor, ContactQuery.CONTACT_ID); } + protected void bindQuickCallView(final ContactListItemView view, Cursor cursor) { + view.showQuickCallView(cursor, ContactQuery.CONTACT_HAS_NUMBER, + ContactQuery.CONTACT_LOOKUP_KEY, ContactQuery.CONTACT_IS_USER_PROFILE); + view.setOnQuickCallClickListener(mClickListener); + } + protected void bindPresenceAndStatusMessage(final ContactListItemView view, Cursor cursor) { view.showPresenceAndStatusMessage(cursor, ContactQuery.CONTACT_PRESENCE_STATUS, ContactQuery.CONTACT_CONTACT_STATUS); diff --git a/src/com/android/contacts/common/list/ContactListFilter.java b/src/com/android/contacts/common/list/ContactListFilter.java index f81ea742..b48efb98 100644..100755 --- a/src/com/android/contacts/common/list/ContactListFilter.java +++ b/src/com/android/contacts/common/list/ContactListFilter.java @@ -45,6 +45,7 @@ public final class ContactListFilter implements Comparable<ContactListFilter>, P * TODO: "group" filter and relevant variables are all obsolete. Remove them. */ private static final int FILTER_TYPE_GROUP = 1; + public static final int FILTER_TYPE_ALL_WITHOUT_SIM = 2; private static final String KEY_FILTER_TYPE = "filter.type"; private static final String KEY_ACCOUNT_NAME = "filter.accountName"; diff --git a/src/com/android/contacts/common/list/ContactListFilterView.java b/src/com/android/contacts/common/list/ContactListFilterView.java index 4cea7558..075f1fb6 100644..100755 --- a/src/com/android/contacts/common/list/ContactListFilterView.java +++ b/src/com/android/contacts/common/list/ContactListFilterView.java @@ -28,6 +28,8 @@ import android.widget.TextView; import com.android.contacts.common.R; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.account.AccountType; +import com.android.contacts.common.model.account.PhoneAccountType; +import com.android.contacts.common.model.account.SimAccountType; /** * Contact list filter parameters. @@ -113,7 +115,13 @@ public class ContactListFilterView extends LinearLayout { break; } case ContactListFilter.FILTER_TYPE_ACCOUNT: { - mAccountUserName.setVisibility(View.VISIBLE); + if (SimAccountType.ACCOUNT_TYPE.equals(mFilter.accountType) + || PhoneAccountType.ACCOUNT_TYPE + .equals(mFilter.accountType)) { + mAccountUserName.setVisibility(View.GONE); + } else { + mAccountUserName.setVisibility(View.VISIBLE); + } mIcon.setVisibility(View.VISIBLE); if (mFilter.icon != null) { mIcon.setImageDrawable(mFilter.icon); @@ -123,7 +131,7 @@ public class ContactListFilterView extends LinearLayout { final AccountType accountType = accountTypes.getAccountType(mFilter.accountType, mFilter.dataSet); mAccountUserName.setText(mFilter.accountName); - mAccountType.setText(accountType.getDisplayLabel(getContext())); + mAccountType.setText(accountType.getDisplayLabel(getContext(),mFilter.accountName)); break; } } diff --git a/src/com/android/contacts/common/list/ContactListItemView.java b/src/com/android/contacts/common/list/ContactListItemView.java index 4c561dfc..dd869b0c 100644..100755 --- a/src/com/android/contacts/common/list/ContactListItemView.java +++ b/src/com/android/contacts/common/list/ContactListItemView.java @@ -26,6 +26,7 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; @@ -52,6 +53,8 @@ import com.android.contacts.common.format.TextHighlighter; import com.android.contacts.common.util.ContactDisplayUtils; import com.android.contacts.common.util.SearchUtil; import com.android.contacts.common.util.ViewUtil; +import com.android.contacts.common.widget.CheckableImageView; +import com.android.contacts.common.widget.CheckableQuickContactBadge; import com.google.common.collect.Lists; @@ -77,7 +80,7 @@ import java.util.regex.Pattern; */ public class ContactListItemView extends ViewGroup - implements SelectionBoundsAdjuster { + implements SelectionBoundsAdjuster, View.OnClickListener { // Style values for layout and appearance // The initialized values are defaults if none is provided through xml. @@ -136,7 +139,7 @@ public class ContactListItemView extends ViewGroup final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale); switch (layoutDirection) { case View.LAYOUT_DIRECTION_RTL: - return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT); + return (PhotoPosition.RIGHT); case View.LAYOUT_DIRECTION_LTR: default: return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT); @@ -151,8 +154,10 @@ public class ContactListItemView extends ViewGroup // The views inside the contact view private boolean mQuickContactEnabled = true; - private QuickContactBadge mQuickContact; - private ImageView mPhotoView; + private boolean mQuickCallButtonEnabled = false; + private CheckableQuickContactBadge mQuickContact; + private ImageView mQuickCallView; + private CheckableImageView mPhotoView; private TextView mNameTextView; private TextView mPhoneticNameTextView; private TextView mLabelView; @@ -160,12 +165,15 @@ public class ContactListItemView extends ViewGroup private TextView mSnippetView; private TextView mStatusView; private ImageView mPresenceIcon; + private String mQuickCallKey; private ColorStateList mSecondaryTextColor; - + private int mQuickCallViewImageId = 0; + private int mQuickCallViewBgId = 0; private int mDefaultPhotoViewSize = 0; + private int mDefaultQuickCallViewSize = 0; /** * Can be effective even when {@link #mPhotoView} is null, as we want to have horizontal padding * to align other data in this View. @@ -177,6 +185,15 @@ public class ContactListItemView extends ViewGroup private int mPhotoViewHeight; /** + * Only effective when {@link #mQuickCallView} is null + */ + private int mQuickCallViewWidth; + /** + * Only effective when {@link #mQuickCallView} is null + */ + private int mQuickCallViewHeight; + + /** * Only effective when {@link #mPhotoView} is null. * When true all the Views on the right side of the photo should have horizontal padding on * those left assuming there is a photo. @@ -219,6 +236,8 @@ public class ContactListItemView extends ViewGroup private Rect mBoundsWithoutHeader = new Rect(); + private OnClickListener mListener; + /** A helper used to highlight a prefix in a text field. */ private final TextHighlighter mTextHighlighter; private CharSequence mUnknownNameText; @@ -226,7 +245,9 @@ public class ContactListItemView extends ViewGroup public ContactListItemView(Context context) { super(context); - mTextHighlighter = new TextHighlighter(Typeface.BOLD); + mTextHighlighter = new TextHighlighter(Typeface.BOLD, + context.getResources().getColor(R.color.text_highlight_color)); + mNameHighlightSequence = new ArrayList<HighlightSequence>(); mNumberHighlightSequence = new ArrayList<HighlightSequence>(); } @@ -254,6 +275,9 @@ public class ContactListItemView extends ViewGroup R.styleable.ContactListItemView_list_item_presence_icon_size, mPresenceIconSize); mDefaultPhotoViewSize = a.getDimensionPixelOffset( R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize); + mDefaultQuickCallViewSize = a.getDimensionPixelOffset( + R.styleable.ContactListItemView_list_item_quick_call_size, + mDefaultQuickCallViewSize); mTextIndent = a.getDimensionPixelOffset( R.styleable.ContactListItemView_list_item_text_indent, mTextIndent); mTextOffsetTop = a.getDimensionPixelOffset( @@ -268,6 +292,12 @@ public class ContactListItemView extends ViewGroup mNameTextViewTextSize = (int) a.getDimension( R.styleable.ContactListItemView_list_item_name_text_size, (int) getResources().getDimension(R.dimen.contact_browser_list_item_text_size)); + mQuickCallViewImageId = a.getResourceId( + R.styleable.ContactListItemView_list_item_quick_call_view_source, + R.drawable.ic_action_call); + mQuickCallViewBgId = a.getResourceId( + R.styleable.ContactListItemView_list_item_quick_call_view_background, + R.drawable.ic_action_call_background); setPaddingRelative( a.getDimensionPixelOffset( @@ -279,7 +309,9 @@ public class ContactListItemView extends ViewGroup a.getDimensionPixelOffset( R.styleable.ContactListItemView_list_item_padding_bottom, 0)); - mTextHighlighter = new TextHighlighter(Typeface.BOLD); + mTextHighlighter = new TextHighlighter(Typeface.BOLD, + context.getResources().getColor(R.color.text_highlight_color)); + a.recycle(); @@ -308,6 +340,22 @@ public class ContactListItemView extends ViewGroup mQuickContactEnabled = flag; } + public void setQuickCallButtonEnabled(boolean flag) { + mQuickCallButtonEnabled = flag; + } + + public void setQuickCallLookup(String lookupKey) { + mQuickCallKey = lookupKey; + } + + public void setQuickCallButtonImageResource(int resourceId) { + mQuickCallViewImageId = resourceId; + } + + public void setQuickCallButtonBackgroundResource(int resourceId) { + mQuickCallViewBgId = resourceId; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // We will match parent's width and wrap content vertically, but make sure @@ -324,15 +372,16 @@ public class ContactListItemView extends ViewGroup mStatusTextViewHeight = 0; ensurePhotoViewSize(); + ensureQuickCallViewSize(); // Width each TextView is able to use. int effectiveWidth; // All the other Views will honor the photo, so available width for them may be shrunk. if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) { effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight() - - (mPhotoViewWidth + mGapBetweenImageAndText); + - (mPhotoViewWidth + mGapBetweenImageAndText + mQuickCallViewWidth); } else { - effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight(); + effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight() - mQuickCallViewWidth; } if (mIsSectionHeaderEnabled) { @@ -450,6 +499,12 @@ public class ContactListItemView extends ViewGroup MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); } + if (isVisible(mQuickCallView)) { + mQuickCallView.measure( + MeasureSpec.makeMeasureSpec(mQuickCallViewWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(mQuickCallViewHeight, MeasureSpec.EXACTLY)); + } + setMeasuredDimension(specWidth, height); } @@ -551,6 +606,9 @@ public class ContactListItemView extends ViewGroup textTopBound += mNameTextViewHeight; } + // Center the photo vertically + final int quickCallTop = topBound + (bottomBound - topBound - mQuickCallViewHeight) / 2; + // Presence and status if (isLayoutRtl) { int statusRightBound = rightBound; @@ -570,6 +628,13 @@ public class ContactListItemView extends ViewGroup statusRightBound, textTopBound + mStatusTextViewHeight); } + + if (isVisible(mQuickCallView)) { + mQuickCallView.layout(-width + (mQuickCallViewWidth + mPhotoViewWidth), + quickCallTop, + rightBound, + quickCallTop + mQuickCallViewHeight); + } } else { int statusLeftBound = leftBound; if (isVisible(mPresenceIcon)) { @@ -588,6 +653,13 @@ public class ContactListItemView extends ViewGroup rightBound, textTopBound + mStatusTextViewHeight); } + + if (isVisible(mQuickCallView)) { + mQuickCallView.layout(rightBound - mQuickCallView.getMeasuredWidth(), + quickCallTop, + rightBound, + quickCallTop + mQuickCallViewHeight); + } } if (isVisible(mStatusView) || isVisible(mPresenceIcon)) { @@ -675,10 +747,33 @@ public class ContactListItemView extends ViewGroup } } + /** + * Extracts width and height from the style + */ + private void ensureQuickCallViewSize() { + mQuickCallViewWidth = mQuickCallViewHeight = getDefaultQuickCallViewSize(); + if (!mQuickCallButtonEnabled || mQuickCallView == null) { + mQuickCallViewWidth = 0; + mQuickCallViewHeight = 0; + } + } + + protected void setDefaultPhotoViewSize(int pixels) { + mDefaultPhotoViewSize = pixels; + } + protected int getDefaultPhotoViewSize() { return mDefaultPhotoViewSize; } + protected void setDefaultQuickCallViewSize(int pixels) { + mDefaultQuickCallViewSize = pixels; + } + + protected int getDefaultQuickCallViewSize() { + return mDefaultQuickCallViewSize; + } + /** * Gets a LayoutParam that corresponds to the default photo size. * @@ -746,6 +841,14 @@ public class ContactListItemView extends ViewGroup } /** + * Get the quick call lookup to use with Intent.ACTION_CALL + * @return + */ + public String getQuickCallLookup() { + return mQuickCallKey; + } + + /** * Returns the quick contact badge, creating it if necessary. */ public QuickContactBadge getQuickContact() { @@ -753,7 +856,7 @@ public class ContactListItemView extends ViewGroup throw new IllegalStateException("QuickContact is disabled for this view"); } if (mQuickContact == null) { - mQuickContact = new QuickContactBadge(getContext()); + mQuickContact = new CheckableQuickContactBadge(getContext()); mQuickContact.setOverlay(null); mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams()); if (mNameTextView != null) { @@ -767,12 +870,21 @@ public class ContactListItemView extends ViewGroup return mQuickContact; } + public void setChecked(boolean checked, boolean animate) { + if (mQuickContact != null) { + mQuickContact.setChecked(checked, animate); + } + if (mPhotoView != null) { + mPhotoView.setChecked(checked, animate); + } + } + /** * Returns the photo view, creating it if necessary. */ public ImageView getPhotoView() { if (mPhotoView == null) { - mPhotoView = new ImageView(getContext()); + mPhotoView = new CheckableImageView(getContext()); mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams()); // Quick contact style used above will set a background - remove it mPhotoView.setBackground(null); @@ -783,6 +895,31 @@ public class ContactListItemView extends ViewGroup } /** + * Returns the quick call view, creating it if necessary. + */ + public ImageView getQuickCallView() { + if (mQuickCallView == null) { + mQuickCallView = new ImageView(mContext); + mQuickCallView.setLayoutParams(getDefaultPhotoLayoutParams()); + mQuickCallView.setImageResource(mQuickCallViewImageId); + mQuickCallView.setBackgroundResource(mQuickCallViewBgId); + mQuickCallView.setClickable(true); + addView(mQuickCallView); + } + return mQuickCallView; + } + + /** + * Removes the quick call view. + */ + public void removeQuickCallView() { + if (mQuickCallView != null) { + removeView(mQuickCallView); + mQuickCallView = null; + } + } + + /** * Removes the photo view. */ public void removePhotoView() { @@ -1135,6 +1272,20 @@ public class ContactListItemView extends ViewGroup } } + public void showQuickCallView(Cursor cursor, int numberColumIndex, int lookUpKey, + int profileKey) { + int hasNumber = cursor.getInt(numberColumIndex); + boolean isProfile = cursor.getInt(profileKey) == 1; + if (!(hasNumber == 0) && !isProfile) { + getQuickCallView().setVisibility(View.VISIBLE); + setQuickCallLookup(cursor.getString(lookUpKey)); + } else { + if (mQuickCallView != null) { + mQuickCallView.setVisibility(View.GONE); + } + } + } + public void setDisplayName(CharSequence name, boolean highlight) { if (!TextUtils.isEmpty(name) && highlight) { clearHighlightSequences(); @@ -1463,7 +1614,27 @@ public class ContactListItemView extends ViewGroup if (mBoundsWithoutHeader.contains((int) x, (int) y) || !pointIsInView(x, y)) { return super.onTouchEvent(event); } else { - return true; + return false; + } + } + + @Override + public void onClick(View view) { + if (mListener != null && mQuickCallButtonEnabled) { + if (view == mQuickCallView) { + mListener.onClick(view); + } + } + } + + /** + * Set the a click listener for the quick call view + * @param listener + */ + public void setOnQuickCallClickListener(OnClickListener listener) { + this.mListener = listener; + if (mListener != null && mQuickCallView != null) { + mQuickCallView.setOnClickListener(mListener); } } diff --git a/src/com/android/contacts/common/list/ContactTileAdapter.java b/src/com/android/contacts/common/list/ContactTileAdapter.java index 789ca026..35f9f185 100644 --- a/src/com/android/contacts/common/list/ContactTileAdapter.java +++ b/src/com/android/contacts/common/list/ContactTileAdapter.java @@ -15,6 +15,7 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.content.ContentUris; import android.content.Context; import android.content.res.Resources; @@ -53,6 +54,11 @@ public class ContactTileAdapter extends BaseAdapter { protected int mNumFrequents; /** + * Get the layout width. + */ + private int nRTLWidth = 0; + + /** * Index of the first NON starred contact in the {@link Cursor} * Only valid when {@link DisplayType#STREQUENT} is true */ @@ -66,6 +72,8 @@ public class ContactTileAdapter extends BaseAdapter { protected int mNameIndex; protected int mPresenceIndex; protected int mStatusIndex; + private int mAccountTypeIndex; + private int mAccountNameIndex; private boolean mIsQuickContactEnabled = false; private final int mPaddingInPixels; @@ -148,6 +156,8 @@ public class ContactTileAdapter extends BaseAdapter { mStarredIndex = ContactTileLoaderFactory.STARRED; mPresenceIndex = ContactTileLoaderFactory.CONTACT_PRESENCE; mStatusIndex = ContactTileLoaderFactory.CONTACT_STATUS; + mAccountTypeIndex = ContactTileLoaderFactory.ACCOUNT_TYPE; + mAccountNameIndex = ContactTileLoaderFactory.ACCOUNT_NAME; } private static boolean cursorIsValid(Cursor cursor) { @@ -186,6 +196,9 @@ public class ContactTileAdapter extends BaseAdapter { * Else use {@link ContactTileLoaderFactory} */ public void setContactCursor(Cursor cursor) { + if (cursor == null || cursor.isClosed()) { + return; + } mContactCursor = cursor; mDividerPosition = getDividerPosition(cursor); @@ -270,6 +283,13 @@ public class ContactTileAdapter extends BaseAdapter { } contact.status = statusMessage; + if (!cursor.isNull(mAccountTypeIndex) && !cursor.isNull(mAccountTypeIndex)) { + final String accountType = cursor.getString(mAccountTypeIndex); + final String accountName = cursor.getString(mAccountNameIndex); + contact.account = new Account(accountName, accountType); + } else { + contact.account = null; + } return contact; } @@ -546,6 +566,7 @@ public class ContactTileAdapter extends BaseAdapter { protected void onLayout(boolean changed, int left, int top, int right, int bottom) { switch (mItemViewType) { case ViewTypes.STARRED: + nRTLWidth = right -left; onLayoutForTiles(); return; default: @@ -567,8 +588,15 @@ public class ContactTileAdapter extends BaseAdapter { // Note MeasuredWidth includes the padding. final int childWidth = child.getMeasuredWidth(); - child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); - childLeft += childWidth; + + // Layout for RTL + if (child.isLayoutRtl()) { + child.layout(nRTLWidth -childWidth, 0, nRTLWidth, child.getMeasuredHeight()); + nRTLWidth -= childWidth; + }else{ + child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); + childLeft += childWidth; + } } } diff --git a/src/com/android/contacts/common/list/ContactTileView.java b/src/com/android/contacts/common/list/ContactTileView.java index 56552bb6..b42ab7bf 100644 --- a/src/com/android/contacts/common/list/ContactTileView.java +++ b/src/com/android/contacts/common/list/ContactTileView.java @@ -15,6 +15,7 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.content.Context; import android.graphics.Rect; import android.net.Uri; @@ -128,7 +129,8 @@ public abstract class ContactTileView extends FrameLayout { DefaultImageRequest request = getDefaultImageRequest(entry.name, entry.lookupKey); configureViewForImage(entry.photoUri == null); if (mPhoto != null) { - mPhotoManager.loadPhoto(mPhoto, entry.photoUri, getApproximateImageSize(), + mPhotoManager.loadPhoto(mPhoto, entry.photoUri, + entry.account, getApproximateImageSize(), isDarkTheme(), isContactPhotoCircular(), request); if (mQuickContact != null) { @@ -136,7 +138,7 @@ public abstract class ContactTileView extends FrameLayout { } } else if (mQuickContact != null) { mQuickContact.assignContactUri(mLookupUri); - mPhotoManager.loadPhoto(mQuickContact, entry.photoUri, + mPhotoManager.loadPhoto(mQuickContact, entry.photoUri, entry.account, getApproximateImageSize(), isDarkTheme(), isContactPhotoCircular(), request); } diff --git a/src/com/android/contacts/common/list/ContactsSectionIndexer.java b/src/com/android/contacts/common/list/ContactsSectionIndexer.java index 8d1c9e1d..bada56c2 100644 --- a/src/com/android/contacts/common/list/ContactsSectionIndexer.java +++ b/src/com/android/contacts/common/list/ContactsSectionIndexer.java @@ -71,8 +71,10 @@ public class ContactsSectionIndexer implements SectionIndexer { } public int getPositionForSection(int section) { - if (section < 0 || section >= mSections.length) { + if (section < 0 || section > mSections.length) { return -1; + } else if (section == mSections.length) { + return mCount; } return mPositions[section]; diff --git a/src/com/android/contacts/common/list/CustomContactListFilterActivity.java b/src/com/android/contacts/common/list/CustomContactListFilterActivity.java index b3253cc3..5066b294 100644..100755 --- a/src/com/android/contacts/common/list/CustomContactListFilterActivity.java +++ b/src/com/android/contacts/common/list/CustomContactListFilterActivity.java @@ -39,6 +39,7 @@ import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.provider.ContactsContract.Groups; import android.provider.ContactsContract.Settings; +import android.text.TextUtils; import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; @@ -54,11 +55,14 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo; import android.widget.TextView; import com.android.contacts.common.R; +import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.ValuesDelta; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.model.account.GoogleAccountType; +import com.android.contacts.common.model.account.PhoneAccountType; +import com.android.contacts.common.model.account.SimAccountType; import com.android.contacts.common.util.EmptyService; import com.android.contacts.common.util.LocalizedNameResolver; import com.android.contacts.common.util.WeakAsyncTask; @@ -347,9 +351,14 @@ public class CustomContactListFilterActivity extends Activity } } else { final Integer titleRes = getAsInteger(Groups.TITLE_RES); + if (titleRes != null) { final String packageName = getAsString(Groups.RES_PACKAGE); - return context.getPackageManager().getText(packageName, titleRes, null); + if (!TextUtils.isEmpty(packageName)) { + return context.getPackageManager().getText(packageName, titleRes, null); + } else { + return getAsString(Groups.TITLE); + } } else { return getAsString(Groups.TITLE); } @@ -584,11 +593,17 @@ public class CustomContactListFilterActivity extends Activity final AccountType accountType = mAccountTypes.getAccountType( account.mType, account.mDataSet); - - text1.setText(account.mName); - text1.setVisibility(account.mName == null ? View.GONE : View.VISIBLE); - text2.setText(accountType.getDisplayLabel(mContext)); - + if (SimAccountType.ACCOUNT_TYPE.equals(account.mType) + || PhoneAccountType.ACCOUNT_TYPE.equals(account.mType)) { + text1.setVisibility(View.VISIBLE); + text1.setText(accountType.getDisplayLabel(mContext, account.mName)); + text2.setVisibility(View.GONE); + } else { + text1.setText(account.mName); + text1.setVisibility(account.mName == null ? View.GONE : View.VISIBLE); + text2.setText(accountType.getDisplayLabel(mContext, account.mName)); + text2.setVisibility(View.VISIBLE); + } return convertView; } diff --git a/src/com/android/contacts/common/list/DefaultContactListAdapter.java b/src/com/android/contacts/common/list/DefaultContactListAdapter.java index 8774777c..c44e1e28 100644..100755 --- a/src/com/android/contacts/common/list/DefaultContactListAdapter.java +++ b/src/com/android/contacts/common/list/DefaultContactListAdapter.java @@ -26,11 +26,15 @@ import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Directory; +import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.SearchSnippets; import android.text.TextUtils; import android.view.View; +import com.android.contacts.common.model.account.SimAccountType; import com.android.contacts.common.preference.ContactsPreferences; +import com.android.contacts.common.MoreContactUtils; +import com.android.contacts.common.SimContactsConstants; import java.util.ArrayList; import java.util.List; @@ -47,6 +51,21 @@ public class DefaultContactListAdapter extends ContactListAdapter { super(context); } + /** append Uri QueryParameter to filter contacts in SIM card */ + private void appendUriQueryParameterWithoutSim(CursorLoader loader, + String key, String value) { + if (null == loader || null == key || null == value) { + return; + } + + Uri uri = loader.getUri(); + if (null != uri) { + uri = uri.buildUpon().appendQueryParameter(key, value) + .appendQueryParameter(SimContactsConstants.WITHOUT_SIM_FLAG, "true").build(); + loader.setUri(uri); + } + } + @Override public void configureLoader(CursorLoader loader, long directoryId) { if (loader instanceof ProfileAndContactsLoader) { @@ -79,6 +98,21 @@ public class DefaultContactListAdapter extends ContactListAdapter { loader.setUri(builder.build()); loader.setProjection(getProjection(true)); } + boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(getContext()); + + if (isAirMode + || (null != filter && filter.filterType == + ContactListFilter.FILTER_TYPE_ALL_WITHOUT_SIM)) { + appendUriQueryParameterWithoutSim(loader, + RawContacts.ACCOUNT_TYPE, SimAccountType.ACCOUNT_TYPE); + } else { + // Do not show contacts when SIM card is disabled + String disabledSimFilter = MoreContactUtils.getDisabledSimFilter(); + if (!TextUtils.isEmpty(disabledSimFilter)) { + appendUriQueryParameterWithoutSim( + loader, RawContacts.ACCOUNT_NAME, disabledSimFilter); + } + } } else { configureUri(loader, directoryId, filter); loader.setProjection(getProjection(false)); @@ -139,10 +173,21 @@ public class DefaultContactListAdapter extends ContactListAdapter { StringBuilder selection = new StringBuilder(); List<String> selectionArgs = new ArrayList<String>(); + boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(getContext()); + String disabledSimFilter = MoreContactUtils.getDisabledSimFilter(); + switch (filter.filterType) { case ContactListFilter.FILTER_TYPE_ALL_ACCOUNTS: { // We have already added directory=0 to the URI, which takes care of this // filter + // Do not show contacts in SIM card when airplane mode is on + if (isAirMode) { + appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE, + SimAccountType.ACCOUNT_TYPE); + } else if (!TextUtils.isEmpty(disabledSimFilter)) { + appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_NAME, + disabledSimFilter); + } break; } case ContactListFilter.FILTER_TYPE_SINGLE_CONTACT: { @@ -163,12 +208,25 @@ public class DefaultContactListAdapter extends ContactListAdapter { if (isCustomFilterForPhoneNumbersOnly()) { selection.append(" AND " + Contacts.HAS_PHONE_NUMBER + "=1"); } + // Do not show contacts in SIM card when airplane mode is on + if (isAirMode) { + appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE, + SimAccountType.ACCOUNT_TYPE); + } else if (!TextUtils.isEmpty(disabledSimFilter)) { + appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_NAME, + disabledSimFilter); + } break; } case ContactListFilter.FILTER_TYPE_ACCOUNT: { // We use query parameters for account filter, so no selection to add here. break; } + case ContactListFilter.FILTER_TYPE_ALL_WITHOUT_SIM: { + appendUriQueryParameterWithoutSim(loader, RawContacts.ACCOUNT_TYPE, + SimAccountType.ACCOUNT_TYPE); + break; + } } loader.setSelection(selection.toString()); loader.setSelectionArgs(selectionArgs.toArray(new String[0])); @@ -190,7 +248,8 @@ public class DefaultContactListAdapter extends ContactListAdapter { if (isQuickContactEnabled()) { bindQuickContact(view, partition, cursor, ContactQuery.CONTACT_PHOTO_ID, ContactQuery.CONTACT_PHOTO_URI, ContactQuery.CONTACT_ID, - ContactQuery.CONTACT_LOOKUP_KEY, ContactQuery.CONTACT_DISPLAY_NAME); + ContactQuery.CONTACT_LOOKUP_KEY, ContactQuery.CONTACT_DISPLAY_NAME, + ContactQuery.CONTACT_ACCOUNT_TYPE, ContactQuery.CONTACT_ACCOUNT_NAME); } else { if (getDisplayPhotos()) { bindPhoto(view, partition, cursor); @@ -198,6 +257,9 @@ public class DefaultContactListAdapter extends ContactListAdapter { } bindNameAndViewId(view, cursor); + if (isQuickCallButtonEnabled()) { + bindQuickCallView(view, cursor); + } bindPresenceAndStatusMessage(view, cursor); if (isSearchMode()) { diff --git a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java index 8c8700c7..35ff111a 100644 --- a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java +++ b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java @@ -15,6 +15,7 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.content.ContentUris; import android.content.Context; import android.content.CursorLoader; @@ -28,6 +29,8 @@ import android.provider.ContactsContract.CommonDataKinds.SipAddress; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Directory; +import android.provider.ContactsContract.RawContacts; +import android.text.TextUtils; import android.telephony.PhoneNumberUtils; import android.text.TextUtils; import android.util.Log; @@ -41,6 +44,9 @@ import com.android.contacts.common.extensions.ExtendedPhoneDirectoriesManager; import com.android.contacts.common.extensions.ExtensionsFactory; import com.android.contacts.common.preference.ContactsPreferences; import com.android.contacts.common.util.Constants; +import com.android.contacts.common.SimContactsConstants; +import com.android.contacts.common.MoreContactUtils; +import com.android.contacts.common.model.account.SimAccountType; import java.util.ArrayList; import java.util.List; @@ -76,6 +82,8 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { Phone.PHOTO_ID, // 6 Phone.DISPLAY_NAME_PRIMARY, // 7 Phone.PHOTO_THUMBNAIL_URI, // 8 + RawContacts.ACCOUNT_TYPE, // 9 + RawContacts.ACCOUNT_NAME, // 10 }; public static final String[] PROJECTION_ALTERNATIVE = new String[] { @@ -88,6 +96,8 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { Phone.PHOTO_ID, // 6 Phone.DISPLAY_NAME_ALTERNATIVE, // 7 Phone.PHOTO_THUMBNAIL_URI, // 8 + RawContacts.ACCOUNT_TYPE, // 9 + RawContacts.ACCOUNT_NAME, // 10 }; public static final int PHONE_ID = 0; @@ -99,6 +109,8 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { public static final int PHOTO_ID = 6; public static final int DISPLAY_NAME = 7; public static final int PHOTO_URI = 8; + public static final int PHONE_ACCOUNT_TYPE = 9; + public static final int PHONE_ACCOUNT_NAME = 10; } private static final String IGNORE_NUMBER_TOO_LONG_CLAUSE = @@ -193,6 +205,13 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { // Remove duplicates when it is possible. builder.appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true"); + + // Do not show contacts in disabled SIM card + String disabledSimFilter = MoreContactUtils.getDisabledSimFilter(); + if (!TextUtils.isEmpty(disabledSimFilter)) { + String disabledSimName = getDisabledSimName(disabledSimFilter); + loader.setSelection(RawContacts.ACCOUNT_NAME+ "<>" + disabledSimName); + } loader.setUri(builder.build()); // TODO a projection that includes the search snippet @@ -366,7 +385,8 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { if (isQuickContactEnabled()) { bindQuickContact(view, partition, cursor, PhoneQuery.PHOTO_ID, PhoneQuery.PHOTO_URI, PhoneQuery.CONTACT_ID, - PhoneQuery.LOOKUP_KEY, PhoneQuery.DISPLAY_NAME); + PhoneQuery.LOOKUP_KEY, PhoneQuery.DISPLAY_NAME, + PhoneQuery.PHONE_ACCOUNT_TYPE, PhoneQuery.PHONE_ACCOUNT_NAME); } else { if (getDisplayPhotos()) { bindPhoto(view, partition, cursor); @@ -436,9 +456,15 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { if (!cursor.isNull(PhoneQuery.PHOTO_ID)) { photoId = cursor.getLong(PhoneQuery.PHOTO_ID); } - + Account account = null; + if (!cursor.isNull(PhoneQuery.PHONE_ACCOUNT_TYPE) + && !cursor.isNull(PhoneQuery.PHONE_ACCOUNT_NAME)) { + final String accountType = cursor.getString(PhoneQuery.PHONE_ACCOUNT_TYPE); + final String accountName = cursor.getString(PhoneQuery.PHONE_ACCOUNT_NAME); + account = new Account(accountName, accountType); + } if (photoId != 0) { - getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, false, + getPhotoLoader().loadThumbnail(view.getPhotoView(), photoId, account, false, getCircularPhotos(), null); } else { final String photoUriString = cursor.getString(PhoneQuery.PHOTO_URI); @@ -450,7 +476,7 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { final String lookupKey = cursor.getString(PhoneQuery.LOOKUP_KEY); request = new DefaultImageRequest(displayName, lookupKey, getCircularPhotos()); } - getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, false, + getPhotoLoader().loadDirectoryPhoto(view.getPhotoView(), photoUri, account, false, getCircularPhotos(), request); } } @@ -541,4 +567,21 @@ public class PhoneNumberListAdapter extends ContactEntryListAdapter { .encodedFragment(cursor.getString(lookUpKeyColumn)) .build(); } + + private String getDisabledSimName(String disabledSimFilter){ + String[] disabledSimArray = disabledSimFilter.split(",");//it will never be null + String disabledSimName = ""; + for (int i = 0; i < disabledSimArray.length; i++) { + if (i < disabledSimArray.length -1) { + //If disabledSimArray[i] is not the last one of the array, + //add "or" after every member of the array. + disabledSimName = disabledSimName + "'" + disabledSimArray[i] + "'" + "or"; + } else { + //If disabledSimArray[i] is the last one of the array, + //should not add anything after it. + disabledSimName = disabledSimName + "'" + disabledSimArray[i] + "'"; + } + } + return disabledSimName; + } } diff --git a/src/com/android/contacts/common/list/PhoneNumberPickerFragment.java b/src/com/android/contacts/common/list/PhoneNumberPickerFragment.java index 968f8db3..06a4f50c 100644 --- a/src/com/android/contacts/common/list/PhoneNumberPickerFragment.java +++ b/src/com/android/contacts/common/list/PhoneNumberPickerFragment.java @@ -42,6 +42,7 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE private static final int REQUEST_CODE_ACCOUNT_FILTER = 1; private static final String KEY_SHORTCUT_ACTION = "shortcutAction"; + private static final String DIRECTORY_ID_ARG_KEY = "directoryId"; private OnPhoneNumberPickerActionListener mListener; private String mShortcutAction; @@ -327,4 +328,16 @@ public class PhoneNumberPickerFragment extends ContactEntryListFragment<ContactE adapter.setPhotoPosition(photoPosition); } } + + /** + * Loads the directory partition. + */ + protected void loadDirectoryPartition(int partitionIndex, DirectoryPartition partition) { + Bundle args = new Bundle(); + args.putLong(DIRECTORY_ID_ARG_KEY, partition.getDirectoryId()); + if (getLoaderManager().getLoader(partitionIndex) != null) { + getLoaderManager().destroyLoader(partitionIndex); + } + getLoaderManager().restartLoader(partitionIndex, args, this); + } } diff --git a/src/com/android/contacts/common/list/ShortcutIntentBuilder.java b/src/com/android/contacts/common/list/ShortcutIntentBuilder.java index 6c97fd9f..53cb857b 100644 --- a/src/com/android/contacts/common/list/ShortcutIntentBuilder.java +++ b/src/com/android/contacts/common/list/ShortcutIntentBuilder.java @@ -15,6 +15,7 @@ */ package com.android.contacts.common.list; +import android.accounts.Account; import android.app.ActivityManager; import android.content.ContentResolver; import android.content.Context; @@ -38,6 +39,7 @@ import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; +import android.provider.ContactsContract.RawContacts; import android.telecom.PhoneAccount; import android.text.TextPaint; import android.text.TextUtils; @@ -56,12 +58,16 @@ public class ShortcutIntentBuilder { private static final String[] CONTACT_COLUMNS = { Contacts.DISPLAY_NAME, Contacts.PHOTO_ID, - Contacts.LOOKUP_KEY + Contacts.LOOKUP_KEY, + RawContacts.ACCOUNT_TYPE, + RawContacts.ACCOUNT_NAME }; private static final int CONTACT_DISPLAY_NAME_COLUMN_INDEX = 0; private static final int CONTACT_PHOTO_ID_COLUMN_INDEX = 1; private static final int CONTACT_LOOKUP_KEY_COLUMN_INDEX = 2; + private static final int CONTACT_ACCOUNT_TYPE_COLUMN_INDEX = 3; + private static final int CONTACT_ACCOUNT_NAME_COLUMN_INDEX = 4; private static final String[] PHONE_COLUMNS = { Phone.DISPLAY_NAME, @@ -69,7 +75,9 @@ public class ShortcutIntentBuilder { Phone.NUMBER, Phone.TYPE, Phone.LABEL, - Phone.LOOKUP_KEY + Phone.LOOKUP_KEY, + RawContacts.ACCOUNT_TYPE, + RawContacts.ACCOUNT_NAME }; private static final int PHONE_DISPLAY_NAME_COLUMN_INDEX = 0; @@ -78,6 +86,8 @@ public class ShortcutIntentBuilder { private static final int PHONE_TYPE_COLUMN_INDEX = 3; private static final int PHONE_LABEL_COLUMN_INDEX = 4; private static final int PHONE_LOOKUP_KEY_COLUMN_INDEX = 5; + private static final int PHONE_ACCOUNT_TYPE_COLUMN_INDEX = 6; + private static final int PHONE_ACCOUNT_NAME_COLUMN_INDEX = 7; private static final String[] PHOTO_COLUMNS = { Photo.PHOTO, @@ -187,6 +197,8 @@ public class ShortcutIntentBuilder { } private final class ContactLoadingAsyncTask extends LoadingAsyncTask { + private Account mAccount; + public ContactLoadingAsyncTask(Uri uri) { super(uri); } @@ -200,6 +212,13 @@ public class ShortcutIntentBuilder { if (cursor.moveToFirst()) { mDisplayName = cursor.getString(CONTACT_DISPLAY_NAME_COLUMN_INDEX); mPhotoId = cursor.getLong(CONTACT_PHOTO_ID_COLUMN_INDEX); + + final String accountType = cursor + .getString(CONTACT_ACCOUNT_TYPE_COLUMN_INDEX); + final String accountName = cursor + .getString(CONTACT_ACCOUNT_NAME_COLUMN_INDEX); + mAccount = new Account(accountName, accountType); + mLookupKey = cursor.getString(CONTACT_LOOKUP_KEY_COLUMN_INDEX); } } finally { @@ -209,7 +228,8 @@ public class ShortcutIntentBuilder { } @Override protected void onPostExecute(Void result) { - createContactShortcutIntent(mUri, mContentType, mDisplayName, mLookupKey, mBitmapData); + createContactShortcutIntent(mUri, mContentType, mDisplayName, + mAccount, mLookupKey, mBitmapData); } } @@ -218,6 +238,7 @@ public class ShortcutIntentBuilder { private String mPhoneNumber; private int mPhoneType; private String mPhoneLabel; + private Account mAccount; public PhoneNumberLoadingAsyncTask(Uri uri, String shortcutAction) { super(uri); @@ -236,6 +257,13 @@ public class ShortcutIntentBuilder { mPhoneNumber = cursor.getString(PHONE_NUMBER_COLUMN_INDEX); mPhoneType = cursor.getInt(PHONE_TYPE_COLUMN_INDEX); mPhoneLabel = cursor.getString(PHONE_LABEL_COLUMN_INDEX); + + final String accountType = cursor + .getString(PHONE_ACCOUNT_TYPE_COLUMN_INDEX); + final String accountName = cursor + .getString(PHONE_ACCOUNT_NAME_COLUMN_INDEX); + mAccount = new Account(accountName, accountType); + mLookupKey = cursor.getString(PHONE_LOOKUP_KEY_COLUMN_INDEX); } } finally { @@ -247,23 +275,24 @@ public class ShortcutIntentBuilder { @Override protected void onPostExecute(Void result) { createPhoneNumberShortcutIntent(mUri, mDisplayName, mLookupKey, mBitmapData, - mPhoneNumber, mPhoneType, mPhoneLabel, mShortcutAction); + mPhoneNumber, mPhoneType, mPhoneLabel, mAccount, mShortcutAction); } } - private Drawable getPhotoDrawable(byte[] bitmapData, String displayName, String lookupKey) { + private Drawable getPhotoDrawable(byte[] bitmapData, String displayName, + String lookupKey, Account account) { if (bitmapData != null) { Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length, null); return new BitmapDrawable(mContext.getResources(), bitmap); } else { - return ContactPhotoManager.getDefaultAvatarDrawableForContact(mContext.getResources(), - false, new DefaultImageRequest(displayName, lookupKey, false)); + return ContactPhotoManager.getDefaultAvatarDrawableForContact(mContext, + false, new DefaultImageRequest(displayName, lookupKey, false), account); } } private void createContactShortcutIntent(Uri contactUri, String contentType, String displayName, - String lookupKey, byte[] bitmapData) { - Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey); + Account account, String lookupKey, byte[] bitmapData) { + Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey, account); Intent shortcutIntent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT); @@ -300,8 +329,8 @@ public class ShortcutIntentBuilder { private void createPhoneNumberShortcutIntent(Uri uri, String displayName, String lookupKey, byte[] bitmapData, String phoneNumber, int phoneType, String phoneLabel, - String shortcutAction) { - Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey); + Account account, String shortcutAction) { + Drawable drawable = getPhotoDrawable(bitmapData, displayName, lookupKey, account); Bitmap bitmap; Uri phoneUri; diff --git a/src/com/android/contacts/common/model/AccountTypeManager.java b/src/com/android/contacts/common/model/AccountTypeManager.java index 6efe8199..ba303c4d 100644 --- a/src/com/android/contacts/common/model/AccountTypeManager.java +++ b/src/com/android/contacts/common/model/AccountTypeManager.java @@ -38,6 +38,7 @@ import android.os.Message; import android.os.SystemClock; import android.provider.ContactsContract; import android.text.TextUtils; +import android.telephony.TelephonyManager; import android.util.Log; import android.util.TimingLogger; @@ -50,7 +51,10 @@ import com.android.contacts.common.model.account.ExchangeAccountType; import com.android.contacts.common.model.account.ExternalAccountType; import com.android.contacts.common.model.account.FallbackAccountType; import com.android.contacts.common.model.account.GoogleAccountType; +import com.android.contacts.common.model.account.PhoneAccountType; +import com.android.contacts.common.model.account.SimAccountType; import com.android.contacts.common.model.dataitem.DataKind; +import com.android.contacts.common.SimContactsConstants; import com.android.contacts.common.testing.NeededForTesting; import com.android.contacts.common.util.Constants; import com.google.common.annotations.VisibleForTesting; @@ -79,6 +83,13 @@ public abstract class AccountTypeManager { private static final Object mInitializationLock = new Object(); private static AccountTypeManager mAccountTypeManager; + public static final int FLAG_ALL_ACCOUNTS = 0; + public static final int FLAG_ALL_ACCOUNTS_WITHOUT_SIM = 1; + /** + * without sim and phone accounts + */ + public static final int FLAG_ALL_ACCOUNTS_WITHOUT_LOCAL = 2; + /** * Requests the singleton instance of {@link AccountTypeManager} with data bound from * the available authenticators. This method can safely be called from the UI thread. @@ -112,6 +123,8 @@ public abstract class AccountTypeManager { * contact writable accounts (if contactWritableOnly is true). */ // TODO: Consider splitting this into getContactWritableAccounts() and getAllAccounts() + public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly, int flag); + public abstract List<AccountWithDataSet> getAccounts(boolean contactWritableOnly); /** @@ -418,6 +431,10 @@ class AccountTypeManagerImpl extends AccountTypeManager accountType = new GoogleAccountType(mContext, auth.packageName); } else if (ExchangeAccountType.isExchangeType(type)) { accountType = new ExchangeAccountType(mContext, auth.packageName, type); + } else if (SimAccountType.ACCOUNT_TYPE.equals(type)) { + accountType = new SimAccountType(mContext, auth.packageName); + } else if (PhoneAccountType.ACCOUNT_TYPE.equals(type)) { + accountType = new PhoneAccountType(mContext, auth.packageName); } else { Log.d(TAG, "Registering external account type=" + type + ", packageName=" + auth.packageName); @@ -563,15 +580,86 @@ class AccountTypeManagerImpl extends AccountTypeManager return null; } + @Override + public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) { + return getAccounts(contactWritableOnly, FLAG_ALL_ACCOUNTS); + } + /** * Return list of all known, contact writable {@link AccountWithDataSet}'s. */ @Override - public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly) { + public List<AccountWithDataSet> getAccounts(boolean contactWritableOnly, + int flag) { ensureAccountsLoaded(); + boolean isAirMode = MoreContactUtils.isAPMOnAndSIMPowerDown(mContext); + switch (flag) { + case FLAG_ALL_ACCOUNTS: + return trimAccountByType( + contactWritableOnly ? mContactWritableAccounts : mAccounts, + isAirMode ? SimAccountType.ACCOUNT_TYPE : null); + case FLAG_ALL_ACCOUNTS_WITHOUT_LOCAL: + return trimAccountByType( + contactWritableOnly ? mContactWritableAccounts : mAccounts, + SimAccountType.ACCOUNT_TYPE, PhoneAccountType.ACCOUNT_TYPE); + case FLAG_ALL_ACCOUNTS_WITHOUT_SIM: + return trimAccountByType( + contactWritableOnly ? mContactWritableAccounts : mAccounts, + SimAccountType.ACCOUNT_TYPE); + } return contactWritableOnly ? mContactWritableAccounts : mAccounts; } + private boolean isSimStateUnknown(Account account) { + int subscription = SimContactsConstants.SUB_INVALID; + subscription = MoreContactUtils.getSubscription(account.type, account.name); + + if (subscription > SimContactsConstants.SUB_INVALID + && TelephonyManager.getDefault().getSimState(subscription) + == TelephonyManager.SIM_STATE_UNKNOWN) { + return true; + } else { + return false; + } + } + + private boolean isSimAccountInvalid(Account account) { + if ((SimContactsConstants.ACCOUNT_TYPE_SIM).equals(account.type)) { + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + if (account.name.equals(SimContactsConstants.SIM_NAME)) + return true; + } else { + if (!account.name.equals(SimContactsConstants.SIM_NAME)) { + return true; + } + } + } + return false; + } + + private List<AccountWithDataSet> trimAccountByType(final List<AccountWithDataSet> list, + String... trimAccountTypes) { + List<AccountWithDataSet> tempList = Lists.newArrayList(); + outer: for (AccountWithDataSet accountWithDataSet : list) { + if (trimAccountTypes != null && trimAccountTypes.length > 0) { + for (String type : trimAccountTypes) { + if (type != null && type.equals(accountWithDataSet.type)) { + continue outer; + } + } + } + + if (isSimStateUnknown(accountWithDataSet)) { + continue outer; + } + if (isSimAccountInvalid(accountWithDataSet)) { + continue outer; + } + tempList.add(accountWithDataSet); + } + return tempList; + } + /** * Return the list of all known, group writable {@link AccountWithDataSet}'s. */ diff --git a/src/com/android/contacts/common/model/RawContactDelta.java b/src/com/android/contacts/common/model/RawContactDelta.java index 7304f023..cf5bf304 100644 --- a/src/com/android/contacts/common/model/RawContactDelta.java +++ b/src/com/android/contacts/common/model/RawContactDelta.java @@ -24,15 +24,20 @@ import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.provider.BaseColumns; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Profile; import android.provider.ContactsContract.RawContacts; +import android.text.TextUtils; import android.util.Log; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.ValuesDelta; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.testing.NeededForTesting; +import com.android.contacts.common.SimContactsConstants; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -416,6 +421,139 @@ public class RawContactDelta implements Parcelable { } } + public ContentValues buildSimDiff() { + ContentValues values = new ContentValues(); + ArrayList<ValuesDelta> names = getMimeEntries(StructuredName.CONTENT_ITEM_TYPE); + ArrayList<ValuesDelta> phones = getMimeEntries(Phone.CONTENT_ITEM_TYPE); + ArrayList<ValuesDelta> emails = getMimeEntries(Email.CONTENT_ITEM_TYPE); + + ValuesDelta nameValuesDelta = null; + ValuesDelta emailValuesDelta = null; + + if (getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true) > 0) { + nameValuesDelta = names.get(0); + names.get(0).putNull(StructuredName.GIVEN_NAME); + names.get(0).putNull(StructuredName.FAMILY_NAME); + names.get(0).putNull(StructuredName.PREFIX); + names.get(0).putNull(StructuredName.MIDDLE_NAME); + names.get(0).putNull(StructuredName.SUFFIX); + names.get(0).put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); + } + if (emails != null && emails.size() > 0) { + emailValuesDelta = emails.get(0); + } + + String name = null; + String number = null; + String newName = null; + String newNumber = null; + StringBuilder email = new StringBuilder(); + StringBuilder anr = new StringBuilder(); + StringBuilder newEmail = new StringBuilder(); + StringBuilder newAnr = new StringBuilder(); + + if (nameValuesDelta != null) { + if (isContactInsert()) { + name = nameValuesDelta.getAsString(StructuredName.DISPLAY_NAME); + } else { + if (nameValuesDelta.getBefore() != null) { + name = nameValuesDelta.getBefore() + .getAsString(StructuredName.DISPLAY_NAME); + } + if (nameValuesDelta.getAfter() != null) { + newName = nameValuesDelta.getAfter() + .getAsString(StructuredName.DISPLAY_NAME); + } + } + } + + if (isContactInsert() && phones != null) { + for (ValuesDelta valuesDelta : phones) { + if (valuesDelta.getAfter() != null + && valuesDelta.getAfter().size() != 0) { + if (Phone.TYPE_MOBILE == valuesDelta.getAfter().getAsLong(Phone.TYPE)) { + if (TextUtils.isEmpty(number)) { + number = valuesDelta.getAfter().getAsString(Phone.NUMBER); + } else { + // don't supports to save two mobile number,so gives + // invalid str here + number = SimContactsConstants.STR_ANRS; + } + } else { + anr.append(valuesDelta.getAfter().getAsString(Phone.NUMBER)); + anr.append(","); + } + } + } + } else if(phones != null) { + for (ValuesDelta valuesDelta : phones) { + if (valuesDelta.getBefore() != null + && valuesDelta.getBefore().size() != 0) { + if (Phone.TYPE_MOBILE == valuesDelta.getBefore().getAsLong(Phone.TYPE) ) { + number = valuesDelta.getBefore().getAsString(Phone.NUMBER); + } else { + anr.append(valuesDelta.getBefore().getAsString(Phone.NUMBER)); + anr.append(","); + } + } + if (valuesDelta.getAfter() != null + && valuesDelta.getAfter().size() != 0) { + if (Phone.TYPE_MOBILE == valuesDelta.getAsLong(Phone.TYPE)) { + if (TextUtils.isEmpty(newNumber)) { + newNumber = valuesDelta.getAfter().getAsString(Phone.NUMBER); + } else { + newNumber = SimContactsConstants.STR_ANRS; + } + } else { + newAnr.append(valuesDelta.getAfter().getAsString(Phone.NUMBER)); + newAnr.append(","); + } + } + } + } + + if (isContactInsert() && emails != null) { + for (ValuesDelta valuesDelta : emails) { + if (valuesDelta.getAfter() != null + && valuesDelta.getAfter().size() != 0) { + email.append(valuesDelta.getAfter().getAsString(Email.DATA)); + email.append(","); + } + } + } else if (emails != null) { + for (ValuesDelta valuesDelta : emails) { + if (valuesDelta.getBefore() != null + && valuesDelta.getBefore().size() != 0) { + email.append(valuesDelta.getBefore().getAsString(Email.DATA)); + email.append(","); + } + if (valuesDelta.getAfter() != null + && valuesDelta.getAfter().size() != 0) { + newEmail.append(valuesDelta.getAfter().getAsString(Email.DATA)); + newEmail.append(","); + } + } + } + + if (isContactInsert()) { + if (name != null || number != null || anr != null || email != null) { + values.put(SimContactsConstants.STR_TAG, name); + values.put(SimContactsConstants.STR_NUMBER, number); + values.put(SimContactsConstants.STR_EMAILS, email.toString()); + values.put(SimContactsConstants.STR_ANRS, anr.toString()); + } + } else { + values.put(SimContactsConstants.STR_TAG, name); + values.put(SimContactsConstants.STR_NUMBER, number); + values.put(SimContactsConstants.STR_EMAILS, email.toString()); + values.put(SimContactsConstants.STR_ANRS, anr.toString()); + values.put(SimContactsConstants.STR_NEW_TAG, newName); + values.put(SimContactsConstants.STR_NEW_NUMBER, newNumber); + values.put(SimContactsConstants.STR_NEW_EMAILS, newEmail.toString()); + values.put(SimContactsConstants.STR_NEW_ANRS, newAnr.toString()); + } + return values; + } /** * Build a list of {@link ContentProviderOperation} that will transform the * current "before" {@link Entity} state into the modified state which this diff --git a/src/com/android/contacts/common/model/RawContactModifier.java b/src/com/android/contacts/common/model/RawContactModifier.java index 954123ba..5ddf0f05 100644 --- a/src/com/android/contacts/common/model/RawContactModifier.java +++ b/src/com/android/contacts/common/model/RawContactModifier.java @@ -487,7 +487,7 @@ public class RawContactModifier { */ public static boolean isEmpty(ValuesDelta values, DataKind kind) { if (Photo.CONTENT_ITEM_TYPE.equals(kind.mimeType)) { - return values.isInsert() && values.getAsByteArray(Photo.PHOTO) == null; + return values.getAsByteArray(Photo.PHOTO) == null; } // No defined fields mean this row is always empty diff --git a/src/com/android/contacts/common/model/ValuesDelta.java b/src/com/android/contacts/common/model/ValuesDelta.java index e30cdd62..2db7e1c8 100644 --- a/src/com/android/contacts/common/model/ValuesDelta.java +++ b/src/com/android/contacts/common/model/ValuesDelta.java @@ -23,6 +23,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.provider.BaseColumns; import android.provider.ContactsContract; +import android.provider.ContactsContract.Data; import com.android.contacts.common.testing.NeededForTesting; import com.google.common.collect.Sets; @@ -61,6 +62,17 @@ public class ValuesDelta implements Parcelable { final ValuesDelta entry = new ValuesDelta(); entry.mBefore = before; entry.mAfter = new ContentValues(); + + // init data1 to mAfter map. when no operation edittext of + // sim phone in the UI, the mAfter init have no data1 value, + // it will cause the builddiff data not right. + if (before.containsKey(Data.DATA1)) { + String contactInfo = before.getAsString(Data.DATA1); + if (null != contactInfo && !"".equals(contactInfo)) { + entry.mAfter.put(Data.DATA1, contactInfo); + } + } + return entry; } @@ -83,6 +95,10 @@ public class ValuesDelta implements Parcelable { return mAfter; } + public ContentValues getBefore() { + return mBefore; + } + public boolean containsKey(String key) { return ((mAfter != null && mAfter.containsKey(key)) || (mBefore != null && mBefore.containsKey(key))); diff --git a/src/com/android/contacts/common/model/account/AccountType.java b/src/com/android/contacts/common/model/account/AccountType.java index 53ab47d9..27b5bc5f 100644..100755 --- a/src/com/android/contacts/common/model/account/AccountType.java +++ b/src/com/android/contacts/common/model/account/AccountType.java @@ -16,19 +16,26 @@ package com.android.contacts.common.model.account; +import android.accounts.AccountManager; +import android.accounts.AuthenticatorDescription; import android.content.ContentValues; import android.content.Context; import android.content.pm.PackageManager; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.StructuredPostal; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.RawContacts; +import android.telephony.TelephonyManager; +import android.util.Log; import android.view.inputmethod.EditorInfo; import android.widget.EditText; +import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.R; import com.android.contacts.common.model.dataitem.DataKind; +import com.android.internal.telephony.PhoneConstants; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -39,6 +46,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Internal structure that represents constraints and styles for a specific data @@ -51,6 +59,12 @@ public abstract class AccountType { private static final String TAG = "AccountType"; /** + * Local phone-storage account + * @hide + */ + public static final String LOCAL_ACCOUNT = "phone-local"; + + /** * The {@link RawContacts#ACCOUNT_TYPE} these constraints apply to. */ public String accountType = null; @@ -96,6 +110,11 @@ public abstract class AccountType { protected boolean mIsInitialized; + private Map<String, AuthenticatorDescription> mTypeToAuthDescription + = new HashMap<String, AuthenticatorDescription>(); + + private AuthenticatorDescription[] mAuthDescs; + protected static class DefinitionException extends Exception { public DefinitionException(String message) { super(message); @@ -196,12 +215,6 @@ public abstract class AccountType { public String getViewGroupActivity() { return null; } - - public CharSequence getDisplayLabel(Context context) { - // Note this resource is defined in the sync adapter package, not resourcePackageName. - return getResourceText(context, syncAdapterPackageName, titleRes, accountType); - } - /** * @return resource ID for the "invite contact" action label, or -1 if not defined. */ @@ -276,15 +289,89 @@ public abstract class AccountType { } } + public void updateAuthDescriptions(Context context) { + mAuthDescs = AccountManager.get(context).getAuthenticatorTypes(); + for (int i = 0; i < mAuthDescs.length; i++) { + mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]); + } + } + public CharSequence getDisplayLabel(Context context) { + CharSequence label = null; + updateAuthDescriptions(context); + if (mTypeToAuthDescription.containsKey(accountType)) { + try { + AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType); + Context authContext = context.createPackageContext(desc.packageName, 0); + label = authContext.getResources().getText(desc.labelId); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "No label name for account type " + accountType); + } catch (Resources.NotFoundException e) { + Log.w(TAG, "No label icon for account type " + accountType); + } + } + return label; + } + + public CharSequence getDisplayLabel(Context context, String accountName) { + if ((SimAccountType.ACCOUNT_TYPE).equals(accountType)) { + final int slot = MoreContactUtils.getSubscription(accountType, + accountName); + return MoreContactUtils.getMultiSimAliasesName(context, slot); + } + return getDisplayLabel(context); + } + + /** + * Gets an icon associated with a particular account type. If none found, return null. + * + * @param accountType the type of account + * @return a drawable for the icon or null if one cannot be found. + */ public Drawable getDisplayIcon(Context context) { - if (this.titleRes != -1 && this.syncAdapterPackageName != null) { - final PackageManager pm = context.getPackageManager(); - return pm.getDrawable(this.syncAdapterPackageName, this.iconRes, null); - } else if (this.titleRes != -1) { - return context.getResources().getDrawable(this.iconRes); - } else { - return null; + Drawable icon = null; + updateAuthDescriptions(context); + if (PhoneAccountType.ACCOUNT_TYPE.equals(accountType)) { + return context.getResources().getDrawable(R.drawable.phone_account); + } + if (mTypeToAuthDescription.containsKey(accountType)) { + try { + AuthenticatorDescription desc = mTypeToAuthDescription + .get(accountType); + Context authContext = context.createPackageContext( + desc.packageName, 0); + icon = authContext.getResources().getDrawable(desc.iconId); + } catch (PackageManager.NameNotFoundException e) { + } catch (Resources.NotFoundException e) { + } + } + if (icon == null) { + icon = context.getPackageManager().getDefaultActivityIcon(); + } + return icon; + } + + public Drawable getDisplayIcon(Context context, String accountName) { + if ((SimAccountType.ACCOUNT_TYPE).equals(accountType)) { + final int slot = MoreContactUtils.getSubscription(accountType, + accountName); + if (TelephonyManager.getDefault().isMultiSimEnabled()) { + switch (slot) { + case PhoneConstants.SUB1: + return context.getResources().getDrawable( + R.drawable.sim1_account); + case PhoneConstants.SUB2: + return context.getResources().getDrawable( + R.drawable.sim2_account); + default: + return context.getResources().getDrawable( + R.drawable.simcard_account); + } + } else { + return context.getResources().getDrawable( + R.drawable.simcard_account); + } } + return getDisplayIcon(context); } /** diff --git a/src/com/android/contacts/common/model/account/BaseAccountType.java b/src/com/android/contacts/common/model/account/BaseAccountType.java index 648a6dc8..1ead103f 100644 --- a/src/com/android/contacts/common/model/account/BaseAccountType.java +++ b/src/com/android/contacts/common/model/account/BaseAccountType.java @@ -436,6 +436,8 @@ public abstract class BaseAccountType extends AccountType { DataKind kind = addKind(new DataKind(GroupMembership.CONTENT_ITEM_TYPE, R.string.groupsLabel, Weight.GROUP_MEMBERSHIP, true)); + kind.actionHeader = new SimpleInflater(R.string.label_groups); + kind.actionBody = new SimpleInflater(GroupMembership.GROUP_ROW_ID); kind.typeOverallMax = 1; kind.fieldList = Lists.newArrayList(); kind.fieldList.add(new EditField(GroupMembership.GROUP_ROW_ID, -1, -1)); diff --git a/src/com/android/contacts/common/model/account/PhoneAccountType.java b/src/com/android/contacts/common/model/account/PhoneAccountType.java new file mode 100644 index 00000000..7e2e1e52 --- /dev/null +++ b/src/com/android/contacts/common/model/account/PhoneAccountType.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014, The Linux Foundation. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.android.contacts.common.model.account; + +import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; +import android.os.SystemProperties; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.telephony.TelephonyManager; +import android.util.Log; +import android.view.inputmethod.EditorInfo; + +import com.android.contacts.common.R; +import com.android.contacts.common.SimContactsConstants; +import com.android.contacts.common.model.account.AccountType.DefinitionException; +import com.google.android.collect.Lists; + + +public class PhoneAccountType extends BaseAccountType{ + private static final String TAG = "PhoneAccountType"; + + public static final String ACCOUNT_TYPE = SimContactsConstants.ACCOUNT_TYPE_PHONE; + public static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT + | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME; + protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE; + + public PhoneAccountType(Context context, String resPackageName) { + this.accountType = ACCOUNT_TYPE; + this.resourcePackageName = null; + this.syncAdapterPackageName = resPackageName; + + try { + + addDataKindStructuredName(context); + addDataKindDisplayName(context); + addDataKindPhoneticName(context); + addDataKindNickname(context); + addDataKindPhone(context); + addDataKindEmail(context); + addDataKindStructuredPostal(context); + addDataKindIm(context); + addDataKindOrganization(context); + addDataKindPhoto(context); + addDataKindNote(context); + addDataKindWebsite(context); + addDataKindGroupMembership(context); + if (context.getResources().getBoolean( + com.android.internal.R.bool.config_built_in_sip_phone)) { + addDataKindSipAddress(context); + } + + mIsInitialized = true; + } catch (DefinitionException e) { + Log.e(TAG, "Problem building account type", e); + } + + } + + @Override + public boolean isGroupMembershipEditable() { + return true; + } + + @Override + public boolean areContactsWritable() { + return true; + } + +} diff --git a/src/com/android/contacts/common/model/account/SimAccountType.java b/src/com/android/contacts/common/model/account/SimAccountType.java new file mode 100644 index 00000000..6473f2b0 --- /dev/null +++ b/src/com/android/contacts/common/model/account/SimAccountType.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2014, The Linux Foundation. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +package com.android.contacts.common.model.account; + +import android.content.Context; +import android.provider.ContactsContract.CommonDataKinds.Email; +import android.provider.ContactsContract.CommonDataKinds.StructuredName; +import android.provider.ContactsContract.CommonDataKinds.Phone; +import android.util.Log; +import android.view.inputmethod.EditorInfo; +import android.graphics.drawable.Drawable; + +import com.android.contacts.common.R; +import com.android.contacts.common.SimContactsConstants; +import com.android.contacts.common.model.account.AccountType.DefinitionException; +import com.android.contacts.common.model.dataitem.DataKind; +import com.google.android.collect.Lists; + +public class SimAccountType extends BaseAccountType{ + private static final String TAG = "SimContactsType"; + + public static final String ACCOUNT_TYPE = SimContactsConstants.ACCOUNT_TYPE_SIM; + public static final int FLAGS_PERSON_NAME = EditorInfo.TYPE_CLASS_TEXT + | EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS | EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME; + public static final int FLAGS_PHONETIC = EditorInfo.TYPE_CLASS_TEXT + | EditorInfo.TYPE_TEXT_VARIATION_PHONETIC; + protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE; + private static Context mContext; + + public SimAccountType(Context context, String resPackageName) { + this.accountType = ACCOUNT_TYPE; + this.resourcePackageName = resPackageName; + this.syncAdapterPackageName = resPackageName; + + this.mContext = context; + + try { + addDataKindStructuredName(context); + addDataKindDisplayName(context); + addDataKindPhone(context); + addDataKindEmail(context); + mIsInitialized = true; + } catch (DefinitionException e) { + Log.e(TAG, "Problem building account type", e); + } + } + + @Override + protected DataKind addDataKindStructuredName(Context context) throws DefinitionException { + final DataKind kind = super.addDataKindStructuredName(context); + kind.fieldList = Lists.newArrayList(); + kind.fieldList.add(new EditField(StructuredName.DISPLAY_NAME, R.string.nameLabelsGroup, + FLAGS_PERSON_NAME)); + + return kind; + } + + @Override + protected DataKind addDataKindPhone(Context context) throws DefinitionException { + final DataKind kind = super.addDataKindPhone(context); + + kind.iconAltRes = R.drawable.ic_text_holo_light; + kind.typeOverallMax = 2; + kind.typeColumn = Phone.TYPE; + kind.typeList = Lists.newArrayList(); + kind.typeList.add(buildPhoneType(Phone.TYPE_MOBILE)); + kind.typeList.add(buildPhoneType(Phone.TYPE_HOME));// This is used to save ANR records + kind.fieldList = Lists.newArrayList(); + kind.fieldList.add(new EditField(Phone.NUMBER, R.string.phoneLabelsGroup, FLAGS_PHONE)); + + return kind; + } + + @Override + protected DataKind addDataKindEmail(Context context) throws DefinitionException { + final DataKind kind = super.addDataKindEmail(context); + + kind.typeOverallMax = 1; + kind.typeColumn = Email.TYPE; + kind.fieldList = Lists.newArrayList(); + kind.fieldList.add(new EditField(Email.ADDRESS, R.string.emailLabelsGroup, FLAGS_EMAIL)); + return kind; + } + + + @Override + public boolean isGroupMembershipEditable() { + return true; + } + + @Override + public boolean areContactsWritable() { + return true; + } + +} diff --git a/src/com/android/contacts/common/preference/ContactsPreferences.java b/src/com/android/contacts/common/preference/ContactsPreferences.java index 311d0075..5c07f83f 100644 --- a/src/com/android/contacts/common/preference/ContactsPreferences.java +++ b/src/com/android/contacts/common/preference/ContactsPreferences.java @@ -27,6 +27,7 @@ import android.provider.ContactsContract; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; +import android.text.TextUtils; import com.android.contacts.common.R; /** @@ -54,6 +55,11 @@ public final class ContactsPreferences implements OnSharedPreferenceChangeListen public static final String SORT_ORDER_KEY = "android.contacts.SORT_ORDER"; /** + * The values of SIMs serial numbers that have been imported + */ + public static final String IMPORTED_SIMS_SNS = "android.contacts.IMPORTED_SIMS"; + + /** * The value for the SORT_ORDER key corresponding to sort by family name first. */ public static final int SORT_ORDER_ALTERNATIVE = 2; @@ -105,6 +111,28 @@ public final class ContactsPreferences implements OnSharedPreferenceChangeListen editor.commit(); } + public String[] getImportedSims() { + String imported = mPreferences.getString(IMPORTED_SIMS_SNS, ""); + if (!TextUtils.isEmpty(imported)) { + return imported.split("\\|"); + } else { + return new String[0]; + } + } + + public void addImportedSims(String simSN) { + String imported = mPreferences.getString(IMPORTED_SIMS_SNS, ""); + if (!TextUtils.isEmpty(imported)) { + imported += "|" + simSN; + } else { + imported = simSN; + } + + final Editor editor = mPreferences.edit(); + editor.putString(IMPORTED_SIMS_SNS, imported); + editor.commit(); + } + public boolean isDisplayOrderUserChangeable() { return mContext.getResources().getBoolean(R.bool.config_display_order_user_changeable); } diff --git a/src/com/android/contacts/common/preference/DisplayOrderPreference.java b/src/com/android/contacts/common/preference/DisplayOrderPreference.java index 6a182c51..c053466d 100644..100755 --- a/src/com/android/contacts/common/preference/DisplayOrderPreference.java +++ b/src/com/android/contacts/common/preference/DisplayOrderPreference.java @@ -21,6 +21,8 @@ import android.content.Context; import android.preference.ListPreference; import android.provider.ContactsContract; import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; import com.android.contacts.common.R; import com.android.contacts.common.preference.ContactsPreferences; @@ -89,4 +91,13 @@ public final class DisplayOrderPreference extends ListPreference { super.onPrepareDialogBuilder(builder); builder.setNegativeButton(null, null); } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame); + if (imageFrame != null) { + imageFrame.setVisibility(View.GONE); + } + } } diff --git a/src/com/android/contacts/common/preference/SortOrderPreference.java b/src/com/android/contacts/common/preference/SortOrderPreference.java index dfd9550b..863d9845 100644..100755 --- a/src/com/android/contacts/common/preference/SortOrderPreference.java +++ b/src/com/android/contacts/common/preference/SortOrderPreference.java @@ -20,6 +20,8 @@ import android.app.AlertDialog.Builder; import android.content.Context; import android.preference.ListPreference; import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; import com.android.contacts.common.R; import com.android.contacts.common.preference.ContactsPreferences; @@ -88,4 +90,13 @@ public final class SortOrderPreference extends ListPreference { super.onPrepareDialogBuilder(builder); builder.setNegativeButton(null, null); } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + final View imageFrame = view.findViewById(com.android.internal.R.id.icon_frame); + if (imageFrame != null) { + imageFrame.setVisibility(View.GONE); + } + } } diff --git a/src/com/android/contacts/common/util/AccountSelectionUtil.java b/src/com/android/contacts/common/util/AccountSelectionUtil.java index 78cc2d5d..ed77da22 100644 --- a/src/com/android/contacts/common/util/AccountSelectionUtil.java +++ b/src/com/android/contacts/common/util/AccountSelectionUtil.java @@ -1,5 +1,7 @@ /* * Copyright (C) 2009 The Android Open Source Project + * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Not a Contribution. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +25,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -32,11 +35,13 @@ import android.widget.ArrayAdapter; import android.widget.TextView; import com.android.contacts.common.R; +import com.android.contacts.common.SimContactsConstants; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.vcard.ImportVCardActivity; +import java.util.ArrayList; import java.util.List; /** @@ -47,8 +52,14 @@ public class AccountSelectionUtil { private static final String LOG_TAG = "AccountSelectionUtil"; public static boolean mVCardShare = false; + private static int SIM_ID_INVALID = -1; + private static int mSelectedSim = SIM_ID_INVALID; + // Constant value to know option is import from all SIM's + private static int IMPORT_FROM_ALL = 8; public static Uri mPath; + // QRD enhancement: import subscription selected by user + private static int mImportSub = SimContactsConstants.SUB_INVALID; public static class AccountSelectedListener implements DialogInterface.OnClickListener { @@ -57,7 +68,7 @@ public class AccountSelectionUtil { final private int mResId; final private int mSubscriptionId; - final protected List<AccountWithDataSet> mAccountList; + protected List<AccountWithDataSet> mAccountList; public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList, int resId, int subscriptionId) { @@ -81,6 +92,19 @@ public class AccountSelectionUtil { dialog.dismiss(); doImport(mContext, mResId, mAccountList.get(which), mSubscriptionId); } + /** + * Reset the account list for this listener, to make sure the selected + * items reflect the displayed items. + * + * @param accountList The reset account list. + */ + void setAccountList(List<AccountWithDataSet> accountList) { + mAccountList = accountList; + } + } + + public static void setImportSubscription(int subscription) { + mImportSub = subscription; } public static Dialog getSelectAccountDialog(Context context, int resId) { @@ -92,15 +116,28 @@ public class AccountSelectionUtil { return getSelectAccountDialog(context, resId, onClickListener, null); } + public static Dialog getSelectAccountDialog(Context context, int resId, + DialogInterface.OnClickListener onClickListener, + DialogInterface.OnCancelListener onCancelListener) { + return getSelectAccountDialog(context, resId, onClickListener, + onCancelListener, true); + } + /** * When OnClickListener or OnCancelListener is null, uses a default listener. * The default OnCancelListener just closes itself with {@link Dialog#dismiss()}. */ public static Dialog getSelectAccountDialog(Context context, int resId, DialogInterface.OnClickListener onClickListener, - DialogInterface.OnCancelListener onCancelListener) { + DialogInterface.OnCancelListener onCancelListener, boolean includeSIM) { final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context); - final List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true); + List<AccountWithDataSet> writableAccountList = accountTypes.getAccounts(true); + if (includeSIM) { + writableAccountList = accountTypes.getAccounts(true); + } else { + writableAccountList = accountTypes.getAccounts(true, + AccountTypeManager.FLAG_ALL_ACCOUNTS_WITHOUT_SIM); + } Log.i(LOG_TAG, "The number of available accounts: " + writableAccountList.size()); @@ -145,6 +182,13 @@ public class AccountSelectionUtil { AccountSelectedListener accountSelectedListener = new AccountSelectedListener(context, writableAccountList, resId); onClickListener = accountSelectedListener; + } else if (onClickListener instanceof AccountSelectedListener) { + // Because the writableAccountList is different if includeSIM or not, so + // should reset the account list for the AccountSelectedListener which + // is initialized with FLAG_ALL_ACCOUNTS. + // Reset the account list to make sure the selected account is contained + // in these display accounts. + ((AccountSelectedListener) onClickListener).setAccountList(writableAccountList); } if (onCancelListener == null) { onCancelListener = new DialogInterface.OnCancelListener() { @@ -204,4 +248,70 @@ public class AccountSelectionUtil { mPath = null; context.startActivity(importIntent); } + + public static class SimSelectedListener + implements DialogInterface.OnClickListener { + + final private Context mContext; + final private AccountWithDataSet mAccount; + + public SimSelectedListener(Context context, AccountWithDataSet account) { + mContext = context; + mAccount = account; + } + + public void onClick(DialogInterface dialog, int which) { + Log.d(LOG_TAG, "onClick OK: mSelectedSim = " + mSelectedSim); + if (mSelectedSim != SIM_ID_INVALID) { + doImportFromSim(mContext, mAccount, mSelectedSim); + } + } + } + + private static void displaySelectSimDialog(Context context, + SimSelectedListener simSelListner) { + Log.d(LOG_TAG, "displaySelectSimDialog"); + + mSelectedSim = SIM_ID_INVALID; + + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.select_sim); + final int numPhones = TelephonyManager.getDefault().getPhoneCount(); + CharSequence[] subList = new CharSequence[numPhones + 1]; + int i; + for (i = 1; i <= numPhones; i++) { + subList[i-1] = "SIM" + i; + } + subList[i-1] = context.getString(R.string.import_contacts_from_all_cards); + builder.setSingleChoiceItems(subList, -1, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d(LOG_TAG, "onClicked Dialog on which = " + which); + mSelectedSim = which; + if (mSelectedSim == numPhones) { + mSelectedSim = IMPORT_FROM_ALL; + } + } + }); + + AlertDialog dialog = builder.create(); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, + context.getString(com.android.internal.R.string.ok), simSelListner); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString( + com.android.internal.R.string.cancel), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d(LOG_TAG, "onClicked Cancel"); + } + }); + + dialog.setOnDismissListener(new DialogInterface.OnDismissListener () { + @Override + public void onDismiss(DialogInterface dialog) { + Log.d(LOG_TAG, "onDismiss"); + Log.d(LOG_TAG, "Selected SUB = " + mSelectedSim); + } + }); + dialog.show(); + } } diff --git a/src/com/android/contacts/common/util/AccountsListAdapter.java b/src/com/android/contacts/common/util/AccountsListAdapter.java index 84435df8..2e1c44ae 100644..100755 --- a/src/com/android/contacts/common/util/AccountsListAdapter.java +++ b/src/com/android/contacts/common/util/AccountsListAdapter.java @@ -29,6 +29,8 @@ import com.android.contacts.common.R; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; +import com.android.contacts.common.model.account.PhoneAccountType; +import com.android.contacts.common.model.account.SimAccountType; import java.util.ArrayList; import java.util.List; @@ -48,7 +50,8 @@ public final class AccountsListAdapter extends BaseAdapter { public enum AccountListFilter { ALL_ACCOUNTS, // All read-only and writable accounts ACCOUNTS_CONTACT_WRITABLE, // Only where the account type is contact writable - ACCOUNTS_GROUP_WRITABLE // Only accounts where the account type is group writable + ACCOUNTS_GROUP_WRITABLE, // Only accounts where the account type is group writable + ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM } public AccountsListAdapter(Context context, AccountListFilter accountListFilter) { @@ -64,6 +67,11 @@ public final class AccountsListAdapter extends BaseAdapter { mContext = context; mAccountTypes = AccountTypeManager.getInstance(context); mAccounts = getAccounts(accountListFilter); + + // Add a virtual local storage account to allow user to store its contacts in the phone + String localAccountName = context.getString(R.string.local_storage_account); + mAccounts.add(0, new AccountWithDataSet(localAccountName, AccountType.LOCAL_ACCOUNT, null)); + if (currentAccount != null && !mAccounts.isEmpty() && !mAccounts.get(0).equals(currentAccount) @@ -75,10 +83,22 @@ public final class AccountsListAdapter extends BaseAdapter { private List<AccountWithDataSet> getAccounts(AccountListFilter accountListFilter) { if (accountListFilter == AccountListFilter.ACCOUNTS_GROUP_WRITABLE) { - return new ArrayList<AccountWithDataSet>(mAccountTypes.getGroupWritableAccounts()); + return new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts( + true, AccountTypeManager.FLAG_ALL_ACCOUNTS_WITHOUT_SIM)); } - return new ArrayList<AccountWithDataSet>(mAccountTypes.getAccounts( - accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE)); + final List<AccountWithDataSet> writableAccountList = mAccountTypes + .getAccounts(accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE + || accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM); + List<AccountWithDataSet> deletedList = new ArrayList<AccountWithDataSet>(); + + if (accountListFilter == AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM) { + for (AccountWithDataSet account : writableAccountList) { + if (SimAccountType.ACCOUNT_TYPE.equals(account.type)) + deletedList.add(account); + } + writableAccountList.removeAll(deletedList); + } + return writableAccountList; } @Override @@ -93,14 +113,20 @@ public final class AccountsListAdapter extends BaseAdapter { final AccountWithDataSet account = mAccounts.get(position); final AccountType accountType = mAccountTypes.getAccountType(account.type, account.dataSet); - text1.setText(accountType.getDisplayLabel(mContext)); + text1.setText(accountType.getDisplayLabel(mContext, account.name)); // For email addresses, we don't want to truncate at end, which might cut off the domain // name. + if (SimAccountType.ACCOUNT_TYPE.equals(account.type) + || PhoneAccountType.ACCOUNT_TYPE.equals(account.type)) { + text2.setVisibility(View.GONE); + } else { + text2.setVisibility(View.VISIBLE); + } text2.setText(account.name); text2.setEllipsize(TruncateAt.MIDDLE); - icon.setImageDrawable(accountType.getDisplayIcon(mContext)); + icon.setImageDrawable(accountType.getDisplayIcon(mContext, account.name)); return resultView; } diff --git a/src/com/android/contacts/common/util/TelephonyManagerUtils.java b/src/com/android/contacts/common/util/TelephonyManagerUtils.java index 7c322ca0..374743d1 100644 --- a/src/com/android/contacts/common/util/TelephonyManagerUtils.java +++ b/src/com/android/contacts/common/util/TelephonyManagerUtils.java @@ -15,12 +15,19 @@ */ package com.android.contacts.common.util; +import android.content.ComponentName; import android.content.Context; +import android.graphics.drawable.Drawable; +import android.telecom.PhoneAccount; +import android.telecom.PhoneAccountHandle; +import android.telecom.TelecomManager; import android.telephony.PhoneNumberUtils; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; +import java.util.List; import java.util.Locale; /** @@ -70,4 +77,70 @@ public class TelephonyManagerUtils { // TODO: Check the telephony manager's subscriptions to see if any support video calls. return true; } + + /** + * Retrieve the account metadata, but if the account does not exist or the device has only a + * single registered and enabled account, return null. + */ + private static PhoneAccount getAccountOrNull(Context context, + PhoneAccountHandle phoneAccount) { + final TelecomManager telecomManager = + (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); + final PhoneAccount account = telecomManager.getPhoneAccount(phoneAccount); + if (account == null || !telecomManager.hasMultipleCallCapableAccounts()) { + return null; + } + return account; + } + + /** + * Generate account info from data in Telecomm database + */ + public static PhoneAccountHandle getAccount(String componentString, + String accountId) { + if (TextUtils.isEmpty(componentString) || TextUtils.isEmpty(accountId)) { + return null; + } + final ComponentName componentName = ComponentName.unflattenFromString(componentString); + return new PhoneAccountHandle(componentName, accountId); + } + + /** + * Generate account icon from data in Telecomm database + */ + public static Drawable getAccountIcon(Context context, PhoneAccountHandle phoneAccount) { + final PhoneAccount account = getAccountOrNull(context, phoneAccount); + if (account == null) { + return null; + } + return account.createIconDrawable(context); + } + + public static Drawable getMultiSimIcon(Context context, int subscription) { + if (context == null) { + // If the context is null, return 0 as no resource found. + return null; + } + + int subId[] = SubscriptionManager.getSubId(subscription); + if (subId == null) { + return null; + } + final TelecomManager telecomManager = (TelecomManager) context + .getSystemService(Context.TELECOM_SERVICE); + List<PhoneAccountHandle> pHandles = telecomManager.getCallCapablePhoneAccounts(); + PhoneAccountHandle phoneAccountHandle = null; + for (PhoneAccountHandle itorator : pHandles) { + if (String.valueOf(subId[0]).equals(itorator.getId())) { + phoneAccountHandle = itorator; + } + } + + if (phoneAccountHandle == null) { + return null; + } + final PhoneAccount account = telecomManager + .getPhoneAccount(phoneAccountHandle); + return account.createIconDrawable(context); + } } diff --git a/src/com/android/contacts/common/vcard/ExportProcessor.java b/src/com/android/contacts/common/vcard/ExportProcessor.java index 791f2f96..72cfa426 100644 --- a/src/com/android/contacts/common/vcard/ExportProcessor.java +++ b/src/com/android/contacts/common/vcard/ExportProcessor.java @@ -56,6 +56,7 @@ public class ExportProcessor extends ProcessorBase { private volatile boolean mCanceled; private volatile boolean mDone; + private String selExport = ""; public ExportProcessor(VCardService service, ExportRequest exportRequest, int jobId, String callingActivity) { @@ -141,7 +142,7 @@ public class ExportProcessor extends ProcessorBase { final Uri contentUriForRawContactsEntity = RawContactsEntity.CONTENT_URI; // TODO: should provide better selection. if (!composer.init(Contacts.CONTENT_URI, new String[] {Contacts._ID}, - null, null, + selExport, null, null, contentUriForRawContactsEntity)) { final String errorReason = composer.getErrorReason(); Log.e(LOG_TAG, "initialization of vCard composer failed: " + errorReason); @@ -216,6 +217,10 @@ public class ExportProcessor extends ProcessorBase { } } + public void setSelExport(String sel) { + selExport = sel; + } + private String translateComposerError(String errorMessage) { final Resources resources = mService.getResources(); if (VCardComposer.FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO.equals(errorMessage)) { @@ -258,8 +263,8 @@ public class ExportProcessor extends ProcessorBase { final Intent intent = new Intent(); intent.setClassName(mService, mCallingActivity); final Notification notification = - NotificationImportExportListener.constructFinishNotification(mService, title, - description, intent); + NotificationImportExportListener.constructFinishNotification(mService, VCardService.TYPE_EXPORT, + title, description, intent); mNotificationManager.notify(NotificationImportExportListener.DEFAULT_NOTIFICATION_TAG, mJobId, notification); } diff --git a/src/com/android/contacts/common/vcard/ExportVCardActivity.java b/src/com/android/contacts/common/vcard/ExportVCardActivity.java index b86845e7..029561d0 100644 --- a/src/com/android/contacts/common/vcard/ExportVCardActivity.java +++ b/src/com/android/contacts/common/vcard/ExportVCardActivity.java @@ -35,6 +35,7 @@ import android.text.TextDirectionHeuristics; import android.text.TextUtils; import android.util.Log; +import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.R; import java.io.File; @@ -50,6 +51,7 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, DialogInterface.OnClickListener, DialogInterface.OnCancelListener { private static final String LOG_TAG = "VCardExport"; private static final boolean DEBUG = VCardService.DEBUG; + private String selExport = ""; /** * Handler used when some Message has come from {@link VCardService}. @@ -121,6 +123,8 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, // String for storing error reason temporarily. private String mErrorReason; + private int mSelectedStorage = VCardService.INTERNAL_PATH; + private class ExportConfirmationListener implements DialogInterface.OnClickListener { private final Uri mDestinationUri; @@ -140,6 +144,7 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, } final ExportRequest request = new ExportRequest(mDestinationUri); // The connection object will call finish(). + mService.setSelExport(selExport); mService.handleExportRequest(request, new NotificationImportExportListener( ExportVCardActivity.this)); } @@ -151,27 +156,15 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, protected void onCreate(Bundle bundle) { super.onCreate(bundle); - // Check directory is available. - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - Log.w(LOG_TAG, "External storage is in state " + Environment.getExternalStorageState() + - ". Cancelling export"); - showDialog(R.id.dialog_sdcard_not_found); - return; - } - - final File targetDirectory = Environment.getExternalStorageDirectory(); - if (!(targetDirectory.exists() && - targetDirectory.isDirectory() && - targetDirectory.canRead()) && - !targetDirectory.mkdirs()) { - showDialog(R.id.dialog_sdcard_not_found); - return; - } + checkStorage(); + } + private void runExportContacts() { final String callingActivity = getIntent().getExtras() .getString(VCardCommonArguments.ARG_CALLING_ACTIVITY); Intent intent = new Intent(this, VCardService.class); intent.putExtra(VCardCommonArguments.ARG_CALLING_ACTIVITY, callingActivity); + intent.putExtra(VCardService.STORAGE_PATH, mSelectedStorage); if (startService(intent) == null) { Log.e(LOG_TAG, "Failed to start vCard service"); @@ -186,6 +179,73 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, showDialog(R.id.dialog_fail_to_export_with_reason); } // Continued to onServiceConnected() + Intent selExportIntent = getIntent(); + if(selExportIntent != null) { + selExport = selExportIntent.getStringExtra("SelExport"); + } + } + + private void checkStorage() { + boolean sdExist = MoreContactUtils.sdCardExist(this); + boolean inExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); + if (sdExist && inExist) { + CharSequence[] storage_list = new CharSequence[2]; + storage_list[VCardService.INTERNAL_PATH] = Environment.getExternalStorageDirectory() + .getPath(); + storage_list[VCardService.EXTERNAL_PATH] = MoreContactUtils.getSDPath(this); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.select_path); + builder.setSingleChoiceItems(storage_list, 0, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d(LOG_TAG, "onClicked Dialog on which = " + which); + mSelectedStorage = which; + } + }); + + AlertDialog dialog = builder.create(); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(android.R.string.ok), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + runExportContacts(); + } + }); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mSelectedStorage = VCardService.INVALID_PATH; + } + }); + dialog.show(); + } else if (inExist) { + mSelectedStorage = VCardService.INTERNAL_PATH; + + // Check directory is available. + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + Log.w(LOG_TAG, "External storage is in state " + + Environment.getExternalStorageState() + ". Cancelling export"); + showDialog(R.id.dialog_sdcard_not_found); + return; + } + + final File targetDirectory = Environment.getExternalStorageDirectory(); + if (!(targetDirectory.exists() && + targetDirectory.isDirectory() && + targetDirectory.canRead()) && + !targetDirectory.mkdirs()) { + showDialog(R.id.dialog_sdcard_not_found); + return; + } + + runExportContacts(); + } else if (sdExist) { + mSelectedStorage = VCardService.EXTERNAL_PATH; + runExportContacts(); + } else { + mSelectedStorage = VCardService.INVALID_PATH; + } } @Override diff --git a/src/com/android/contacts/common/vcard/ImportVCardActivity.java b/src/com/android/contacts/common/vcard/ImportVCardActivity.java index 62e8431c..d36dcaf3 100644 --- a/src/com/android/contacts/common/vcard/ImportVCardActivity.java +++ b/src/com/android/contacts/common/vcard/ImportVCardActivity.java @@ -45,6 +45,7 @@ import android.text.style.RelativeSizeSpan; import android.util.Log; import android.widget.Toast; +import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.R; import com.android.contacts.common.model.AccountTypeManager; import com.android.contacts.common.model.account.AccountWithDataSet; @@ -122,6 +123,7 @@ public class ImportVCardActivity extends Activity { /* package */ VCardImportExportListener mListener; private String mErrorMessage; + private int mSelectedStorage = VCardService.INTERNAL_PATH; private Handler mHandler = new Handler(); @@ -882,7 +884,60 @@ public class ImportVCardActivity extends Activity { importVCard(uri); } else { Log.i(LOG_TAG, "Start vCard without Uri. The user will select vCard manually."); + checkStorage(); + } + } + + private void checkStorage() { + boolean sdExist = MoreContactUtils.sdCardExist(this); + boolean inExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); + if (sdExist && inExist) { + CharSequence[] storage_list = new CharSequence[2]; + storage_list[VCardService.INTERNAL_PATH] = Environment.getExternalStorageDirectory() + .getPath(); + storage_list[VCardService.EXTERNAL_PATH] = MoreContactUtils.getSDPath(this); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.select_path); + builder.setSingleChoiceItems(storage_list, 0, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Log.d(LOG_TAG, "onClicked Dialog on which = " + which); + mSelectedStorage = which; + } + }); + + AlertDialog dialog = builder.create(); + dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + mSelectedStorage = VCardService.INVALID_PATH; + finish(); + } + }); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(android.R.string.ok), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + doScanExternalStorageAndImportVCard(); + } + }); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mSelectedStorage = VCardService.INVALID_PATH; + finish(); + } + }); + dialog.show(); + } else if (inExist) { + mSelectedStorage = VCardService.INTERNAL_PATH; + doScanExternalStorageAndImportVCard(); + } else if (sdExist) { + mSelectedStorage = VCardService.EXTERNAL_PATH; doScanExternalStorageAndImportVCard(); + } else { + mSelectedStorage = VCardService.INVALID_PATH; } } @@ -993,7 +1048,26 @@ public class ImportVCardActivity extends Activity { */ private void doScanExternalStorageAndImportVCard() { // TODO: should use getExternalStorageState(). - final File file = Environment.getExternalStorageDirectory(); + Log.i(LOG_TAG, "Import Vcard from path:" + mSelectedStorage); + if (mSelectedStorage == VCardService.INVALID_PATH) + return; + File file; + switch (mSelectedStorage) { + case VCardService.INTERNAL_PATH: + file = Environment.getExternalStorageDirectory(); + break; + case VCardService.EXTERNAL_PATH: + final String sdcardPath = MoreContactUtils.getSDPath(this); + if (sdcardPath != null) { + file = new File(sdcardPath); + } else { + file = Environment.getExternalStorageDirectory(); + } + break; + default: + file = Environment.getExternalStorageDirectory(); + break; + } if (!file.exists() || !file.isDirectory() || !file.canRead()) { showDialog(R.id.dialog_sdcard_not_found); } else { diff --git a/src/com/android/contacts/common/vcard/NotificationImportExportListener.java b/src/com/android/contacts/common/vcard/NotificationImportExportListener.java index a85825f1..63420026 100644 --- a/src/com/android/contacts/common/vcard/NotificationImportExportListener.java +++ b/src/com/android/contacts/common/vcard/NotificationImportExportListener.java @@ -131,7 +131,7 @@ public class NotificationImportExportListener implements VCardImportExportListen } final Notification notification = NotificationImportExportListener.constructFinishNotification(mContext, - description, null, intent); + VCardService.TYPE_IMPORT, description, null, intent); mNotificationManager.notify(NotificationImportExportListener.DEFAULT_NOTIFICATION_TAG, jobId, notification); } @@ -261,11 +261,13 @@ public class NotificationImportExportListener implements VCardImportExportListen * @param intent Intent to be launched when the Notification is clicked. Can be null. */ /* package */ static Notification constructFinishNotification( - Context context, String title, String description, Intent intent) { + Context context, int type, String title, String description, Intent intent) { return new Notification.Builder(context) .setAutoCancel(true) + .setSmallIcon(type == VCardService.TYPE_IMPORT + ? android.R.drawable.stat_sys_download_done + : android.R.drawable.stat_sys_upload_done) .setColor(context.getResources().getColor(R.color.dialtacts_theme_color)) - .setSmallIcon(android.R.drawable.stat_sys_download_done) .setContentTitle(title) .setContentText(description) .setContentIntent(PendingIntent.getActivity(context, 0, diff --git a/src/com/android/contacts/common/vcard/SelectAccountActivity.java b/src/com/android/contacts/common/vcard/SelectAccountActivity.java index d05810db..5ee36bc6 100644 --- a/src/com/android/contacts/common/vcard/SelectAccountActivity.java +++ b/src/com/android/contacts/common/vcard/SelectAccountActivity.java @@ -24,6 +24,7 @@ import android.util.Log; import com.android.contacts.common.R; import com.android.contacts.common.model.AccountTypeManager; +import com.android.contacts.common.model.account.AccountType; import com.android.contacts.common.model.account.AccountWithDataSet; import com.android.contacts.common.util.AccountSelectionUtil; @@ -52,30 +53,25 @@ public class SelectAccountActivity extends Activity { protected void onCreate(Bundle bundle) { super.onCreate(bundle); - // There's three possibilities: - // - more than one accounts -> ask the user - // - just one account -> use the account without asking the user + // There are two possibilities: + // - one or more than one accounts -> ask the user (user can select phone-local also) // - no account -> use phone-local storage without asking the user final int resId = R.string.import_from_sdcard; final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this); final List<AccountWithDataSet> accountList = accountTypes.getAccounts(true); if (accountList.size() == 0) { - Log.w(LOG_TAG, "Account does not exist"); - finish(); - return; - } else if (accountList.size() == 1) { - final AccountWithDataSet account = accountList.get(0); - final Intent intent = new Intent(); - intent.putExtra(ACCOUNT_NAME, account.name); - intent.putExtra(ACCOUNT_TYPE, account.type); - intent.putExtra(DATA_SET, account.dataSet); - setResult(RESULT_OK, intent); + Log.w(LOG_TAG, "Select phone-local storage account"); finish(); return; } Log.i(LOG_TAG, "The number of available accounts: " + accountList.size()); + // Add a virtual local storage account to allow user to store its contacts in the phone + AccountWithDataSet localAccount = new AccountWithDataSet( + getString(R.string.local_storage_account), AccountType.LOCAL_ACCOUNT, null); + accountList.add(0, localAccount); + // Multiple accounts. Let users to select one. mAccountSelectionListener = new AccountSelectionUtil.AccountSelectedListener( @@ -83,12 +79,15 @@ public class SelectAccountActivity extends Activity { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); - final AccountWithDataSet account = mAccountList.get(which); - final Intent intent = new Intent(); - intent.putExtra(ACCOUNT_NAME, account.name); - intent.putExtra(ACCOUNT_TYPE, account.type); - intent.putExtra(DATA_SET, account.dataSet); - setResult(RESULT_OK, intent); + // Position 0 contains the phone-local account + if (which > 0) { + final AccountWithDataSet account = mAccountList.get(which); + final Intent intent = new Intent(); + intent.putExtra(ACCOUNT_NAME, account.name); + intent.putExtra(ACCOUNT_TYPE, account.type); + intent.putExtra(DATA_SET, account.dataSet); + setResult(RESULT_OK, intent); + } finish(); } }; diff --git a/src/com/android/contacts/common/vcard/VCardService.java b/src/com/android/contacts/common/vcard/VCardService.java index 0a50becc..7b90eddb 100644 --- a/src/com/android/contacts/common/vcard/VCardService.java +++ b/src/com/android/contacts/common/vcard/VCardService.java @@ -31,6 +31,7 @@ import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; +import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.R; import java.io.File; @@ -55,6 +56,10 @@ import java.util.concurrent.RejectedExecutionException; public class VCardService extends Service { private final static String LOG_TAG = "VCardService"; + public final static int INTERNAL_PATH = 0; + public final static int EXTERNAL_PATH = 1; + public final static int INVALID_PATH = -1; + public final static String STORAGE_PATH = "storage"; /* package */ final static boolean DEBUG = false; /* package */ static final int MSG_IMPORT_REQUEST = 1; @@ -71,7 +76,8 @@ public class VCardService extends Service { /* package */ static final int TYPE_EXPORT = 2; /* package */ static final String CACHE_FILE_PREFIX = "import_tmp_"; - + private String selExport = ""; + private int mStorage = INTERNAL_PATH; private class CustomMediaScannerConnectionClient implements MediaScannerConnectionClient { final MediaScannerConnection mConnection; @@ -150,7 +156,16 @@ public class VCardService extends Service { } private void initExporterParams() { - mTargetDirectory = Environment.getExternalStorageDirectory(); + if (mStorage == EXTERNAL_PATH) { + String targetDirectory = MoreContactUtils.getSDPath(this); + if (targetDirectory != null) { + mTargetDirectory = new File(targetDirectory); + } else { + mTargetDirectory = Environment.getExternalStorageDirectory(); + } + } else { + mTargetDirectory = Environment.getExternalStorageDirectory(); + } mFileNamePrefix = getString(R.string.config_export_file_prefix); mFileNameSuffix = getString(R.string.config_export_file_suffix); mFileNameExtension = getString(R.string.config_export_file_extension); @@ -179,9 +194,11 @@ public class VCardService extends Service { if (intent != null && intent.getExtras() != null) { mCallingActivity = intent.getExtras().getString( VCardCommonArguments.ARG_CALLING_ACTIVITY); + mStorage = intent.getExtras().getInt(STORAGE_PATH); } else { mCallingActivity = null; } + initExporterParams(); return START_STICKY; } @@ -232,7 +249,10 @@ public class VCardService extends Service { public synchronized void handleExportRequest(ExportRequest request, VCardImportExportListener listener) { - if (tryExecute(new ExportProcessor(this, request, mCurrentJobId, mCallingActivity))) { + ExportProcessor processor = new ExportProcessor(this, request, mCurrentJobId, + mCallingActivity); + processor.setSelExport(selExport); + if (tryExecute(processor)) { final String path = request.destUri.getEncodedPath(); if (DEBUG) Log.d(LOG_TAG, "Reserve the path " + path); if (!mReservedDestination.add(path)) { @@ -256,6 +276,10 @@ public class VCardService extends Service { } } + public void setSelExport(String sel) { + selExport = sel; + } + /** * Tries to call {@link ExecutorService#execute(Runnable)} toward a given processor. * @return true when successful. diff --git a/src/com/android/contacts/common/widget/CheckableFlipDrawable.java b/src/com/android/contacts/common/widget/CheckableFlipDrawable.java new file mode 100644 index 00000000..329b665c --- /dev/null +++ b/src/com/android/contacts/common/widget/CheckableFlipDrawable.java @@ -0,0 +1,300 @@ +package com.android.contacts.common.widget; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.Checkable; +import android.widget.QuickContactBadge; + +import com.android.contacts.common.R; + +public class CheckableFlipDrawable extends FlipDrawable implements + ValueAnimator.AnimatorUpdateListener { + + private final FrontDrawable mFrontDrawable; + private final CheckmarkDrawable mCheckmarkDrawable; + + private final ValueAnimator mCheckmarkScaleAnimator; + private final ValueAnimator mCheckmarkAlphaAnimator; + + private static final int POST_FLIP_DURATION_MS = 150; + + private static final float CHECKMARK_SCALE_BEGIN_VALUE = 0.2f; + private static final float CHECKMARK_ALPHA_BEGIN_VALUE = 0f; + + /** Must be <= 1f since the animation value is used as a percentage. */ + private static final float END_VALUE = 1f; + + public CheckableFlipDrawable(Drawable front, final Resources res, + final int checkBackgroundColor, final int flipDurationMs) { + super(new FrontDrawable(front), new CheckmarkDrawable(res, checkBackgroundColor), + flipDurationMs, 0 /* preFlipDurationMs */, POST_FLIP_DURATION_MS); + + mFrontDrawable = (FrontDrawable) mFront; + mCheckmarkDrawable = (CheckmarkDrawable) mBack; + + // We will create checkmark animations that are synchronized with the + // flipping animation. The entire delay + duration of the checkmark animation + // needs to equal the entire duration of the flip animation (where delay is 0). + + // The checkmark animation is in effect only when the back drawable is being shown. + // For the flip animation duration <pre>[_][]|[][_]<post> + // The checkmark animation will be |--delay--|-duration-| + + // Need delay to skip the first half of the flip duration. + final long animationDelay = mPreFlipDurationMs + mFlipDurationMs / 2; + // Actual duration is the second half of the flip duration. + final long animationDuration = mFlipDurationMs / 2 + mPostFlipDurationMs; + + mCheckmarkScaleAnimator = ValueAnimator.ofFloat(CHECKMARK_SCALE_BEGIN_VALUE, END_VALUE) + .setDuration(animationDuration); + mCheckmarkScaleAnimator.setStartDelay(animationDelay); + mCheckmarkScaleAnimator.addUpdateListener(this); + + mCheckmarkAlphaAnimator = ValueAnimator.ofFloat(CHECKMARK_ALPHA_BEGIN_VALUE, END_VALUE) + .setDuration(animationDuration); + mCheckmarkAlphaAnimator.setStartDelay(animationDelay); + mCheckmarkAlphaAnimator.addUpdateListener(this); + } + + public void setFront(Drawable front) { + mFrontDrawable.setInnerDrawable(front); + invalidateSelf(); + } + + public void setCheckMarkBackgroundColor(int color) { + mCheckmarkDrawable.setBackgroundColor(color); + invalidateSelf(); + } + + @Override + public void reset() { + super.reset(); + if (mCheckmarkScaleAnimator == null) { + // Call from super's constructor. Not yet initialized. + return; + } + mCheckmarkScaleAnimator.cancel(); + mCheckmarkAlphaAnimator.cancel(); + boolean side = getSideFlippingTowards(); + mCheckmarkDrawable.setScaleAnimatorValue(side ? CHECKMARK_SCALE_BEGIN_VALUE : END_VALUE); + mCheckmarkDrawable.setAlphaAnimatorValue(side ? CHECKMARK_ALPHA_BEGIN_VALUE : END_VALUE); + } + + @Override + public void flip() { + super.flip(); + // Keep the checkmark animators in sync with the flip animator. + if (mCheckmarkScaleAnimator.isStarted()) { + mCheckmarkScaleAnimator.reverse(); + mCheckmarkAlphaAnimator.reverse(); + } else { + if (!getSideFlippingTowards() /* front to back */) { + mCheckmarkScaleAnimator.start(); + mCheckmarkAlphaAnimator.start(); + } else /* back to front */ { + mCheckmarkScaleAnimator.reverse(); + mCheckmarkAlphaAnimator.reverse(); + } + } + } + + @Override + public void onAnimationUpdate(final ValueAnimator animation) { + //noinspection ConstantConditions + final float value = (Float) animation.getAnimatedValue(); + + if (animation == mCheckmarkScaleAnimator) { + mCheckmarkDrawable.setScaleAnimatorValue(value); + } else if (animation == mCheckmarkAlphaAnimator) { + mCheckmarkDrawable.setAlphaAnimatorValue(value); + } + } + + private static class FrontDrawable extends Drawable implements Drawable.Callback { + private Drawable mDrawable; + + public FrontDrawable(Drawable d) { + mDrawable = d; + mDrawable.setCallback(this); + } + + public void setInnerDrawable(Drawable d) { + mDrawable.setCallback(null); + mDrawable = d; + mDrawable.setCallback(this); + assignDrawableBounds(getBounds()); + invalidateSelf(); + } + + @Override + protected void onBoundsChange(final Rect bounds) { + super.onBoundsChange(bounds); + assignDrawableBounds(bounds); + } + + private void assignDrawableBounds(Rect bounds) { + int w = mDrawable.getIntrinsicWidth(); + int h = mDrawable.getIntrinsicHeight(); + if (w > 0 && h > 0) { + mDrawable.setBounds(0, 0, w, h); + } else { + mDrawable.setBounds(bounds); + } + } + + @Override + public void draw(final Canvas canvas) { + final Rect bounds = getBounds(); + if (!isVisible() || bounds.isEmpty()) { + return; + } + + int w = mDrawable.getIntrinsicWidth(); + int h = mDrawable.getIntrinsicHeight(); + + if (w <= 0 || h <= 0) { + mDrawable.draw(canvas); + } else { + final float widthScale = (float) bounds.width() / (float) w; + final float heightScale = (float) bounds.height() / (float) h; + final float scale = Math.max(widthScale, heightScale); + + canvas.save(); + canvas.scale(scale, scale); + canvas.translate(bounds.left, bounds.top); + mDrawable.draw(canvas); + canvas.restore(); + } + } + + @Override + public void setAlpha(final int alpha) { + mDrawable.setAlpha(alpha); + } + + @Override + public void setColorFilter(final ColorFilter cf) { + mDrawable.setColorFilter(cf); + } + + @Override + public int getOpacity() { + return mDrawable.getOpacity(); + } + + @Override + public void invalidateDrawable(final Drawable who) { + invalidateSelf(); + } + + @Override + public void scheduleDrawable(final Drawable who, final Runnable what, final long when) { + scheduleSelf(what, when); + } + + @Override + public void unscheduleDrawable(final Drawable who, final Runnable what) { + unscheduleSelf(what); + } + } + + private static class CheckmarkDrawable extends Drawable { + private static Bitmap sCheckMark; + + private final Paint mPaint; + + private float mScaleFraction; + private float mAlphaFraction; + + private static final Matrix sMatrix = new Matrix(); + + public CheckmarkDrawable(final Resources res, int backgroundColor) { + if (sCheckMark == null) { + sCheckMark = BitmapFactory.decodeResource(res, R.drawable.ic_check_wht_24dp); + } + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setFilterBitmap(true); + mPaint.setColor(backgroundColor); + } + + public void setBackgroundColor(int color) { + mPaint.setColor(color); + } + + @Override + public void draw(final Canvas canvas) { + final Rect bounds = getBounds(); + if (!isVisible() || bounds.isEmpty()) { + return; + } + + canvas.drawCircle(bounds.centerX(), bounds.centerY(), bounds.width() / 2, mPaint); + + // Scale the checkmark. + sMatrix.reset(); + sMatrix.setScale(mScaleFraction, mScaleFraction, sCheckMark.getWidth() / 2, + sCheckMark.getHeight() / 2); + sMatrix.postTranslate(bounds.centerX() - sCheckMark.getWidth() / 2, + bounds.centerY() - sCheckMark.getHeight() / 2); + + // Fade the checkmark. + final int oldAlpha = mPaint.getAlpha(); + // Interpolate the alpha. + mPaint.setAlpha((int) (oldAlpha * mAlphaFraction)); + canvas.drawBitmap(sCheckMark, sMatrix, mPaint); + // Restore the alpha. + mPaint.setAlpha(oldAlpha); + } + + @Override + public void setAlpha(final int alpha) { + mPaint.setAlpha(alpha); + } + + @Override + public void setColorFilter(final ColorFilter cf) { + mPaint.setColorFilter(cf); + } + + @Override + public int getOpacity() { + // Always a gray background. + return PixelFormat.OPAQUE; + } + + /** + * Set value as a fraction from 0f to 1f. + */ + public void setScaleAnimatorValue(final float value) { + final float old = mScaleFraction; + mScaleFraction = value; + if (old != mScaleFraction) { + invalidateSelf(); + } + } + + /** + * Set value as a fraction from 0f to 1f. + */ + public void setAlphaAnimatorValue(final float value) { + final float old = mAlphaFraction; + mAlphaFraction = value; + if (old != mAlphaFraction) { + invalidateSelf(); + } + } + } +} diff --git a/src/com/android/contacts/common/widget/CheckableImageView.java b/src/com/android/contacts/common/widget/CheckableImageView.java new file mode 100644 index 00000000..57bac3e0 --- /dev/null +++ b/src/com/android/contacts/common/widget/CheckableImageView.java @@ -0,0 +1,96 @@ +package com.android.contacts.common.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.Checkable; +import android.widget.ImageView; + +import com.android.contacts.common.R; + +public class CheckableImageView extends ImageView implements Checkable { + private boolean mChecked = false; + private int mCheckMarkBackgroundColor; + private CheckableFlipDrawable mDrawable; + + public CheckableImageView(Context context) { + super(context); + init(context); + } + + public CheckableImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public CheckableImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + public CheckableImageView(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context); + } + + private void init(Context context) { + TypedArray a = context.obtainStyledAttributes(android.R.styleable.Theme); + setCheckMarkBackgroundColor(a.getColor(android.R.styleable.Theme_colorPrimary, + context.getResources().getColor(R.color.people_app_theme_color))); + a.recycle(); + } + + public void setCheckMarkBackgroundColor(int color) { + mCheckMarkBackgroundColor = color; + if (mDrawable != null) { + mDrawable.setCheckMarkBackgroundColor(color); + } + } + + public void toggle() { + setChecked(!mChecked); + } + + @Override + public boolean isChecked() { + return mChecked; + } + + @Override + public void setChecked(boolean checked) { + setChecked(checked, true); + } + + public void setChecked(boolean checked, boolean animate) { + if (mChecked == checked) { + return; + } + + mChecked = checked; + applyCheckState(animate); + } + + @Override + public void setImageDrawable(Drawable d) { + if (d != null) { + if (mDrawable == null) { + mDrawable = new CheckableFlipDrawable(d, getResources(), + mCheckMarkBackgroundColor, 150); + applyCheckState(false); + } else { + mDrawable.setFront(d); + } + d = mDrawable; + } + super.setImageDrawable(d); + } + + private void applyCheckState(boolean animate) { + mDrawable.flipTo(!mChecked); + if (!animate) { + mDrawable.reset(); + } + } +} diff --git a/src/com/android/contacts/common/widget/CheckableQuickContactBadge.java b/src/com/android/contacts/common/widget/CheckableQuickContactBadge.java new file mode 100644 index 00000000..27b64660 --- /dev/null +++ b/src/com/android/contacts/common/widget/CheckableQuickContactBadge.java @@ -0,0 +1,98 @@ +package com.android.contacts.common.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.Checkable; +import android.widget.QuickContactBadge; + +import com.android.contacts.common.R; + +public class CheckableQuickContactBadge extends QuickContactBadge implements Checkable { + private boolean mChecked = false; + private int mCheckMarkBackgroundColor; + private CheckableFlipDrawable mDrawable; + + public CheckableQuickContactBadge(Context context) { + super(context); + init(context); + } + + public CheckableQuickContactBadge(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public CheckableQuickContactBadge(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } + + public CheckableQuickContactBadge(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context); + } + + private void init(Context context) { + TypedArray a = context.obtainStyledAttributes(android.R.styleable.Theme); + setCheckMarkBackgroundColor(a.getColor(android.R.styleable.Theme_colorPrimary, + context.getResources().getColor(R.color.people_app_theme_color))); + a.recycle(); + } + + public void setCheckMarkBackgroundColor(int color) { + mCheckMarkBackgroundColor = color; + if (mDrawable != null) { + mDrawable.setCheckMarkBackgroundColor(color); + } + } + + public void toggle() { + setChecked(!mChecked); + } + + @Override + public boolean isChecked() { + return mChecked; + } + + @Override + public void setChecked(boolean checked) { + setChecked(checked, true); + } + + public void setChecked(boolean checked, boolean animate) { + if (mChecked == checked) { + return; + } + + mChecked = checked; + if (mDrawable != null) { + applyCheckState(animate); + } + } + + @Override + public void setImageDrawable(Drawable d) { + if (d != null) { + if (mDrawable == null) { + mDrawable = new CheckableFlipDrawable(d, getResources(), + mCheckMarkBackgroundColor, 150); + applyCheckState(false); + } else { + mDrawable.setFront(d); + } + d = mDrawable; + } + super.setImageDrawable(d); + } + + private void applyCheckState(boolean animate) { + mDrawable.flipTo(!mChecked); + if (!animate) { + mDrawable.reset(); + } + } +} diff --git a/src/com/android/contacts/common/widget/FlipDrawable.java b/src/com/android/contacts/common/widget/FlipDrawable.java new file mode 100644 index 00000000..ba62e0fe --- /dev/null +++ b/src/com/android/contacts/common/widget/FlipDrawable.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.contacts.common.widget; + +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; + +/** + * A drawable that wraps two other drawables and allows flipping between them. The flipping + * animation is a 2D rotation around the y axis. + * + * <p/> + * The 3 durations are: (best viewed in documentation form) + * <pre> + * <pre>[_][]|[][_]<post> + * | | | + * V V V + * <pre>< flip ><post> + * </pre> + */ +public class FlipDrawable extends Drawable implements Drawable.Callback { + + /** + * The inner drawables. + */ + protected Drawable mFront; + protected final Drawable mBack; + + protected final int mFlipDurationMs; + protected final int mPreFlipDurationMs; + protected final int mPostFlipDurationMs; + private final ValueAnimator mFlipAnimator; + + private static final float END_VALUE = 2f; + + /** + * From 0f to END_VALUE. Determines the flip progress between mFront and mBack. 0f means + * mFront is fully shown, while END_VALUE means mBack is fully shown. + */ + private float mFlipFraction = 0f; + + /** + * True if flipping towards front, false if flipping towards back. + */ + private boolean mFlipToSide = true; + + /** + * Create a new FlipDrawable. The front is fully shown by default. + * + * <p/> + * The 3 durations are: (best viewed in documentation form) + * <pre> + * <pre>[_][]|[][_]<post> + * | | | + * V V V + * <pre>< flip ><post> + * </pre> + * + * @param front The front drawable. + * @param back The back drawable. + * @param flipDurationMs The duration of the actual flip. This duration includes both + * animating away one side and showing the other. + * @param preFlipDurationMs The duration before the actual flip begins. Subclasses can use this + * to add flourish. + * @param postFlipDurationMs The duration after the actual flip begins. Subclasses can use this + * to add flourish. + */ + public FlipDrawable(final Drawable front, final Drawable back, final int flipDurationMs, + final int preFlipDurationMs, final int postFlipDurationMs) { + if (front == null || back == null) { + throw new IllegalArgumentException("Front and back drawables must not be null."); + } + mFront = front; + mBack = back; + + mFront.setCallback(this); + mBack.setCallback(this); + + mFlipDurationMs = flipDurationMs; + mPreFlipDurationMs = preFlipDurationMs; + mPostFlipDurationMs = postFlipDurationMs; + + mFlipAnimator = ValueAnimator.ofFloat(0f, END_VALUE) + .setDuration(mPreFlipDurationMs + mFlipDurationMs + mPostFlipDurationMs); + mFlipAnimator.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(final ValueAnimator animation) { + final float old = mFlipFraction; + //noinspection ConstantConditions + mFlipFraction = (Float) animation.getAnimatedValue(); + if (old != mFlipFraction) { + invalidateSelf(); + } + } + }); + + reset(); + } + + @Override + protected void onBoundsChange(final Rect bounds) { + super.onBoundsChange(bounds); + if (bounds.isEmpty()) { + mFront.setBounds(0, 0, 0, 0); + mBack.setBounds(0, 0, 0, 0); + } else { + mFront.setBounds(bounds); + mBack.setBounds(bounds); + } + } + + @Override + public void draw(final Canvas canvas) { + final Rect bounds = getBounds(); + if (!isVisible() || bounds.isEmpty()) { + return; + } + + final Drawable inner = getSideShown() /* == front */ ? mFront : mBack; + + final float totalDurationMs = mPreFlipDurationMs + mFlipDurationMs + mPostFlipDurationMs; + + final float scaleX; + if (mFlipFraction / 2 <= mPreFlipDurationMs / totalDurationMs) { + // During pre-flip. + scaleX = 1; + } else if (mFlipFraction / 2 >= (totalDurationMs - mPostFlipDurationMs) / totalDurationMs) { + // During post-flip. + scaleX = 1; + } else { + // During flip. + final float flipFraction = mFlipFraction / 2; + final float flipMiddle = (mPreFlipDurationMs / totalDurationMs + + (totalDurationMs - mPostFlipDurationMs) / totalDurationMs) / 2; + final float distFraction = Math.abs(flipFraction - flipMiddle); + final float multiplier = 1 / (flipMiddle - (mPreFlipDurationMs / totalDurationMs)); + scaleX = distFraction * multiplier; + } + + canvas.save(); + // The flip is a simple 1 dimensional scale. + canvas.scale(scaleX, 1, bounds.exactCenterX(), bounds.exactCenterY()); + inner.draw(canvas); + canvas.restore(); + } + + @Override + public void setAlpha(final int alpha) { + mFront.setAlpha(alpha); + mBack.setAlpha(alpha); + } + + @Override + public void setColorFilter(final ColorFilter cf) { + mFront.setColorFilter(cf); + mBack.setColorFilter(cf); + } + + @Override + public int getOpacity() { + return resolveOpacity(mFront.getOpacity(), mBack.getOpacity()); + } + + @Override + protected boolean onLevelChange(final int level) { + return mFront.setLevel(level) || mBack.setLevel(level); + } + + @Override + public void invalidateDrawable(final Drawable who) { + invalidateSelf(); + } + + @Override + public void scheduleDrawable(final Drawable who, final Runnable what, final long when) { + scheduleSelf(what, when); + } + + @Override + public void unscheduleDrawable(final Drawable who, final Runnable what) { + unscheduleSelf(what); + } + + /** + * Stop animating the flip and reset to one side. + * @param side Pass true if reset to front, false if reset to back. + */ + public void reset() { + final float old = mFlipFraction; + mFlipAnimator.cancel(); + mFlipFraction = mFlipToSide ? 0f : 2f; + if (mFlipFraction != old) { + invalidateSelf(); + } + } + + /** + * Returns true if the front is shown. Returns false if the back is shown. + */ + public boolean getSideShown() { + final float totalDurationMs = mPreFlipDurationMs + mFlipDurationMs + mPostFlipDurationMs; + final float middleFraction = (mPreFlipDurationMs / totalDurationMs + + (totalDurationMs - mPostFlipDurationMs) / totalDurationMs) / 2; + return mFlipFraction / 2 < middleFraction; + } + + /** + * Returns true if the front is being flipped towards. Returns false if the back is being + * flipped towards. + */ + public boolean getSideFlippingTowards() { + return mFlipToSide; + } + + /** + * Starts an animated flip to the other side. If a flip animation is currently started, + * it will be reversed. + */ + public void flip() { + mFlipToSide = !mFlipToSide; + if (mFlipAnimator.isStarted()) { + mFlipAnimator.reverse(); + } else { + if (!mFlipToSide /* front to back */) { + mFlipAnimator.start(); + } else /* back to front */ { + mFlipAnimator.reverse(); + } + } + } + + /** + * Start an animated flip to a side. This works regardless of whether a flip animation is + * currently started. + * @param side Pass true if flip to front, false if flip to back. + */ + public void flipTo(final boolean side) { + if (mFlipToSide != side) { + flip(); + } + } + + /** + * Returns whether flipping is in progress. + */ + public boolean isFlipping() { + return mFlipAnimator.isStarted(); + } +} diff --git a/src/com/android/contacts/common/widget/FloatingActionButtonController.java b/src/com/android/contacts/common/widget/FloatingActionButtonController.java index 679eb7b4..15d68594 100644 --- a/src/com/android/contacts/common/widget/FloatingActionButtonController.java +++ b/src/com/android/contacts/common/widget/FloatingActionButtonController.java @@ -25,6 +25,7 @@ import android.view.View; import com.android.contacts.common.util.ViewUtil; import com.android.contacts.common.R; import com.android.phone.common.animation.AnimUtils; +import com.android.phone.common.animation.AnimUtils.AnimationCallback; /** * Controls the movement and appearance of the FAB (Floating Action Button). @@ -142,8 +143,12 @@ public class FloatingActionButtonController { * @param delayMs The delay for the effect, in milliseconds. */ public void scaleIn(int delayMs) { + scaleIn(delayMs, null); + } + + public void scaleIn(int delayMs, AnimationCallback callback) { setVisible(true); - AnimUtils.scaleIn(mFloatingActionButtonContainer, FAB_SCALE_IN_DURATION, delayMs); + AnimUtils.scaleIn(mFloatingActionButtonContainer, FAB_SCALE_IN_DURATION, delayMs, callback); AnimUtils.fadeIn(mFloatingActionButton, FAB_SCALE_IN_DURATION, delayMs + FAB_SCALE_IN_FADE_IN_DELAY, null); } @@ -153,10 +158,14 @@ public class FloatingActionButtonController { * an animation for hiding the floating action button. */ public void scaleOut() { - AnimUtils.scaleOut(mFloatingActionButtonContainer, mAnimationDuration); + scaleOut(null); + } + + public void scaleOut(AnimationCallback callback) { + AnimUtils.scaleOut(mFloatingActionButtonContainer, mAnimationDuration, callback); // Fade out the icon faster than the scale out animation, so that the icon scaling is less // obvious. We don't want it to scale, but the resizing the container is not as performant. - AnimUtils.fadeOut(mFloatingActionButton, FAB_ICON_FADE_OUT_DURATION, null); + AnimUtils.fadeOut(mFloatingActionButton, FAB_ICON_FADE_OUT_DURATION); } /** |