2014-02-13 28 views
0

我正在開發一個REST應用程序批量刪除聯繫人(我的意思是聯繫人,而不是原始聯繫人)。我花了超過3分鐘時間刪除一批約116個聯繫人,這在我看來是很重要的。有時它會打印Contacts deleted,但它們仍在手機的聯繫人列表中,其他時候它們真的被刪除。批量/批量刪除聯繫人 - 採取辦法長

任何人都可以點我在哪裏出了問題嗎?

我收到一封包含聯繫人的ID的JSONArray(和其他一些細節,但只有ID在該方法中使用的)應該刪除。

這裏是我刪除聯繫人代碼:

public Boolean deleteBatchContact(final JSONArray jsonArray) throws JSONException, RemoteException, OperationApplicationException 
{ 
    final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 
    final Long startTime = System.currentTimeMillis(); 

    if(jsonArray.length() != 0) // there must be something in the JSONArray 
    { 
     for(int i = 0; i < jsonArray.length(); i++) 
     { 
      final JSONObject jsonContactObject = jsonArray.getJSONObject(i); 
      final String contactId = jsonContactObject.getString("id"); 
      Long id = Long.parseLong(contactId); 

      ops.add(ContentProviderOperation.newDelete(ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(contactId))) 
        .withYieldAllowed(true) 
        .build()); 
     } 

     try { 
      final ContentProviderResult[] cpr = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops); 
      final Long endTimeTry = System.currentTimeMillis(); 
      final Integer numberOfContactsDeleted = cpr.length; 

      if(numberOfContactsDeleted > 0) 
      { 
       Log.d(TAG, numberOfContactsDeleted + " Contacts deleted!"); 
       final Long totalSuccess = endTimeTry-startTime; 
       Log.d(TAG, "Total Time (Sucess): " + totalSuccess); 

       return true; 
      } 
      else 
      { 
       Log.d(TAG, "Menor ou igual a zero..."); 
       final Long totalFailed = endTimeTry-startTime; 
       Log.d(TAG, "Total Time (No deletes): " + totalFailed); 
       return false; 
      } 

     } catch (Exception e) { 
      Log.d(TAG, "deleteBatchContact: " + e.getMessage()); 
      return false; 
     } 
    } 
    Long endTimeReturnFalse = System.currentTimeMillis(); 
    Long totalTimeReturnFalse = endTimeReturnFalse - startTime; 
    Log.d(TAG, "Total time return false: " + totalTimeReturnFalse); 
    return false; 
} 

而這裏就是我所說的deleteBatchContact方法:

else if(type.equalsIgnoreCase("delete")) 
    { 
     Log.d(TAG, "DELETE REQUEST"); 
     String strJson = request.getEntityAsText(); 
     int age = response.getAge(); 
     Log.d(TAG, "age1: " + age); 
     Log.d(TAG, "is commited1? " + response.isCommitted()); 
     try { 
      Log.d(TAG, "Try..."); 
      JSONArray jsonArray = new JSONArray(strJson); 
      if(processDelete(jsonArray) == true) 
      { 
       Log.d(TAG, "Response -> Deleted with Success!"); 
       response.setEntity("Deleted with success!", MediaType.TEXT_ALL); 
       age = response.getAge(); 
       Log.d(TAG, "age2: " + age); 
       Log.d(TAG, "is commited2? " + response.isCommitted()); 
      } 
      else 
      { 
       Log.d(TAG, "Response -> No contacts deleted..."); 
       response.setEntity("No contacts deleted...", MediaType.TEXT_ALL); 
       age = response.getAge(); 
       Log.d(TAG, "age3: " + age); 
       Log.d(TAG, "is commited3? " + response.isCommitted()); 
      } 
     } catch (RemoteException e) { 
      Log.d(TAG, "processDelete exception: " + e.getMessage()); 
      e.printStackTrace(); 
     } catch (JSONException e) { 
      Log.d(TAG, "processDelete exception: " + e.getMessage()); 
      e.printStackTrace(); 
     } catch (OperationApplicationException e) { 
      Log.d(TAG, "processDelete exception: " + e.getMessage()); 
      e.printStackTrace(); 
     } 

    } 

這裏是輸出:

02-13 01:28:04.484: D/ContactRestlet(17638): DELETE REQUEST 
02-13 01:28:04.507: D/ContactRestlet(17638): age1: 0 
02-13 01:28:04.507: D/ContactRestlet(17638): is commited1? false 
02-13 01:28:04.507: D/ContactRestlet(17638): Try... 
02-13 01:30:04.671: D/ContactRestlet(17638): DELETE REQUEST 
02-13 01:30:04.671: D/ContactRestlet(17638): age1: 0 
02-13 01:30:04.671: D/ContactRestlet(17638): is commited1? false 
02-13 01:30:04.671: D/ContactRestlet(17638): Try... 
02-13 01:31:07.468: D/ContactList(17638): 116 Contacts deleted! 
02-13 01:31:07.468: D/ContactList(17638): Total Time (Sucess): 182911 
02-13 01:31:07.468: D/ContactRestlet(17638): Response -> Deleted with Success! 
02-13 01:31:07.472: D/ContactRestlet(17638): age2: 0 
02-13 01:31:07.472: D/ContactRestlet(17638): is commited2? false 
02-13 01:31:07.476: W/System.err(17638): 2014-02-13 01:31:07 - - - 8080 DELETE /contacts - 1001 21 12590 62837 http://10.17.1.72:8080 Apache-HttpClient/4.3.1 (java 1.5) - 

編輯: 正如@ RocketRandom,這裏是我的新代碼:

public Boolean deleteBatchContact(final JSONArray jsonArray) throws JSONException, RemoteException, OperationApplicationException 
{ 
    final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 
    final Long startTime = System.currentTimeMillis(); 

    if(jsonArray.length() != 0) // there must be something in the JSONArray 
    { 
     StringBuilder query = new StringBuilder(" in {"); 
     for(int i = 0; i < jsonArray.length(); i++) 
     { 
      final JSONObject jsonContactObject = jsonArray.getJSONObject(i); 
      final String contactId = jsonContactObject.getString("id"); 

      query.append(contactId).append(","); 
     } 
     query.deleteCharAt(query.length()-1); 
     query.append("}"); 

     ops.add(ContentProviderOperation.newDelete(Contacts.CONTENT_URI) 
     .withSelection(Contacts._ID + " in { 1 , 2 , 3 , 4 , 5, 6, 7, 8, 9}", null).build()); 

     try { 
      final ContentProviderResult[] cpr = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops); 
      final Long endTimeTry = System.currentTimeMillis(); 
      final Integer numberOfContactsDeleted = cpr.length; 

      if(numberOfContactsDeleted > 0) 
      { 
       Log.d(TAG, numberOfContactsDeleted + " Contacts deleted!"); 
       final Long totalSuccess = endTimeTry-startTime; 
       Log.d(TAG, "Total Time (Sucess): " + totalSuccess); 

       return true; 
      } 
      else 
      { 
       Log.d(TAG, "Menor ou igual a zero..."); 
       final Long totalFailed = endTimeTry-startTime; 
       Log.d(TAG, "Total Time (No deletes): " + totalFailed); 
       return false; 
      } 
     } catch (Exception e) { 
      Log.d(TAG, "deleteBatchContact: " + e.getMessage()); 
      return false; 
     } 
    } 
    Long endTimeReturnFalse = System.currentTimeMillis(); 
    Long totalTimeReturnFalse = endTimeReturnFalse - startTime; 
    Log.d(TAG, "Total time return false: " + totalTimeReturnFalse); 
    return false; 
} 

這是輸出:

03-06 01:42:10.367: D/ContactList(8925): 1 Contacts deleted! 
03-06 01:42:10.367: D/ContactList(8925): Total Time (Sucess): 84 

現在,它不刪除任何接觸,你可以當場哪來的錯誤? 即使它說,一個聯繫人刪除,沒有被刪除。所有這些聯絡人ID是有效的(他們在我的聯繫人表中,我已經從我的設備下載,並檢查它。)

回答

1

編輯:刪除早先提出的解決方案。這是行不通的。 (對不起爲該)

我檢查觸點者代碼和批量刪除僅支持生接觸。對於聯繫人,他們在那裏執行只是返回,他們有一個很好的「TODO」在那裏。

您的原始代碼是正確的做法。 當你刪除一個聯繫人(沒有isCallerSyncAdapter標誌)時,提供者會做什麼,它查詢所有具有該聯繫人ID的原始聯繫人,並設置髒標誌一個接一個(所以需要一段時間)

我試過我的目的:

03-19 13:28:11.620:d/tmp目錄(5912):188個聯繫人刪除!

03-19 13:28:11.620:d/TMP(5912):總時間(Sucess):387496

即每接觸,這是可怕的需要大約2秒鐘。 但我不明白的方式,使其更快,而無需修改的Android通訊錄ContentProvider的

+0

據我所知,Android不讓你做這些類型的查詢直入SQL數據庫的精簡版。 – dazito

+0

我的意思是使用android提供的API創建一個類似的查詢。可以調整where字符串以合併上述查詢。以示例更新後。 – RocketRandom

+0

請檢查我編輯的問題。現在它不會刪除任何聯繫人。 – dazito