Android中删除常用联系人(上)

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

               
在Android 4.0中,google已经把移除常用联系人这个功能去掉。
当用户在进行拨打电话,接听电话等电话行为时,系统会自动对其对应号码的使用进行计数。然后根据计数情况来显示常用联系人。 移除常用联系人只是指把该联系人从常用联系人列表移除。
移除常用联系人基本思想是: 在数据库中,保留goolge原来中用对通话进行计数的字段 DataUsageStatColumns.TIMES_USED  ,新增加一个字段 DataUsageStatColumns.FAKE_TIMES_USED 来对通话进行计数,并提供一些对该字段操作接口,然后根据我们 DataUsageStatColumns.FAKE_TIMES_USED 计数情况来显示常用联系人
移除常用联系该功能的实现主要分为两个部分:
第一, 当用户从Call log删除一个通话记录,表明用户不想和该联系人的该通话记录本看到,因此应该把该联系人从常用联系人列表中移除。
第二, 用户可以从常用联系人列表中移除一个联系人,同时把和该联系人相关的Call log记录都删除掉。
添加移除常用联系功能,需要修改两个应用程序的源码,一个是com.android.providers.contacts,另一个是com.android.contacts
。在MTK6575平台上,对于应用 com.android.providers.contacts改动的文件有
 
  

packages / providers / ContactsProvider / src / com / android / providers / contacts / CallLogProvider . java
packages / providers / ContactsProvider / src / com / android / providers / contacts / ContactsProvider2 . java
packages / providers / ContactsProvider / src / com / android / providers / contacts / ContactsDatabaseHelper . java

主要修改如下:
文件packages/providers/ContactsProvider/src/com/android/providers/contacts/CallLogProvider.java
 
   

@@ - 127 , 7 + 132 , 22 @@ public class CallLogProvider extends ContentProvider {
         sCallsProjectionMap . put ( Calls . DATA_ID , Calls . DATA_ID );
          /* The previous lines are provided and maintained by Mediatek inc.*/
      }
+     private static final HashMap < String , String > sCallsToJoin_USAGE_STAT_ProjectionMap ;
+     static {
+         /*Calls projection map*/
+        sCallsToJoin_USAGE_STAT_ProjectionMap = new HashMap < String , String >();
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . _ID , Tables . CALLS + "._id as " + Calls . _ID );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . NUMBER , Calls . NUMBER );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . DATE , Calls . DATE );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . DURATION , Calls . DURATION );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . TYPE , Calls . TYPE );
+         /* The fillowing lines are provided and maintained by Mediatek inc.*/
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . SIM_ID , Calls . SIM_ID );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . RAW_CONTACT_ID , Calls . RAW_CONTACT_ID );
+        sCallsToJoin_USAGE_STAT_ProjectionMap . put ( Calls . DATA_ID , Calls . DATA_ID );
+         /* The previous lines are provided and maintained by Mediatek inc.*/
+     }
      private static final String mstableCallsJoinData = Tables . CALLS + " LEFT JOIN "  
      + " (SELECT * FROM " +   Views . DATA + " WHERE " + Data . _ID + " IN "
      + "(SELECT " +   Calls . DATA_ID + " FROM " + Tables . CALLS + ")) AS " + Views . DATA
@@ - 605 , 7 + 625 , 7 @@ public class CallLogProvider extends ContentProvider {
          return getDatabaseModifier ( db ). update ( Tables . CALLS , values , selectionBuilder . build (),
                 selectionArgs );
      }
-
+     IContentProvider mContentProvider ;
      @Override
      public int delete ( Uri uri , String selection , String [] selectionArgs ) {
          SelectionBuilder selectionBuilder = new SelectionBuilder ( selection );
@@ - 640 , 7 + 660 , 31 @@ public class CallLogProvider extends ContentProvider {
          *       selectionBuilder . build (), selectionArgs );
          * /
         case CALLS: {
-            int count = 0;
+              ArrayList<Long> idList=new ArrayList<Long> ();
+              ArrayList<Integer> typeList=new ArrayList<Integer> ();
+              
+              Cursor c = db.query(true,
+                    Tables.CALLS, new String[] { Calls._ID, Calls.DATA_ID,Calls.TYPE},
+                    selection, selectionArgs,null,null,null,null);
+              long id=-1;
+              if(c.moveToFirst())
+              {
+                      do
+                      {
+                              id=c.getLong(1);
+                              if(id>0)
+                              {
+                                     idList.add(id);
+                                     typeList.add(c.getInt(2));
+                              }
+                              
+                      }while(c.moveToNext());
+              }
+              long ids[]=new long[idList.size()];
+              for(int i=0;i<ids.length;i++)
+                      ids[i]=idList.get(i);
+              c.close();
+             int count = 0;
             if (FeatureOption.MTK_SEARCH_DB_SUPPORT == true) {
               / *  
                * update name_lookup for usage of dialer search :
@@ - 788 , 6 + 832 , 36 @@ public class CallLogProvider extends ContentProvider {
              if ( count > 0 ) {
               notifyDialerSearchChange ();
              }
+             if ( ids . length > 0 && uri . getBooleanQueryParameter ( "updateFakeTimesUsed" , true ))
+             {
+                               IContentProvider cp = null ;
+                   synchronized ( this ) {
+                       cp = mContentProvider ;
+                       if ( cp == null ) {
+                           cp = mContentProvider = getContext (). getContentResolver (). acquireProvider ( ContactsContract . AUTHORITY );
+                       }
+                   }
+                 try {
+                       Bundle bundle = new Bundle ();
+                      bundle . putLongArray ( "dataIds" , ids );
+                       //bundle.putIntArray("types", types);
+                      //bundle.putIntArray("counts", counts);
+                    Bundle b = cp.call(ContactsProvider2.CALL_METHOD_UPDATE_FAKE_TIMES_USED, "Asynchronous", bundle);
+                    /*if (b != null) {
+                        int v = b.getInt("count",0);
+                        if(v!=count)
+                        {
+                              Log.e(TAG, "some erro happpend in CALL_METHOD_UPDATE_FAKE_TIMES_USED");
+                        }
+                    }*/
+                    // If the response Bundle is null, we fall through
+                    // to the query interface below.
+                } catch (RemoteException e) {
+                   Log.w(TAG, "", e);
+                    // Not supported by the remote side?  Fall through
+                    // to query().
+                }
+            }
             return count;
         }

文件packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsDatabaseHelper.java
 
   

@@ - 733 , 7 + 733 , 12 @@ import com . mediatek . providers . contacts . ContactsFeatureConstants . FeatureOption ;
          public static final String TIMES_USED = "times_used" ;
          public static final String CONCRETE_TIMES_USED =
                  Tables . DATA_USAGE_STAT + "." + TIMES_USED ;
-
+         /** type: INTEGER */
+         public static final String FAKE_TIMES_USED = "fake_times_used" ;
+         public static final String CONCRETE_FAKE_TIMES_USED =
+                 Tables . DATA_USAGE_STAT + "." + FAKE_TIMES_USED ;
+         /*add by Robin Hu*/
          /** type: INTEGER */
          public static final String USAGE_TYPE_INT = "usage_type" ;
          public static final String CONCRETE_USAGE_TYPE =
@@ - 1383 , 6 + 1388 , 7 @@ import com . mediatek . providers . contacts . ContactsFeatureConstants . FeatureOption ;
                  DataUsageStatColumns . DATA_ID + " INTEGER NOT NULL, " +
                  DataUsageStatColumns . USAGE_TYPE_INT + " INTEGER NOT NULL DEFAULT 0, " +
                  DataUsageStatColumns . TIMES_USED + " INTEGER NOT NULL DEFAULT 0, " +
+                 DataUsageStatColumns . FAKE_TIMES_USED + " INTEGER NOT NULL DEFAULT 0, " +
                  DataUsageStatColumns . LAST_TIME_USED + " INTERGER NOT NULL DEFAULT 0, " +
                  "FOREIGN KEY(" + DataUsageStatColumns . DATA_ID + ") REFERENCES "
                          + Tables . DATA + "(" + Data . _ID + ")" +
@@ - 1918 , 6 + 1924 , 7 @@ import com . mediatek . providers . contacts . ContactsFeatureConstants . FeatureOption ;
                  + MimetypesColumns . CONCRETE_MIMETYPE + " AS " + Data . MIMETYPE + ", "
                  + DataUsageStatColumns . USAGE_TYPE_INT + ", "
                  + DataUsageStatColumns . TIMES_USED + ", "
+                 + DataUsageStatColumns . FAKE_TIMES_USED + ", "
                  + DataUsageStatColumns . LAST_TIME_USED
                  + " FROM " + Tables . DATA_USAGE_STAT
                  + " JOIN " + Tables . DATA + " ON ("

 文件packages/providers/ContactsProvider/src/com/android/providers/contacts/ContactsProvider2.java
 
   

@@ - 261 , 8 + 264 , 7 @@ public class ContactsProvider2 extends AbstractContactsProvider
      * the total times contacted . See also { @link #sStrequentFrequentProjectionMap}.
      */
     private static final String TIMES_USED_SORT_COLUMN = "times_used_sort";
-
-    private static final String FREQUENT_ORDER_BY = DataUsageStatColumns.TIMES_USED + " DESC,"
+    private static final String FREQUENT_ORDER_BY = DataUsageStatColumns.FAKE_TIMES_USED + " DESC,"
             + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
     /* package */ static final String UPDATE_TIMES_CONTACTED_CONTACTS_TABLE =
@@ -745,7 +747,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
     private static final ProjectionMap sStrequentFrequentProjectionMap = ProjectionMap.builder()
             .addAll(sContactsProjectionMap)
-            .add(TIMES_USED_SORT_COLUMN, "SUM(" + DataUsageStatColumns.CONCRETE_TIMES_USED + ")")
+            .add(TIMES_USED_SORT_COLUMN, "SUM(" + DataUsageStatColumns.CONCRETE_FAKE_TIMES_USED + ")")
             .build();
      /**
@@ -771,7 +773,8 @@ public class ContactsProvider2 extends AbstractContactsProvider
     private static final ProjectionMap sStrequentPhoneOnlyFrequentProjectionMap
             = ProjectionMap.builder()
             .addAll(sContactsProjectionMap)
-            .add(TIMES_USED_SORT_COLUMN, DataUsageStatColumns.CONCRETE_TIMES_USED)
+            //.add(TIMES_USED_SORT_COLUMN, DataUsageStatColumns.CONCRETE_TIMES_USED)
+            .add(TIMES_USED_SORT_COLUMN, DataUsageStatColumns.CONCRETE_FAKE_TIMES_USED)
             .add(Phone.NUMBER)
             .add(Phone.TYPE)
             .add(Phone.LABEL)
@@ -2218,7 +2221,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
      @Override
     public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        if (mWriteAccessLatch != null) {
+       if (mWriteAccessLatch != null) {
             // We are stuck trying to upgrade contacts db.  The only update request
             // allowed in this case is an update of provider status, which will trigger
             // an attempt to upgrade contacts again.
@@ -2295,7 +2298,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
     /* package */ void substituteDb(SQLiteDatabase db) {
         mActiveDb.set(db);
     }
-
+Handler handler=new Handler();
     @Override
     public Bundle call(String method, String arg, Bundle extras) {
         waitForAccess(mReadAccessLatch);
@@ -2315,6 +2318,72 @@ public class ContactsProvider2 extends AbstractContactsProvider
             response.putParcelable(Authorization.KEY_AUTHORIZED_URI, authUri);
             return response;
         }
+        else if (CALL_METHOD_UPDATE_FAKE_TIMES_USED.equals(method)) {
+              String strUri=extras.getString("Uri");
+              if(strUri==null)
+              {
+                  final long[] dataIds= extras.getLongArray("dataIds");
+                  //final int[] types=extras.getIntArray("types");
+                  //final int [] counts=extras.getIntArray("counts");
+                  if("Asynchronous".equals(arg))
+                  {
+                        Runnable r=new Runnable()
+                        {
+
+                                     @Override
+                                     public void run() {
+                                             // TODO Auto-generated method stub
+                                             for(int i=0;i<dataIds.length;i++)
+                                             update_FAKE_TIMES_USED_Stat(dataIds[i],ID_TYPE_VIEW_DATA,false);
+                                     }};
+                                     handler.postDelayed(r, 10);
+                                     return null;
+                  }
+                  else
+                  {
+                         int count=0;
+                         for(int i=0;i<dataIds.length;i++)
+                                 count+= update_FAKE_TIMES_USED_Stat(dataIds[i],ID_TYPE_VIEW_DATA,false);
+                         Bundle response = new Bundle();
+                         response.putInt("count", count);
+                         return response;
+                  }
+              }
+              else
+              {
+                      Uri uri=Uri.parse(strUri);
+                int match = sUriMatcher.match(uri);
+                match = processMatchEx(match, uri);
+                int count=-1;
+                List<String> pathSegments = uri.getPathSegments();
+                if(match==CONTACTS_LOOKUP_ID)
+                {
+                      int type=ID_TYPE_VIEW_DATA;
+                      if(arg!=null)
+                      {
+                              if(arg.equals("ID_TYPE_CONTACT"))
+                                     type=ID_TYPE_CONTACT;
+                              else if(arg.equals("ID_TYPE_RAW_CONTACT"))
+                              {
+                                     type=ID_TYPE_RAW_CONTACT;
+                              }
+                      }
+                    long id = Long.parseLong(pathSegments.get(3));
+                    count= update_FAKE_TIMES_USED_Stat(id,type,true);    
+                }
+                /*else if(match==CONTACTS_LOOKUP)
+                {
+                      String contactLookupKey = pathSegments.get(2);
+                      count= update_FAKE_TIMES_USED_Stat(contactLookupKey);
+                }*/
+                if(count!=-1)
+                {
+                      Bundle response = new Bundle();
+                      response.putInt("count", count);
+                      return response;
+                }
+              }
+       }
         return null;
     }
 
@@ -5515,7 +5584,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
                 // UNION ALL
                 // (SQL for listing frequently contacted items)
                 // ORDER BY ...
-
+              
                 final boolean phoneOnly = readBooleanQueryParameter(
                         uri, ContactsContract.STREQUENT_PHONE_ONLY, false);
                 if (match == CONTACTS_STREQUENT_FILTER && uri.getPathSegments().size() > 3) {
@@ -5569,7 +5638,8 @@ public class ContactsProvider2 extends AbstractContactsProvider
                             + " ON (" + DataUsageStatColumns.CONCRETE_DATA_ID + "="
                                 + DataColumns.CONCRETE_ID + " AND "
                             + DataUsageStatColumns.CONCRETE_USAGE_TYPE + "="
-                                + DataUsageStatColumns.USAGE_TYPE_INT_CALL + ")");
+                                + DataUsageStatColumns.USAGE_TYPE_INT_CALL 
+                                + " AND "+DataUsageStatColumns.CONCRETE_FAKE_TIMES_USED+">0"+")");
                     appendContactPresenceJoin(tableBuilder, projection, RawContacts.CONTACT_ID);
                     appendContactStatusUpdateJoin(tableBuilder, projection,
                             ContactsColumns.LAST_STATUS_UPDATE_ID);
@@ -6955,7 +7025,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
         if (includeDataUsageStat) {
             sb.append(" ON (" +
                     DbQueryUtils.concatenateClauses(
-                            DataUsageStatColumns.CONCRETE_TIMES_USED + " > 0",
+                            DataUsageStatColumns.CONCRETE_FAKE_TIMES_USED + " > 0",
                             RawContacts.CONTACT_ID + "=" + Views.CONTACTS + "." + Contacts._ID) +
                     ")");
         }
@@ -8431,7 +8501,6 @@ public class ContactsProvider2 extends AbstractContactsProvider
 
         return successful;
     }
-
     /**
      * Update {@link Tables#DATA_USAGE_STAT}.
      *
@@ -8444,7 +8513,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
         final String where = DataUsageStatColumns.DATA_ID + " =? AND "
                 + DataUsageStatColumns.USAGE_TYPE_INT + " =?";
         final String[] columns =
-                new String[] { DataUsageStatColumns._ID, DataUsageStatColumns.TIMES_USED };
+                new String[] { DataUsageStatColumns._ID, DataUsageStatColumns.TIMES_USED, DataUsageStatColumns.FAKE_TIMES_USED };
         final ContentValues values = new ContentValues();
         for (Long dataId : dataIds) {
             final String[] args = new String[] { dataId.toString(), String.valueOf(typeInt) };
@@ -8460,6 +8529,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
                         } else {
                             values.clear();
                             values.put(DataUsageStatColumns.TIMES_USED, cursor.getInt(1) + 1);
+                            values.put(DataUsageStatColumns.FAKE_TIMES_USED, cursor.getInt(2) + 1);
                             values.put(DataUsageStatColumns.LAST_TIME_USED, currentTimeMillis);
                             mActiveDb.get().update(Tables.DATA_USAGE_STAT, values,
                                     DataUsageStatColumns._ID + " =?",
@@ -8470,6 +8540,7 @@ public class ContactsProvider2 extends AbstractContactsProvider
                         values.put(DataUsageStatColumns.DATA_ID, dataId);
                         values.put(DataUsageStatColumns.USAGE_TYPE_INT, typeInt);
                         values.put(DataUsageStatColumns.TIMES_USED, 1);
+                        values.put(DataUsageStatColumns.FAKE_TIMES_USED, 1);
                         values.put(DataUsageStatColumns.LAST_TIME_USED, currentTimeMillis);
                         mActiveDb.get().insert(Tables.DATA_USAGE_STAT, null, values);
                     }
@@ -8484,7 +8555,213 @@ public class ContactsProvider2 extends AbstractContactsProvider
 
         return dataIds.size();
     }
+    /**
+     * Update {@link Tables#DATA_USAGE_STAT}.
+     *
+     * @return the number of rows affected.
+     */
+     final int update_FAKE_TIMES_USED_Stat(
+            long dataIds[]) 
+    {
+       return update_FAKE_TIMES_USED_Stat(dataIds,null,null);
+    }
+    /* package */ int update_FAKE_TIMES_USED_Stat(
+            long dataIds[], int types[], int  counts[]) {
+        //int typeInt;
+        /*final String where = DataUsageStatColumns.DATA_ID + " =? AND "
+                + DataUsageStatColumns.USAGE_TYPE_INT + " ="+DataUsageStatColumns.USAGE_TYPE_INT_CALL;*/
+        final String where = DataUsageStatColumns.DATA_ID + " =?";
+       
+        final String[] columns =
+                new String[] { DataUsageStatColumns._ID, DataUsageStatColumns.FAKE_TIMES_USED };
+        final ContentValues values = new ContentValues();
+        int n=0;
+        int i=0;
+        long dataId=0;
+        if(mActiveDb.get()==null)
+              mActiveDb.set(mContactsHelper.getWritableDatabase());
+        for (i=0; i<dataIds.length;i++) {
+              dataId=dataIds[i];
+              //typeInt = types[i];
+              //typeInt = sDataUsageTypeMap.get(types[i]);
+            final String[] args = new String[] { dataId+""};
+            mActiveDb.get().beginTransaction();
+            try {
+                final Cursor cursor = mActiveDb.get().query(Tables.DATA_USAGE_STAT, columns, where,
+                        args, null, null, null);
+                try {
+                    if (cursor.getCount() > 0) {
+                        if (!cursor.moveToFirst()) {
+                            Log.e(TAG,
+                                    "moveToFirst() failed while getAccount() returned non-zero.");
+                        } else {
+                              
+                              //n=cursor.getInt(1) + counts[i];
+                              n=0;//force clear
+                              do{
+                            values.clear();
+                            values.put(DataUsageStatColumns.FAKE_TIMES_USED,n);
+                            mActiveDb.get().update(Tables.DATA_USAGE_STAT, values,
+                                    DataUsageStatColumns._ID + " =?",
+                                    new String[] { cursor.getString(0) });
+                              }while(cursor.moveToNext());
+                        }
+                    } else {
+                      Log.wtf(TAG, "warning!There is no record for dataId=="+dataId+" and Type=="+DataUsageStatColumns.USAGE_TYPE_INT_CALL);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程设计说明书 一、课程目标 通过本课程的学习,学生将能够掌握Android手机通讯录的设计与实现,包括界面布局、数据存储、联系人管理等基本功能,培养学生的Android应用开发能力。 二、教学内容 1. Android应用开发概述 介绍Android系统架构、应用开发流程和常用开发工具 2. Android界面设计 学习使用XML和Java代码实现Android应用界面布局和交互 3. 数据存储与管理 学习使用SQLite数据库存储联系人信息,并实现增删改查等操作 4. 联系人管理功能 实现添加联系人、查看联系人详情、编辑联系人信息、删除联系人等功能 5. 系统权限与安全 介绍Android应用的权限管理机制,确保应用的安全性 三、教学方法 采用理论教学与实践相结合的教学方法,通过案例分析和实际操作,引导学生深入理解Android应用开发的各个环节。 四、教学过程 1. 理论讲解 通过课堂讲解、案例分析等方式,让学生掌握Android应用开发的基本原理和技术 2. 实践操作 指导学生使用Android Studio开发工具,逐步实现通讯录应用的各项功能 3. 课程作业 布置相关的课程设计作业,要求学生独立完成一个简单的Android手机通讯录应用 五、教学评价与考核 根据学生的平时表现、课程设计作业和最终项目成果进行综合评定,注重对学生实际操作能力和项目完成质量的评估。 六、参考教材 1. 《Android应用开发实战》 2. 《Android编程权威指南》 3. 《Android开发技术详解》 通过本课程的学习,学生将能够掌握Android手机通讯录的设计与实现,为将来的Android应用开发打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值