2011-06-09 62 views
4

我試圖從CallLog中查詢數據並插入到數據庫中。爲此,我創建了一個COntentObserver作爲Service中的內部類,並在onChange()方法中調用了我的方法,該方法轉到指定的URI並查詢已更改的數據。ContentObserver onChange()重複多次

但是,讓我們說,我接到一個電話,所以觀察員被通知。所以,我的方法去通話記錄內容提供商,查詢和插入,但它插入兩個,三個相同的寄存器。

這是我的服務代碼。

public class RatedCallsService extends Service 

private Handler handler = new Handler(); 
    private SQLiteDatabase db; 
    private OpenHelper helper; 
    private String theDate; 
    private String theMonth_; 
    private String theYear_; 
    private String theDay_; 
    public static boolean servReg = false; 

    class RatedCallsContentObserver extends ContentObserver { 

      public RatedCallsContentObserver(Handler h) { 

       super(h); 
       //helper = new OpenHelper(getApplicationContext()); 
       //db = helper.getWritableDatabase(); 

      } 

      @Override 
      public boolean deliverSelfNotifications() { 

       return true; 

      } 

      @Override 
      public void onChange(boolean selfChange) { 

       super.onChange(selfChange); 
       Log.i(LOG_TAG, "Inside on Change. selfChange " + selfChange); 
       searchInsert(); 
      } 
     } 

     @Override 
     public IBinder onBind(Intent arg0) { 

      return null; 

     } 

     @Override 

     public void onCreate() { 
      servReg = true; 
      db = DataHandlerDB.createDB(this); 
      registerContentObserver(); 

     } 

     @Override 
     public void onDestroy() { 

      super.onDestroy(); 
      db.close(); 
      this.getApplicationContext().getContentResolver().unregisterContentObserver(new RatedCallsContentObserver(handler)); 

     } 

     private void searchInsert() { 

        Cursor cursor = getContentResolver().query(
      android.provider.CallLog.Calls.CONTENT_URI, null, null, null, 
      android.provider.CallLog.Calls.DATE + " DESC "); 

    if (cursor.moveToFirst()) { 

     int numberColumnId = cursor 
       .getColumnIndex(android.provider.CallLog.Calls.NUMBER); 
     int durationId = cursor 
       .getColumnIndex(android.provider.CallLog.Calls.DURATION); 
     int contactNameId = cursor 
       .getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME); 
     int numTypeId = cursor 
       .getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE); 
     int callTypeId = cursor 
       .getColumnIndex(android.provider.CallLog.Calls.TYPE); 

     Date dt = new Date(); 
     int hours = dt.getHours(); 
     int minutes = dt.getMinutes(); 
     int seconds = dt.getSeconds(); 
     String currTime = hours + ":" + minutes + ":" + seconds; 

     SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy"); 

     Date date = new Date(); 

     cursor.moveToFirst(); 

     String contactNumber = cursor.getString(numberColumnId); 
     String contactName = (null == cursor.getString(contactNameId) ? "" 
       : cursor.getString(contactNameId)); 
     String duration = cursor.getString(durationId); 
     String numType = cursor.getString(numTypeId); 
     String callType = cursor.getString(callTypeId); 

     seconds = Integer.parseInt(duration); 

     theDate = dateFormat.format(date); 

     if (theDate.length() == 9) { 

      theMonth_ = theDate.substring(0, 1); 
      theDay_ = theDate.substring(2, 4); 
      theYear_ = theDate.substring(5, 9); 

     } else if (theDate.length() == 10) { 

      theMonth_ = theDate.substring(0, 2); 
      theDay_ = theDate.substring(3, 4); 
      theYear_ = theDate.substring(6, 10); 

     } else if (theDate.length() == 8) { 

      theMonth_ = theDate.substring(0, 1); 
      theDay_ = theDate.substring(2, 3); 
      theYear_ = theDate.substring(4, 8); 

     } 

     ContentValues values = new ContentValues(); 
     ContentValues values2 = new ContentValues(); 

     values.put("contact_id", 1); 
     values.put("contact_name", contactName); 
     values.put("number_type", numType); 
     values.put("contact_number", contactNumber); 
     values.put("duration", Utilities.convertTime(seconds)); 
     values.put("date", dateFormat.format(date)); 
     values.put("current_time", currTime); 
     values.put("cont", 1); 
     values.put("type", callType); 

     values2.put("month", 
       Utilities.monthName(Integer.parseInt(theMonth_))); 
     values2.put("duration", Utilities.convertTime(seconds)); 
     values2.put("year", theYear_); 
     values2.put("month_num", Integer.parseInt(theMonth_)); 

     if (!db.isOpen()) { 
      db = getApplicationContext() 
        .openOrCreateDatabase(
          "/data/data/com.project.myapp/databases/myDb.db", 
          SQLiteDatabase.OPEN_READWRITE, null); 
     }   
     if (duration != "") {    
      if (Integer.parseInt(duration) != 0) { 

       String existingMonthDuration = DataHandlerDB 
         .selectMonthsDuration(theMonth_, theYear_, this); 
       Integer newMonthDuration; 


       if (existingMonthDuration != "") { 

        newMonthDuration = Integer 
          .parseInt(existingMonthDuration) 
          + Integer.parseInt(duration);      

        values2.put("duration", 
          Utilities.convertTime(newMonthDuration)); 
        db.update(DataHandlerDB.TABLE_NAME_3, values2, 
          "year = ?", new String[] { theYear_ }); 

       } else { 

        db.insert(DataHandlerDB.TABLE_NAME_3, null, values2); 

       } 

       db.insert(DataHandlerDB.TABLE_NAME_2, null, values); 

      } 
     } 
     cursor.close(); 

    } 

      } 

    public void registerContentObserver() { 

      this.getApplicationContext() 
        .getContentResolver() 
        .registerContentObserver(
          android.provider.CallLog.Calls.CONTENT_URI, false, 
          new RatedCallsContentObserver(handler)); 

     } 
    } 

我試過了一切。註銷觀察員等,但沒有任何內容。

回答

2

我從android.provider.CallLog.Calls.DATE中選擇了呼叫的時間戳,在插入之前我檢查是否有像這樣的時間戳,如果有我不插入,如果沒有我插入數據。這個值是獨一無二的,所以永遠不會有彼此喜歡的東西。

1

在我訂閱短信內容提供商時,會發生這種情況。我認爲他們是Android處理消息和調用這種行爲的方式,每當我發送短信時我都會收到2次呼叫,所以我猜是因爲郵件放在發件箱表中了?首先,然後移動到發送表。呼叫提供商可能會發生類似情況嗎?也許這個電話被放置在提供商內部的一個臨時表中,然後一旦你收到它或者錯過它,這個電話就會轉到正確的表格(收到/錯過)。我所做的是,每次我的觀察者被調用時,我都會檢查消息的Id,並且保留前一個消息的Id,以便我可以檢查由於我剛剛處理的相同ID而導致觀察者是否被調用。

自我更改是否有所不同?

提示。不要依賴此提供商來監控您的所有呼叫。一旦android決定終止你的應用程序,你會注意到你的提供者將不會收到任何呼叫。嘗試使用AlarmManager每隔一段時間安排內容觀察者的附件。