liuyuqi-dellpc 4 years ago
commit
21d428e681

+ 9 - 0
.classpath

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="gen"/>
+	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+	<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+	<classpathentry kind="output" path="bin/classes"/>
+</classpath>

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+/bin
+/gen
+/.settings

+ 33 - 0
.project

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>DeleteAllContacts</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

+ 31 - 0
AndroidManifest.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="me.yoqi.deleteallcontacts"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="21" />
+
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>

BIN
ic_launcher-web.png


BIN
libs/android-support-v4.jar


+ 20 - 0
proguard-project.txt

@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}

+ 16 - 0
project.properties

@@ -0,0 +1,16 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-21
+android.library.reference.1=../appcompat_v7
+android.library.reference.2=../appcompat_v7

BIN
res/drawable-hdpi/ic_launcher.png


BIN
res/drawable-mdpi/ic_launcher.png


BIN
res/drawable-xhdpi/ic_launcher.png


BIN
res/drawable-xxhdpi/ic_launcher.png


+ 40 - 0
res/layout/activity_main.xml

@@ -0,0 +1,40 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="me.yoqi.deleteallcontacts.MainActivity" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/hello_world" />
+
+    <Button
+        android:id="@+id/btn_del_contact"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/textView1"
+        android:layout_alignStart="@+id/btn_del_contact"
+        android:layout_below="@+id/textView1"
+        android:layout_marginLeft="57dp"
+        android:layout_marginStart="57dp"
+        android:layout_marginTop="37dp"
+        android:text="删除所有联系人" />
+
+    <TextView
+        android:id="@+id/tv_contact"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignLeft="@+id/btn_del_contact"
+        android:layout_alignStart="@+id/btn_del_contact"
+        android:layout_below="@+id/btn_del_contact"
+        android:layout_marginTop="91dp"
+        android:scrollbars="vertical"
+        android:text="TextView" />
+
+</RelativeLayout>

+ 12 - 0
res/menu/main.xml

@@ -0,0 +1,12 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="me.yoqi.deleteallcontacts.MainActivity" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:title="@string/action_settings"
+        app:showAsAction="never"/>
+
+</menu>

+ 11 - 0
res/values-v11/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 12 - 0
res/values-v14/styles.xml

@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>

+ 10 - 0
res/values-w820dp/dimens.xml

@@ -0,0 +1,10 @@
+<resources>
+
+    <!--
+         Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
+    -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+
+</resources>

+ 7 - 0
res/values/dimens.xml

@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>

+ 8 - 0
res/values/strings.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">DeleteAllContacts</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="action_settings">Settings</string>
+
+</resources>

+ 20 - 0
res/values/styles.xml

@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>

+ 73 - 0
src/me/yoqi/deleteallcontacts/MainActivity.java

@@ -0,0 +1,73 @@
+package me.yoqi.deleteallcontacts;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+import me.yoqi.deleteallcontacts.utils.ContactManager;
+
+public class MainActivity extends AppCompatActivity {
+	Button btnDelUser;
+	TextView tvContact;
+	Context mContext;
+	static String TAG = "me.yoqi.deleteallcontacts.MainActivity";
+	ContactManager contactManager;
+
+	private static class MyHandler extends Handler {
+
+		public MyHandler(Context mContext) {
+
+		}
+
+		@Override
+		public void handleMessage(Message msg) {
+			super.handleMessage(msg);
+			switch (msg.what) {
+			case 0:
+				// 更新UI
+				break;
+			}
+			super.handleMessage(msg);
+		}
+	}
+
+	@Override
+	protected void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		setContentView(R.layout.activity_main);
+		mContext = this;
+		contactManager = new ContactManager(mContext);
+		initView();
+		initData();
+	}
+
+	void initView() {
+		btnDelUser = (Button) findViewById(R.id.btn_del_contact);
+		tvContact = (TextView) findViewById(R.id.tv_contact);
+		btnDelUser.setOnClickListener(new OnClickListener() {
+
+			@Override
+			public void onClick(View v) {
+				HashMap<String, Object> contactNum = contactManager.delAllContacts();
+				Toast.makeText(mContext, "已经删除  " + contactNum.size() + "    个联系人", Toast.LENGTH_SHORT).show();
+				initData();
+			}
+		});
+	}
+
+	void initData() {
+		MyHandler mHandler = new MyHandler(this);
+
+		ArrayList<String> allContact = contactManager.getAllContact();
+		tvContact.setText(allContact.toString());
+	}
+}

+ 55 - 0
src/me/yoqi/deleteallcontacts/utils/BlackBerryContactManager.java

@@ -0,0 +1,55 @@
+package me.yoqi.deleteallcontacts.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+
+/**
+ * 黑莓联系人管理,与 android 联系人管理不一样。
+ * 
+ * @author liuyuqi
+ *
+ */
+public class BlackBerryContactManager {
+	ContentResolver resolver;
+	static String TAG = "me.yoqi.deleteallcontacts.utils.ContactManager";
+
+	public BlackBerryContactManager(Context context) {
+		resolver = context.getContentResolver();
+	}
+
+	/**
+	 * 查询所有联系人
+	 */
+	public ArrayList<String> getAllContact() {
+		ArrayList<String> res = new ArrayList<String>();
+		Uri uri = ContactsContract.Data.CONTENT_URI;
+		Cursor cursorUser = resolver.query(uri,
+				new String[] { ContactsContract.CommonDataKinds.Phone._ID,
+						ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
+						ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID },
+				null, null, null);
+
+		while (cursorUser.moveToNext()) {
+			int id = cursorUser.getInt(0); // 按上面数组的声明顺序获取
+			String name = cursorUser.getString(1);
+			int rawContactsId = cursorUser.getInt(2);
+			res.add("id:" + id + " ,name:" + name + " ,rawContacntsID:" + rawContactsId + "\r\n");
+		}
+		return res;
+	}
+
+	public void deleteAllContacts() throws UnsupportedEncodingException, Exception {
+//		ContactList contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);
+//		Enumeration e = contactList.items();
+//		while (e.hasMoreElements()) {
+//			Contact c = (Contact) e.nextElement();
+//			contactList.removeContact(c);
+//		}
+	}
+}

+ 222 - 0
src/me/yoqi/deleteallcontacts/utils/ContactManager.java

@@ -0,0 +1,222 @@
+package me.yoqi.deleteallcontacts.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.RawContacts;
+import android.util.Log;
+
+/**
+ * 联系人管理,三个表 ContactsContract.Data.CONTENT_URI;
+ * ContactsContract.RawContacts.CONTENT_URI
+ * ContactsContract.Contacts.CONTENT_URI
+ * 
+ * @author liuyuqi
+ *
+ */
+public class ContactManager {
+	ContentResolver resolver;
+	static String TAG = "me.yoqi.deleteallcontacts.utils.ContactManager";
+
+	public ContactManager(Context context) {
+		resolver = context.getContentResolver();
+	}
+
+	/**
+	 * 删除所有联系人
+	 * 
+	 * @return
+	 */
+	public HashMap<String, Object> delAllContacts() {
+		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+		ContentProviderOperation op = null;
+		Uri uri = null;
+		HashMap<String, Object> delResult = new HashMap<String, Object>();
+		int num = 0;// 删除影响的行数
+		resolver.delete(
+				Uri.parse(ContactsContract.RawContacts.CONTENT_URI.toString() + "?"
+						+ ContactsContract.CALLER_IS_SYNCADAPTER + "=true"),
+				ContactsContract.RawContacts._ID + ">0", null);
+		// 删除Data表的数据
+		uri = Uri.parse(Data.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(uri).withSelection(Data.RAW_CONTACT_ID + ">0", null)
+				.withYieldAllowed(true).build();
+		ops.add(op);
+		// 删除RawContacts表的数据
+		uri = Uri.parse(RawContacts.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(RawContacts.CONTENT_URI).withSelection(RawContacts._ID + ">0", null)
+				.withYieldAllowed(true).build();
+		ops.add(op);
+		// 删除Contacts表的数据
+		uri = Uri.parse(Contacts.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(uri).withSelection(Contacts._ID + ">0", null).withYieldAllowed(true)
+				.build();
+		ops.add(op);
+		// 执行批量删除
+		try {
+			ContentProviderResult[] results = resolver.applyBatch(ContactsContract.AUTHORITY, ops);
+			for (ContentProviderResult result : results) {
+				num += result.count;
+				Log.i(TAG, "删除影响的行数:" + result.count);
+			}
+			delResult.put("result", "1");
+			delResult.put("obj", num);
+		} catch (Exception e) {
+			Log.i(TAG, e.getMessage());
+			delResult.put("result", "-1");
+			delResult.put("obj", "删除失败!" + e.getMessage());
+		}
+		if (delResult.size() == 0) {
+			delResult.put("result", "0");
+			delResult.put("obj", "无效删除,联系人信息不正确!");
+		}
+		return delResult;
+	}
+
+	/**
+	 * 删除联系人 ,联系人相关联的有三张表,将三张表的数据全部删除 部分手机删除第二张即可,部分手机需要删除三张表
+	 * resolver.delete(ContactsContract.Data.CONTENT_URI, null, null);
+	 * resolver.delete(ContactsContract.RawContacts.CONTENT_URI, null, null);
+	 * resolver.delete(ContactsContract.Contacts.CONTENT_URI, null, null);
+	 * 
+	 * @param contactId
+	 *            联系人ID
+	 * @param groupId
+	 * @return 如果删除成功:(1, num); 如果删除失败:(-1, "删除失败:" + e.getMessage());
+	 *         如果信息无效:(0, "无效删除,联系人信息不正确!");
+	 */
+	public HashMap<String, Object> delContacts(List<String> contactIds) {
+		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+		ContentProviderOperation op = null;
+		Uri uri = null;
+
+		HashMap<String, Object> delResult = new HashMap<String, Object>();
+		int num = 0;// 删除影响的行数
+		if (Utils.isEmpty(contactIds)) {
+			delResult.put("result", "0");
+			delResult.put("obj", "无效删除,联系人id不正确!");
+			return delResult;
+		}
+		List<String> ids = new ArrayList<String>();
+		String selection = " in(";
+		for (String contactId : contactIds) {
+			// 如果联系人id 不大于 0,或者不存在,循环下一次
+			if (!Utils.isNumber(contactId) || Long.parseLong(contactId) <= 0 || !isExistContact(contactId)) {
+				continue;
+			}
+			selection += "?,";
+			ids.add(contactId);
+		}
+		if (ids.size() == 0) {
+			delResult.put("result", "0");
+			delResult.put("obj", "无效联系人id");
+			return delResult;
+		}
+		selection = selection.substring(0, selection.length() - 1) + ")";
+		String[] selectionArgs = ids.toArray(new String[] {});
+
+		// 删除Data表的数据
+		uri = Uri.parse(Data.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(uri).withSelection(Data.RAW_CONTACT_ID + selection, selectionArgs)
+				.withYieldAllowed(true).build();
+		ops.add(op);
+		// 删除RawContacts表的数据
+		uri = Uri.parse(RawContacts.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
+				.withSelection(RawContacts._ID + selection, selectionArgs).withYieldAllowed(true).build();
+		ops.add(op);
+		// 删除Contacts表的数据
+		uri = Uri.parse(Contacts.CONTENT_URI.toString() + "?" + ContactsContract.CALLER_IS_SYNCADAPTER + "=true");
+		op = ContentProviderOperation.newDelete(uri).withSelection(Contacts._ID + selection, selectionArgs)
+				.withYieldAllowed(true).build();
+		ops.add(op);
+
+		// 执行批量删除
+		try {
+			ContentProviderResult[] results = resolver.applyBatch(ContactsContract.AUTHORITY, ops);
+			for (ContentProviderResult result : results) {
+				num += result.count;
+				Log.i(TAG, "删除影响的行数:" + result.count);
+			}
+			delResult.put("result", "1");
+			delResult.put("obj", num);
+		} catch (Exception e) {
+			Log.i(TAG, e.getMessage());
+			delResult.put("result", "-1");
+			delResult.put("obj", "删除失败!" + e.getMessage());
+		}
+		if (delResult.size() == 0) {
+			delResult.put("result", "0");
+			delResult.put("obj", "无效删除,联系人id不正确!");
+		}
+		return delResult;
+	}
+
+	/**
+	 * 根据id查询联系人是否存在
+	 */
+	private boolean isExistContact(String id) {
+		if (Utils.isEmpty(id)) {
+			return false;
+		}
+		Cursor cursor = resolver.query(Contacts.CONTENT_URI, new String[] { Contacts._ID }, Contacts._ID + " = ? ",
+				new String[] { id }, null);
+
+		if (cursor.moveToFirst()) {
+			return true;
+		}
+		cursor.close();
+		return false;
+	}
+
+	/**
+	 * 根据组的 id 查询组是否存在
+	 * 
+	 * @return boolean
+	 */
+	public boolean isExistGroup(String id) {
+		if (Utils.isEmpty(id)) {
+			return false;
+		}
+		Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] { Groups._ID }, Groups._ID + "=" + id, null,
+				null);
+		if (cursor.moveToFirst()) {
+			return true;
+		}
+		cursor.close();
+		return false;
+	}
+
+	/**
+	 * 查询所有联系人
+	 */
+	public ArrayList<String> getAllContact() {
+		ArrayList<String> res = new ArrayList<String>();
+		Uri uri = ContactsContract.Data.CONTENT_URI;
+		Cursor cursorUser = resolver.query(uri,
+				new String[] { ContactsContract.CommonDataKinds.Phone._ID,
+						ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
+						ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID },
+				null, null, null);
+
+		while (cursorUser.moveToNext()) {
+			int id = cursorUser.getInt(0); // 按上面数组的声明顺序获取
+			String name = cursorUser.getString(1);
+			int rawContactsId = cursorUser.getInt(2);
+			res.add("id:" + id + " ,name:" + name + " ,rawContacntsID:" + rawContactsId + "\r\n");
+		}
+		return res;
+	}
+
+}

+ 33 - 0
src/me/yoqi/deleteallcontacts/utils/Utils.java

@@ -0,0 +1,33 @@
+package me.yoqi.deleteallcontacts.utils;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class Utils {
+
+	/** 判断list 是否为空
+	 * @param contactIds
+	 * @return
+	 */
+	public static boolean isEmpty(List<String> contactIds) {
+		return contactIds.size() > 0;
+	}
+
+	/** 判断 string是否为数字
+	 * @param contactId
+	 * @return
+	 */
+	public static boolean isNumber(String contactId) {
+		Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
+		return pattern.matcher(contactId).matches();
+	}
+
+	/** 判断string是否为空
+	 * @param id
+	 * @return
+	 */
+	public static boolean isEmpty(String id) {
+		return id.length() > 0;
+	}
+
+}