summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdnan <adnan@cyngn.com>2014-09-03 12:21:41 -0700
committerAdnan <adnan@cyngn.com>2014-09-03 12:21:41 -0700
commit5b1c3ec10fed8585fccb47e66ad70dbc9e8f0714 (patch)
treeef63e473015c5dec8b6c2bd58cd2715e08eadcf1
parent7e71900b03360c0f8b86add6c2e8f1f3f1c34699 (diff)
downloadpackages_apps_Contacts-5b1c3ec10fed8585fccb47e66ad70dbc9e8f0714.tar.gz
packages_apps_Contacts-5b1c3ec10fed8585fccb47e66ad70dbc9e8f0714.tar.bz2
packages_apps_Contacts-5b1c3ec10fed8585fccb47e66ad70dbc9e8f0714.zip
Contacts: Rewrite local group edit activity.
- Tabhosts are so API level 9. - Create contextual action bar - Fix layouts Change-Id: Ided714358e27b8f012d2e63837d9a0c698821bfb
-rw-r--r--AndroidManifest.xml2
-rw-r--r--res/drawable-hdpi/ic_menu_content_cut.pngbin0 -> 1138 bytes
-rw-r--r--res/drawable-hdpi/ic_menu_content_discard.pngbin0 -> 1090 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_content_cut.pngbin0 -> 721 bytes
-rw-r--r--res/drawable-mdpi/ic_menu_content_discard.pngbin0 -> 689 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_content_cut.pngbin0 -> 1565 bytes
-rw-r--r--res/drawable-xhdpi/ic_menu_content_discard.pngbin0 -> 1394 bytes
-rw-r--r--res/drawable-xxhdpi/ic_menu_content_cut.pngbin0 -> 2491 bytes
-rw-r--r--res/drawable-xxhdpi/ic_menu_content_discard.pngbin0 -> 2162 bytes
-rw-r--r--res/layout/group_manage.xml92
-rw-r--r--res/layout/member_item.xml7
-rw-r--r--res/menu/member_list_options.xml21
-rw-r--r--res/menu/member_list_options_cab.xml25
-rw-r--r--res/values/cm_strings.xml1
-rw-r--r--res/xml/group_edit.xml47
-rw-r--r--src/com/android/contacts/group/local/GroupEditActivity.java522
-rw-r--r--src/com/android/contacts/group/local/MemberListActivity.java513
17 files changed, 484 insertions, 746 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d8e0ada58..5ffc13787 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -455,8 +455,6 @@
<activity android:name=".common.vcard.ExportVCardActivity"
android:theme="@style/BackgroundOnlyTheme" />
- <activity android:name=".group.local.GroupEditActivity" />
-
<activity android:name=".group.local.MemberListActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Holo.Light">
diff --git a/res/drawable-hdpi/ic_menu_content_cut.png b/res/drawable-hdpi/ic_menu_content_cut.png
new file mode 100644
index 000000000..58b5e49af
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_content_cut.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_content_discard.png b/res/drawable-hdpi/ic_menu_content_discard.png
new file mode 100644
index 000000000..ece5ad8d6
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_content_discard.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_content_cut.png b/res/drawable-mdpi/ic_menu_content_cut.png
new file mode 100644
index 000000000..91f267d8b
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_content_cut.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_content_discard.png b/res/drawable-mdpi/ic_menu_content_discard.png
new file mode 100644
index 000000000..93483b6cb
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_content_discard.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_content_cut.png b/res/drawable-xhdpi/ic_menu_content_cut.png
new file mode 100644
index 000000000..5885fcf94
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_content_cut.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_content_discard.png b/res/drawable-xhdpi/ic_menu_content_discard.png
new file mode 100644
index 000000000..94f7c8c1c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_content_discard.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_content_cut.png b/res/drawable-xxhdpi/ic_menu_content_cut.png
new file mode 100644
index 000000000..dd5c2a38f
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_content_cut.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_content_discard.png b/res/drawable-xxhdpi/ic_menu_content_discard.png
new file mode 100644
index 000000000..df7526973
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_content_discard.png
Binary files differ
diff --git a/res/layout/group_manage.xml b/res/layout/group_manage.xml
index 150b403c4..a5e720ced 100644
--- a/res/layout/group_manage.xml
+++ b/res/layout/group_manage.xml
@@ -29,80 +29,34 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<TabHost
- android:id="@android:id/tabhost"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android">
+ android:id="@android:id/tabhost"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
- <FrameLayout
- android:id="@android:id/tabcontent"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="0" />
-
- <TabWidget
- android:id="@android:id/tabs"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:visibility="gone" />
-
- <TextView android:id="@+id/emptyText"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:text="@string/noMember"
- android:textSize="20sp"
- android:textColor="?android:attr/textColorSecondary"
- android:paddingLeft="10dip"
- android:paddingRight="10dip"
- android:paddingTop="10dip"
- android:gravity="center"
- android:lineSpacingMultiplier="0.92"/>
-
- <ListView
- android:layout_weight="1"
- android:id="@+id/member_list"
- android:visibility="gone"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <LinearLayout android:id="@+id/tool_bar"
- android:layout_weight="0"
- android:orientation="horizontal"
- android:visibility="gone"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="5dip"
- android:paddingLeft="4dip"
- android:paddingRight="4dip"
- android:paddingBottom="1dip"
- android:background="@android:drawable/bottom_bar">
-
- <Button
- android:id="@+id/btn_delete"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:text="@string/button_delete" />
-
- <Button
- android:id="@+id/btn_move"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:text="@string/button_moveto" />
-
- <Button
- android:id="@+id/btn_cancel"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:text="@string/button_cancel" />
- </LinearLayout>
+ <TextView android:id="@+id/emptyText"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:text="@string/noMember"
+ android:textSize="20sp"
+ android:textColor="?android:attr/textColorSecondary"
+ android:paddingLeft="10dip"
+ android:paddingRight="10dip"
+ android:paddingTop="10dip"
+ android:gravity="center"
+ android:lineSpacingMultiplier="0.92"/>
+
+ <ListView
+ android:layout_weight="1"
+ android:id="@+id/member_list"
+ android:visibility="gone"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
</LinearLayout>
</TabHost>
diff --git a/res/layout/member_item.xml b/res/layout/member_item.xml
index 04c9d7e63..0ac8239a9 100644
--- a/res/layout/member_item.xml
+++ b/res/layout/member_item.xml
@@ -43,8 +43,8 @@
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="1"
- android:paddingLeft="3dip"
- android:paddingRight="3dip">
+ android:paddingLeft="5dip"
+ android:paddingRight="5dip">
<QuickContactBadge
android:layout_width="48dip"
android:layout_height="48dip"
@@ -54,7 +54,8 @@
<TextView
android:layout_weight="1"
- android:gravity="right"
+ android:gravity="left"
+ android:paddingLeft="3dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
diff --git a/res/menu/member_list_options.xml b/res/menu/member_list_options.xml
new file mode 100644
index 000000000..0992da3df
--- /dev/null
+++ b/res/menu/member_list_options.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/add"
+ android:icon="@drawable/ic_menu_add_field_holo_light"
+ android:title="@string/title_add_members"
+ android:showAsAction="always" />
+</menu> \ No newline at end of file
diff --git a/res/menu/member_list_options_cab.xml b/res/menu/member_list_options_cab.xml
new file mode 100644
index 000000000..9c41e4e3c
--- /dev/null
+++ b/res/menu/member_list_options_cab.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/move"
+ android:icon="@drawable/ic_menu_content_cut"
+ android:title="@string/button_moveto"
+ android:showAsAction="always" />
+ <item android:id="@+id/remove"
+ android:icon="@drawable/ic_menu_content_discard"
+ android:title="@string/button_delete"
+ android:showAsAction="always" />
+</menu> \ No newline at end of file
diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml
index 2ffcde95b..bba1b247b 100644
--- a/res/values/cm_strings.xml
+++ b/res/values/cm_strings.xml
@@ -215,6 +215,7 @@
<string name="menu_sync_to_baidu_cloud">Sync to Baidu Cloud Now</string>
<string name="delete_locale_group_dialog_message">Confirm group deletion?</string>
+ <string name="edit_local_group_dialog_title">Rename group</string>
<string name="too_many_contacts_add_to_group">Too many contacts, must be fewer than <xliff:g id="count">%d</xliff:g></string>
diff --git a/res/xml/group_edit.xml b/res/xml/group_edit.xml
deleted file mode 100644
index 239924b47..000000000
--- a/res/xml/group_edit.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- * Copyright (c) 2013, 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.
- -->
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/title_group_edit">
- <EditTextPreference
- android:key="group_title"
- android:dialogTitle="@string/title_group_name"
- android:persistent="false"
- android:summary="@string/title_group_name"/>
-
- <PreferenceScreen
- android:key="group_member"
- android:title="@string/title_add_members"
- android:summary="@string/summary_add_members"
- android:persistent="false" />
-
- <PreferenceCategory
- android:title="@string/title_members_list"/>
-</PreferenceScreen>
diff --git a/src/com/android/contacts/group/local/GroupEditActivity.java b/src/com/android/contacts/group/local/GroupEditActivity.java
deleted file mode 100644
index c3164c797..000000000
--- a/src/com/android/contacts/group/local/GroupEditActivity.java
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * Copyright (C) 2013,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.group.local;
-
-import android.app.AlertDialog;
-import android.app.AlertDialog.Builder;
-import android.app.ProgressDialog;
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.preference.EditTextPreference;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.provider.ContactsContract;
-import android.provider.LocalGroups;
-import android.provider.ContactsContract.CommonDataKinds.LocalGroup;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.LocalGroups.Group;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.Toast;
-
-import com.android.contacts.R;
-import com.android.contacts.editor.MultiPickContactActivity;
-import com.android.contacts.common.list.AccountFilterActivity;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.SimContactsConstants;
-import com.android.contacts.common.model.account.PhoneAccountType;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-
-public class GroupEditActivity extends PreferenceActivity implements OnPreferenceChangeListener,
- OnPreferenceClickListener, TextWatcher {
-
- private static final String TAG = GroupEditActivity.class.getSimpleName();
-
- private static final String KEY_TITLE = "group_title";
-
- private static final String KEY_MEMBER = "group_member";
-
- private EditTextPreference titleView;
-
- private Group group;
-
- private PreferenceScreen addMemberView;
-
- private static final int CODE_PICK_MEMBER = 1;
- private AddMembersTask mAddMembersTask;
-
- // indicate whether the task is canceled.
- private boolean mIsAddMembersTaskCanceled;
-
- private static final int MSG_CANCEL = 1;
-
- private int mChangeStartPos;
- private int mChangeCount;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- this.addPreferencesFromResource(R.xml.group_edit);
- titleView = (EditTextPreference) this.findPreference(KEY_TITLE);
- titleView.getEditText().addTextChangedListener(this);
- titleView.setOnPreferenceChangeListener(this);
- addMemberView = (PreferenceScreen) this.findPreference(KEY_MEMBER);
- addMemberView.setOnPreferenceClickListener(this);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- group = Group.restoreGroupById(getContentResolver(),
- Long.parseLong(getIntent().getData().getLastPathSegment()));
- initView();
- }
-
- private void initView() {
- // avoid group is null, only for Monkey test.
- if (group != null) {
- // If the length of group name is more than GROUP_NAME_MAX_LENGTH,
- // the
- // name will be limited here.
- String groupName = group.getTitle();
- if (groupName.length() > AddLocalGroupDialog.GROUP_NAME_MAX_LENGTH) {
- groupName = groupName.substring(0, AddLocalGroupDialog.GROUP_NAME_MAX_LENGTH);
- }
- titleView.setTitle(groupName);
- titleView.setText(groupName);
- }
- }
-
- @Override
- public boolean onPreferenceChange(Preference arg0, Object arg1) {
- if (titleView == arg0 && !group.getTitle().equals(arg1) && ((String) arg1).length() > 0) {
- if (checkGroupTitleExist((String) arg1)) {
- Toast.makeText(getApplicationContext(), R.string.error_group_exist,
- Toast.LENGTH_SHORT).show();
- } else {
- group.setTitle((String) arg1);
- if (group.update(getContentResolver()))
- initView();
- }
- }
- return false;
- }
-
- private boolean checkGroupTitleExist(String name) {
- Cursor c = null;
- try {
- c = getApplicationContext().getContentResolver().query(
- LocalGroups.CONTENT_URI, null, LocalGroups.GroupColumns.TITLE + "=?",
- new String[] {
- name
- }, null);
- if (c != null) {
- return c.getCount() > 0;
- } else {
- return false;
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (addMemberView == preference) {
- pickMembers();
- }
- return false;
- }
-
- private void pickMembers() {
- Intent intent = new Intent(MultiPickContactActivity.ACTION_MULTI_PICK);
- intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
- intent.putExtra(MultiPickContactActivity.IS_CONTACT,true);
- intent.setClass(this, MultiPickContactActivity.class);
- ContactListFilter filter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ACCOUNT,
- PhoneAccountType.ACCOUNT_TYPE, SimContactsConstants.PHONE_NAME, null, null);
- intent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER, filter);
- startActivityForResult(intent, CODE_PICK_MEMBER);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- menu.add(0, 0, 0, R.string.menu_option_delete);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case 0:
- new AlertDialog.Builder(this)
- .setMessage(R.string.delete_locale_group_dialog_message)
- .setTitle(R.string.delete_group_dialog_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setPositiveButton(R.string.btn_ok, new OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- if (group.delete(getContentResolver())) {
- finish();
- }
- }
- }).setNegativeButton(R.string.btn_cancel, new OnClickListener() {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // TODO Auto-generated method stub
- // Don't need any operation
- }
- }).show();
-
- break;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (resultCode == RESULT_OK)
- switch (requestCode) {
- case CODE_PICK_MEMBER:
- Bundle result = data.getExtras().getBundle("result");
-
- // define member object mAddMembersTask to use later.
- mAddMembersTask = new AddMembersTask(result);
- mAddMembersTask.execute();
- }
- }
-
- class AddMembersTask extends AsyncTask<Object, Object, Object> {
- private ProgressDialog mProgressDialog;
-
- private Handler alertHandler = new Handler() {
- @Override
- public void dispatchMessage(Message msg) {
- if (msg.what == MSG_CANCEL) {
- Toast.makeText(GroupEditActivity.this, R.string.add_member_task_canceled,
- Toast.LENGTH_LONG).show();
- } else if (msg.what == 0) {
- Toast.makeText(GroupEditActivity.this, R.string.toast_not_add,
- Toast.LENGTH_LONG)
- .show();
- }
- }
- };
-
- private Bundle result;
-
- private int size;
-
- AddMembersTask(Bundle result) {
- size = result.size();
- this.result = result;
- HandlerThread thread = new HandlerThread("DownloadTask");
- thread.start();
- }
-
- protected void onPostExecute(Object result) {
- if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
- }
- new LocalGroupCountTask(GroupEditActivity.this).execute();
- }
-
- @Override
- protected void onPreExecute() {
- mIsAddMembersTaskCanceled = false;
- mProgressDialog = new ProgressDialog(GroupEditActivity.this);
- mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- mProgressDialog.setProgress(0);
- mProgressDialog.setMax(size);
- mProgressDialog.show();
- mProgressDialog.setOnCancelListener(new OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
-
- // if dialog is canceled, cancel the task also.
- mIsAddMembersTaskCanceled = true;
- }
- });
- }
-
- @Override
- protected Bundle doInBackground(Object... params) {
- proccess();
- return null;
- }
-
- public void proccess() {
- boolean hasInvalide = false;
- int progressIncrement = 0;
- ContentValues values = new ContentValues();
- // add Non-null protection of group for monkey test
- if (null != group) {
- values.put(LocalGroup.DATA1, group.getId());
- }
-
- Set<String> keySet = result.keySet();
- Iterator<String> it = keySet.iterator();
-
- // add a ContentProviderOperation update list.
- final ArrayList<ContentProviderOperation> updateList =
- new ArrayList<ContentProviderOperation>();
- ContentProviderOperation.Builder builder = null;
- mIsAddMembersTaskCanceled = false;
- while (it.hasNext()) {
- if (mIsAddMembersTaskCanceled) {
- alertHandler.sendEmptyMessage(MSG_CANCEL);
- break;
- }
- if (progressIncrement++ % 2 == 0) {
- if (mProgressDialog != null) {
- mProgressDialog.incrementProgressBy(2);
- } else if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
- mProgressDialog = null;
- }
- }
- String id = it.next();
- Cursor c = null;
- try {
- c = getContentResolver().query(RawContacts.CONTENT_URI, new String[] {
- RawContacts._ID, RawContacts.ACCOUNT_TYPE
- }, RawContacts.CONTACT_ID + "=?", new String[] {
- id
- }, null);
- if (c.moveToNext()) {
- String rawId = String.valueOf(c.getLong(0));
-
- if (!PhoneAccountType.ACCOUNT_TYPE.equals(c.getString(1))) {
- hasInvalide = true;
- continue;
- }
-
- builder = ContentProviderOperation.newDelete(Data.CONTENT_URI);
- builder.withSelection(Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE
- + "=?", new String[] {
- rawId, LocalGroup.CONTENT_ITEM_TYPE
- });
-
- // add the delete operation to the update list.
- updateList.add(builder.build());
-
- builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
- // add Non-null protection of group for monkey test
- if (null != group) {
- builder.withValue(LocalGroup.DATA1, group.getId());
- }
- builder.withValue(Data.RAW_CONTACT_ID, rawId);
- builder.withValue(Data.MIMETYPE, LocalGroup.CONTENT_ITEM_TYPE);
-
- // add the insert operation to the update list.
- updateList.add(builder.build());
- }
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
- // if task is canceled ,still update the database with the data in
- // updateList.
-
- // apply batch to execute the delete and insert operation.
- if (updateList.size() > 0) {
- addMembersApplyBatchByBuffer(updateList, getContentResolver());
- }
- if (hasInvalide) {
- alertHandler.sendEmptyMessage(0);
- }
- }
-
- private void addMembersApplyBatchByBuffer(ArrayList<ContentProviderOperation> list,
- ContentResolver cr) {
- final ArrayList<ContentProviderOperation> temp =
- new ArrayList<ContentProviderOperation>(BUFFER_LENGTH);
- int bufferSize = list.size() / BUFFER_LENGTH;
- for (int index = 0; index <= bufferSize; index++) {
- temp.clear();
- if (index == bufferSize) {
- for (int i = index * BUFFER_LENGTH; i < list.size(); i++) {
- temp.add(list.get(i));
- }
- } else {
- for (int i = index * BUFFER_LENGTH; i < index * BUFFER_LENGTH + BUFFER_LENGTH;
- i++) {
- temp.add(list.get(i));
- }
- }
- if (!temp.isEmpty()) {
- try {
- cr.applyBatch(ContactsContract.AUTHORITY, temp);
- if (mProgressDialog != null) {
- mProgressDialog.incrementProgressBy(temp.size() / 4);
- } else if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
- mProgressDialog = null;
- }
- } catch (Exception e) {
- Log.e(TAG, "apply batch by buffer error:" + e);
- }
- }
- }
- }
- }
-
- /**
- * the max length of applyBatch is 500
- */
- private static final int BUFFER_LENGTH = 499;
-
- public static void applyBatchByBuffer(ArrayList<ContentProviderOperation> list,
- ContentResolver cr) {
- final ArrayList<ContentProviderOperation> temp = new ArrayList<ContentProviderOperation>(
- BUFFER_LENGTH);
- int bufferSize = list.size() / BUFFER_LENGTH;
- for (int index = 0; index <= bufferSize; index++) {
- temp.clear();
- if (index == bufferSize) {
- for (int i = index * BUFFER_LENGTH; i < list.size(); i++) {
- temp.add(list.get(i));
- }
- } else {
- for (int i = index * BUFFER_LENGTH; i < index * BUFFER_LENGTH + BUFFER_LENGTH;
- i++) {
- temp.add(list.get(i));
- }
- }
- if (!temp.isEmpty()) {
- try {
- cr.applyBatch(ContactsContract.AUTHORITY, temp);
- } catch (Exception e) {
- Log.e(TAG, "apply batch by buffer error:" + e);
- }
- }
- }
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // The start position of new added characters.
- mChangeStartPos = start;
- // The number of new added characters.
- mChangeCount = count;
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- String name = s.toString();
- int len = 0;
- // The end position of insert string.
- int insertEnd = mChangeStartPos + mChangeCount - 1;
- // The string need to keep.
- String keepStr = name.substring(insertEnd + 1);
- // Keep string len.
- int keepStrCharLen = 0;
- for (int n = 0; n < keepStr.length(); n++) {
- // Get the char length of keep string.
- // To get the char number need insert.
- keepStrCharLen += getCharacterVisualLength(keepStr, n);
- }
- String headStr = name.substring(0, insertEnd + 1);
- for (int i = 0; i < headStr.length(); i++) {
- int ch = Character.codePointAt(name, i);
- len += getCharacterVisualLength(name, i);
- if (len > AddLocalGroupDialog.GROUP_NAME_MAX_LENGTH - keepStrCharLen || ch == 10) {
- // Delete the redundant text.
- s.delete(i, s.length() - keepStr.length());
- // Use setTextKeepState to keep the cursor position.
- titleView.getEditText().setTextKeepState(s);
- break;
- }
- }
- }
-
- /**
- * A character beyond 0xff is twice as big as a character within 0xff in
- * width when showing.
- */
- private int getCharacterVisualLength(String seq, int index) {
- int cp = Character.codePointAt(seq, index);
- if (cp >= 0x00 && cp <= 0xFF) {
- return 1;
- } else {
- return 2;
- }
- }
-
- @Override
- protected void onStop() {
-
- // dismiss dialog and cancel the task in order to avoid a case that
- // GroupEditActivity does
- // not exist,but task is going on in background, then onPostExecute()
- // will cause Exception.
- if (mAddMembersTask != null && mAddMembersTask.mProgressDialog != null) {
- if (mAddMembersTask.mProgressDialog.isShowing()) {
- mAddMembersTask.mProgressDialog.dismiss();
- mIsAddMembersTaskCanceled = true;
- }
- }
- super.onStop();
- }
-}
diff --git a/src/com/android/contacts/group/local/MemberListActivity.java b/src/com/android/contacts/group/local/MemberListActivity.java
index 711cd3f40..41b012f17 100644
--- a/src/com/android/contacts/group/local/MemberListActivity.java
+++ b/src/com/android/contacts/group/local/MemberListActivity.java
@@ -29,11 +29,14 @@
package com.android.contacts.group.local;
+import android.app.ActionBar;
+import android.app.Activity;
import android.app.AlertDialog;
-import android.app.TabActivity;
+import android.app.ProgressDialog;
import android.content.AsyncQueryHandler;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
@@ -48,8 +51,10 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Message;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.LocalGroup;
@@ -58,39 +63,43 @@ import android.provider.ContactsContract.Contacts.Photo;
import android.provider.ContactsContract.Data;
import android.provider.LocalGroups;
import android.provider.LocalGroups.GroupColumns;
+import android.text.TextUtils;
import android.util.Log;
+import android.view.ActionMode;
import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
+import android.widget.AbsListView;
import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CursorAdapter;
+import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.QuickContactBadge;
-import android.widget.TabHost;
import android.widget.TextView;
+import android.widget.Toast;
import com.android.contacts.R;
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.SimContactsConstants;
+import com.android.contacts.common.list.AccountFilterActivity;
+import com.android.contacts.common.list.ContactListFilter;
+import com.android.contacts.common.model.account.PhoneAccountType;
+import com.android.contacts.editor.MultiPickContactActivity;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
-public class MemberListActivity extends TabActivity implements OnItemClickListener,
- OnClickListener, OnItemLongClickListener {
+public class MemberListActivity extends Activity implements AdapterView.OnItemClickListener {
- private static final String TAB_TAG = "groups";
-
- private TabHost mTabHost;
+ private static final int CODE_PICK_MEMBER = 1;
private Uri uri;
@@ -119,19 +128,16 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
private MemberListAdapter mAdapter;
- private ListView listView;
-
- private TextView emptyText;
-
- private Bundle removeSet;
+ private AddMembersTask mAddMembersTask;
+ private LocalGroups.Group mGroup;
- private View toolsBar;
+ private ActionMode mActionMode;
- private Button deleteBtn;
+ private ListView mListView;
- private Button moveBtn;
+ private TextView emptyText;
- private Button cancelBtn;
+ private Bundle mRemoveSet;
private DeleteMembersThread mDeleteMembersTask;
@@ -143,7 +149,7 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
@Override
public void handleMessage(Message msg) {
mDeleteMembersTask = null;
- removeSet.clear();
+ mRemoveSet.clear();
mAdapter.refresh();
new LocalGroupCountTask(MemberListActivity.this).execute();
}
@@ -165,7 +171,7 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
this.mRemoveSet = removeSet;
}
- public int getStaus() {
+ public int getStatus() {
return status;
}
@@ -259,29 +265,103 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
super.onCreate(savedInstanceState);
setContentView(R.layout.group_manage);
- toolsBar = findViewById(R.id.tool_bar);
- deleteBtn = (Button) toolsBar.findViewById(R.id.btn_delete);
- moveBtn = (Button) toolsBar.findViewById(R.id.btn_move);
- cancelBtn = (Button) toolsBar.findViewById(R.id.btn_cancel);
- deleteBtn.setOnClickListener(this);
- moveBtn.setOnClickListener(this);
- cancelBtn.setOnClickListener(this);
+ // actionbar setup
+ final ActionBar actionBar = getActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
- removeSet = new Bundle();
+ mRemoveSet = new Bundle();
mQueryHandler = new QueryHandler(this);
mAdapter = new MemberListAdapter(this);
mContactPhotoManager = ContactPhotoManager.getInstance(this);
emptyText = (TextView) findViewById(R.id.emptyText);
- listView = (ListView) findViewById(R.id.member_list);
- listView.setOnItemClickListener(this);
- listView.setOnItemLongClickListener(this);
- listView.setAdapter(mAdapter);
- mTabHost = getTabHost();
+ mListView = (ListView) findViewById(R.id.member_list);
+ mListView.setAdapter(mAdapter);
+ mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ mListView.setOnItemClickListener(this);
+ mListView.setMultiChoiceModeListener(mMultiChoiceModeListener);
uri = getIntent().getParcelableExtra("data");
- addEditView();
getContentResolver().registerContentObserver(
Uri.withAppendedPath(LocalGroup.CONTENT_FILTER_URI,
Uri.encode(uri.getLastPathSegment())), true, observer);
+ mGroup = LocalGroups.Group.restoreGroupById(getContentResolver(),
+ Long.parseLong(uri.getLastPathSegment()));
+ actionBar.setSubtitle(mGroup.getTitle());
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.member_list_options, menu);
+ menu.add(0, 0, 0, R.string.menu_option_delete);
+ menu.add(0, 1, 0, R.string.edit_local_group_dialog_title);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ break;
+ case R.id.add:
+ pickMembers();
+ break;
+ case 0:
+ new AlertDialog.Builder(this)
+ .setMessage(R.string.delete_locale_group_dialog_message)
+ .setTitle(R.string.delete_group_dialog_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ if (mGroup.delete(getContentResolver())) {
+ finish();
+ }
+ }
+ }).setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ // Don't need any operation
+ }
+ }).show();
+ break;
+ case 1:
+ final EditText editText = new EditText(this);
+ editText.setHint(R.string.group_edit_field_hint_text);
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.edit_local_group_dialog_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setView(editText)
+ .setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (!TextUtils.isEmpty(editText.getText())) {
+ if (checkGroupTitleExist(editText.getText().toString())) {
+ Toast.makeText(getApplicationContext(), R.string.error_group_exist,
+ Toast.LENGTH_SHORT).show();
+ } else {
+ mGroup.setTitle(editText.getText().toString());
+ if (mGroup.update(getContentResolver())) {
+ getActionBar().setSubtitle(mGroup.getTitle());
+ }
+ }
+ }
+ }
+ }).setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // TODO Auto-generated method stub
+ // Don't need any operation
+ }
+ }).show();
+ }
+ return false;
}
private ContentObserver observer = new ContentObserver(new Handler()) {
@@ -291,6 +371,26 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
}
};
+ private boolean checkGroupTitleExist(String name) {
+ Cursor c = null;
+ try {
+ c = getApplicationContext().getContentResolver().query(
+ LocalGroups.CONTENT_URI, null, LocalGroups.GroupColumns.TITLE + "=?",
+ new String[] {
+ name
+ }, null);
+ if (c != null) {
+ return c.getCount() > 0;
+ } else {
+ return false;
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
@Override
protected void onPause() {
super.onPause();
@@ -304,35 +404,67 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
getContentResolver().unregisterContentObserver(observer);
}
- @Override
- public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- selectAll();
- return true;
- }
-
private void updateDisplay(boolean isEmpty) {
if (isEmpty) {
- listView.setVisibility(View.GONE);
+ mListView.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
} else {
- listView.setVisibility(View.VISIBLE);
+ mListView.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
}
}
- private void selectAll() {
- Cursor cursor = mAdapter.getCursor();
- if (cursor == null) {
- return;
+ private AbsListView.MultiChoiceModeListener mMultiChoiceModeListener
+ = new AbsListView.MultiChoiceModeListener() {
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ View v = mListView.getChildAt(position);
+ String contactId = (String) v.getTag();
+ CheckBox checkBox = (CheckBox) v.findViewById(R.id.pick_contact_check);
+ if (mRemoveSet.containsKey(contactId)) {
+ mRemoveSet.remove(contactId);
+ } else {
+ mRemoveSet.putString(contactId, contactId);
+ }
+ setCheckStatus(contactId, checkBox);
}
- cursor.moveToPosition(-1);
- while (cursor.moveToNext()) {
- String contactId = String.valueOf(cursor.getLong(SUMMARY_RAW_CONTACTS_ID_INDEX));
- removeSet.putString(contactId, contactId);
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mode.getMenuInflater().inflate(R.menu.member_list_options_cab, menu);
+ mActionMode = mode;
+ return true;
}
- mAdapter.refresh();
- }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.move:
+ chooseGroup();
+ return true;
+ case R.id.remove:
+ removeContactsFromGroup();
+ mAdapter.refresh();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mListView.clearChoices();
+ mRemoveSet.clear();
+ mAdapter.notifyDataSetChanged();
+ mActionMode = null;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+ };
@Override
protected void onResume() {
@@ -341,13 +473,17 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
startQuery();
}
- private void addEditView() {
- Intent intent = new Intent(this, GroupEditActivity.class);
- intent.setData(uri);
-
- mTabHost.addTab(mTabHost.newTabSpec(TAB_TAG)
- .setIndicator(TAB_TAG, getResources().getDrawable(R.drawable.ic_launcher_contacts))
- .setContent(intent));
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_OK)
+ switch (requestCode) {
+ case CODE_PICK_MEMBER:
+ Bundle result = data.getExtras().getBundle("result");
+
+ // define member object mAddMembersTask to use later.
+ mAddMembersTask = new AddMembersTask(result);
+ mAddMembersTask.execute();
+ }
}
private void startQuery() {
@@ -423,18 +559,18 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
* job if removeSet is empty.
*/
Cursor cursor = getCursor();
- if (!removeSet.isEmpty() && cursor != null && !cursor.isClosed()) {
+ if (!mRemoveSet.isEmpty() && cursor != null && !cursor.isClosed()) {
cursor.moveToPosition(-1);
Bundle newRemoveSet = new Bundle();
while (cursor.moveToNext()) {
String contactId = String.valueOf(
cursor.getLong(SUMMARY_RAW_CONTACTS_ID_INDEX));
- if (removeSet.containsKey(contactId)) {
+ if (mRemoveSet.containsKey(contactId)) {
newRemoveSet.putString(contactId, contactId);
}
}
- if (newRemoveSet.size() != removeSet.size()) {
- removeSet = newRemoveSet;
+ if (newRemoveSet.size() != mRemoveSet.size()) {
+ mRemoveSet = newRemoveSet;
}
}
updateToolsBar();
@@ -517,52 +653,38 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
}
@Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- String contactId = (String) arg1.getTag();
- CheckBox checkBox = (CheckBox) arg1.findViewById(R.id.pick_contact_check);
- if (removeSet.containsKey(contactId)) {
- removeSet.remove(contactId);
+ public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
+ if (!mListView.isItemChecked(position)) {
+ mListView.setItemChecked(position, true);
} else {
- removeSet.putString(contactId, contactId);
+ mListView.setItemChecked(position, false);
}
- setCheckStatus(contactId, checkBox);
- updateToolsBar();
+ }
+
+ private void pickMembers() {
+ Intent intent = new Intent(MultiPickContactActivity.ACTION_MULTI_PICK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra(MultiPickContactActivity.IS_CONTACT,true);
+ intent.setClass(this, MultiPickContactActivity.class);
+ ContactListFilter filter = new ContactListFilter(ContactListFilter.FILTER_TYPE_ACCOUNT,
+ PhoneAccountType.ACCOUNT_TYPE, SimContactsConstants.PHONE_NAME, null, null);
+ intent.putExtra(AccountFilterActivity.KEY_EXTRA_CONTACT_LIST_FILTER, filter);
+ startActivityForResult(intent, CODE_PICK_MEMBER);
}
private void updateToolsBar() {
if (mDeleteMembersTask != null
- && mDeleteMembersTask.getStaus() == DeleteMembersThread.TASK_RUNNING) {
- if (toolsBar.getVisibility() != View.GONE) {
- toolsBar.setVisibility(View.GONE);
- }
+ && mDeleteMembersTask.getStatus() == DeleteMembersThread.TASK_RUNNING) {
return;
}
- if (removeSet.isEmpty() && toolsBar.getVisibility() == View.VISIBLE) {
- toolsBar.setVisibility(View.GONE);
- toolsBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.tools_bar_disappear));
- } else if (!removeSet.isEmpty() && toolsBar.getVisibility() == View.GONE) {
- toolsBar.setVisibility(View.VISIBLE);
- toolsBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.tools_bar_appear));
+ if (mRemoveSet.isEmpty() && mActionMode != null) {
+ mActionMode.finish();
}
}
private void setCheckStatus(String contactId, CheckBox checkBox) {
- checkBox.setChecked(removeSet.containsKey(contactId));
- }
-
- @Override
- public void onClick(View v) {
- if (v == cancelBtn) {
- removeSet.clear();
- mAdapter.refresh();
- } else if (v == deleteBtn) {
- removeContactsFromGroup();
- mAdapter.refresh();
- } else if (v == moveBtn) {
- chooseGroup();
- }
-
+ checkBox.setChecked(mRemoveSet.containsKey(contactId));
}
private void chooseGroup() {
@@ -601,8 +723,8 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
}
private void moveContactstoGroup(int groupId) {
- if (removeSet != null && removeSet.size() > 0) {
- Bundle bundleData = (Bundle) removeSet.clone();
+ if (mRemoveSet != null && mRemoveSet.size() > 0) {
+ Bundle bundleData = (Bundle) mRemoveSet.clone();
if (mDeleteMembersTask != null) {
mDeleteMembersTask.setStatus(DeleteMembersThread.TASK_CANCEL);
mDeleteMembersTask = null;
@@ -615,8 +737,8 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
}
private void removeContactsFromGroup() {
- if (removeSet != null && removeSet.size() > 0) {
- Bundle bundleData = (Bundle) removeSet.clone();
+ if (mRemoveSet != null && mRemoveSet.size() > 0) {
+ Bundle bundleData = (Bundle) mRemoveSet.clone();
if (mDeleteMembersTask != null) {
mDeleteMembersTask.setStatus(DeleteMembersThread.TASK_CANCEL);
mDeleteMembersTask = null;
@@ -651,4 +773,189 @@ public class MemberListActivity extends TabActivity implements OnItemClickListen
return new DefaultImageRequest(displayName, lookupKey);
}
+
+ class AddMembersTask extends AsyncTask<Object, Object, Object> {
+ private ProgressDialog mProgressDialog;
+ private static final int MSG_CANCEL = 1;
+ private boolean mIsAddMembersTaskCanceled;
+
+ private Handler alertHandler = new Handler() {
+ @Override
+ public void dispatchMessage(Message msg) {
+ if (msg.what == MSG_CANCEL) {
+ Toast.makeText(MemberListActivity.this, R.string.add_member_task_canceled,
+ Toast.LENGTH_LONG).show();
+ } else if (msg.what == 0) {
+ Toast.makeText(MemberListActivity.this, R.string.toast_not_add,
+ Toast.LENGTH_LONG)
+ .show();
+ }
+ }
+ };
+
+ private Bundle result;
+
+ private int size;
+
+ AddMembersTask(Bundle result) {
+ size = result.size();
+ this.result = result;
+ HandlerThread thread = new HandlerThread("DownloadTask");
+ thread.start();
+ }
+
+ protected void onPostExecute(Object result) {
+ if (mProgressDialog != null && mProgressDialog.isShowing()) {
+ mProgressDialog.dismiss();
+ }
+ new LocalGroupCountTask(MemberListActivity.this).execute();
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mIsAddMembersTaskCanceled = false;
+ mProgressDialog = new ProgressDialog(MemberListActivity.this);
+ mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ mProgressDialog.setProgress(0);
+ mProgressDialog.setMax(size);
+ mProgressDialog.show();
+ mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+
+ // if dialog is canceled, cancel the task also.
+ mIsAddMembersTaskCanceled = true;
+ }
+ });
+ }
+
+ @Override
+ protected Bundle doInBackground(Object... params) {
+ process();
+ return null;
+ }
+
+ public void process() {
+ boolean hasInvalide = false;
+ int progressIncrement = 0;
+ ContentValues values = new ContentValues();
+ // add Non-null protection of group for monkey test
+ if (null != mGroup) {
+ values.put(LocalGroup.DATA1, mGroup.getId());
+ }
+
+ Set<String> keySet = result.keySet();
+ Iterator<String> it = keySet.iterator();
+
+ // add a ContentProviderOperation update list.
+ final ArrayList<ContentProviderOperation> updateList =
+ new ArrayList<ContentProviderOperation>();
+ ContentProviderOperation.Builder builder = null;
+ mIsAddMembersTaskCanceled = false;
+ while (it.hasNext()) {
+ if (mIsAddMembersTaskCanceled) {
+ alertHandler.sendEmptyMessage(MSG_CANCEL);
+ break;
+ }
+ if (progressIncrement++ % 2 == 0) {
+ if (mProgressDialog != null) {
+ mProgressDialog.incrementProgressBy(2);
+ } else if (mProgressDialog != null && mProgressDialog.isShowing()) {
+ mProgressDialog.dismiss();
+ mProgressDialog = null;
+ }
+ }
+ String id = it.next();
+ Cursor c = null;
+ try {
+ c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI, new String[] {
+ ContactsContract.RawContacts._ID, ContactsContract.RawContacts.ACCOUNT_TYPE
+ }, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] {
+ id
+ }, null);
+ if (c.moveToNext()) {
+ String rawId = String.valueOf(c.getLong(0));
+
+ if (!PhoneAccountType.ACCOUNT_TYPE.equals(c.getString(1))) {
+ hasInvalide = true;
+ continue;
+ }
+
+ builder = ContentProviderOperation.newDelete(Data.CONTENT_URI);
+ builder.withSelection(Data.RAW_CONTACT_ID + "=? and " + Data.MIMETYPE
+ + "=?", new String[] {
+ rawId, LocalGroup.CONTENT_ITEM_TYPE
+ });
+
+ // add the delete operation to the update list.
+ updateList.add(builder.build());
+
+ builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
+ // add Non-null protection of group for monkey test
+ if (null != mGroup) {
+ builder.withValue(LocalGroup.DATA1, mGroup.getId());
+ }
+ builder.withValue(Data.RAW_CONTACT_ID, rawId);
+ builder.withValue(Data.MIMETYPE, LocalGroup.CONTENT_ITEM_TYPE);
+
+ // add the insert operation to the update list.
+ updateList.add(builder.build());
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ // if task is canceled ,still update the database with the data in
+ // updateList.
+
+ // apply batch to execute the delete and insert operation.
+ if (updateList.size() > 0) {
+ addMembersApplyBatchByBuffer(updateList, getContentResolver());
+ }
+ if (hasInvalide) {
+ alertHandler.sendEmptyMessage(0);
+ }
+ }
+
+ /**
+ * the max length of applyBatch is 500
+ */
+ private static final int BUFFER_LENGTH = 499;
+
+
+ private void addMembersApplyBatchByBuffer(ArrayList<ContentProviderOperation> list,
+ ContentResolver cr) {
+ final ArrayList<ContentProviderOperation> temp =
+ new ArrayList<ContentProviderOperation>(BUFFER_LENGTH);
+ int bufferSize = list.size() / BUFFER_LENGTH;
+ for (int index = 0; index <= bufferSize; index++) {
+ temp.clear();
+ if (index == bufferSize) {
+ for (int i = index * BUFFER_LENGTH; i < list.size(); i++) {
+ temp.add(list.get(i));
+ }
+ } else {
+ for (int i = index * BUFFER_LENGTH; i < index * BUFFER_LENGTH + BUFFER_LENGTH;
+ i++) {
+ temp.add(list.get(i));
+ }
+ }
+ if (!temp.isEmpty()) {
+ try {
+ cr.applyBatch(ContactsContract.AUTHORITY, temp);
+ if (mProgressDialog != null) {
+ mProgressDialog.incrementProgressBy(temp.size() / 4);
+ } else if (mProgressDialog != null && mProgressDialog.isShowing()) {
+ mProgressDialog.dismiss();
+ mProgressDialog = null;
+ }
+ } catch (Exception e) {
+ Log.e(MemberListActivity.class.getSimpleName(), "apply batch by buffer error:" + e);
+ }
+ }
+ }
+ }
+ }
}