2010-12-15 70 views
1

J'ai implémenté un ContentObserver et cela a bien fonctionné. Mais à chaque fois que le ContentObserver est averti de certaines modifications dans le fournisseur de contenu CallLog.Calls, il exécute la méthode onChange() sans s'arrêter.Android ContentObserver ne s'est jamais arrêté

J'aimerais que mon observateur s'exécute une fois pour chaque élément qui a changé dans le fournisseur de contenu. Ainsi, si 5 nouveaux éléments ont été ajoutés au fournisseur de contenu CallLog.Calls, l'observateur doit être averti 5 fois, et pour chaque notification à l'observateur, un nouvel appel à la méthode onChange() doit avoir lieu.

Voici mon code.

public class RatedCalls extends ListActivity { 

private static final String LOG_TAG = "RATEDCALLSOBSERVER"; 
private Handler handler = new Handler(); 
private RatedCallsContentObserver callsObserver = null; 
private SQLiteDatabase db; 
private Cursor cursor; 
StringBuilder sb = new StringBuilder(); 
OpenHelper openHelper = new OpenHelper(RatedCalls.this); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.getApplicationContext() 
      .getContentResolver() 
      .registerContentObserver(
        android.provider.CallLog.Calls.CONTENT_URI, true, 
        new RatedCallsContentObserver(handler)); 
    Log.d("FILLLIST", "calling from onCreate()"); 
} 

class RatedCallsContentObserver extends ContentObserver { 
    public RatedCallsContentObserver(Handler h) { 
     super(h); 
    } 

    @Override 
    public boolean deliverSelfNotifications() { 
     return true; 
    } 

    @Override 
    public void onChange(boolean selfChange) { 
     Log.d(LOG_TAG, "RatedCallsContentObserver.onChange(" + selfChange 
       + ")"); 
     super.onChange(selfChange); 
     fillList(); 
    } 
} 

private void fillList() { 

    cursor = getContentResolver().query(
      android.provider.CallLog.Calls.CONTENT_URI, null, null, null, 
      android.provider.CallLog.Calls.DATE + " DESC "); 
    Log.d("FILLLIST", "Calling from filllist"); 

    db = openHelper.getWritableDatabase(); 

    startManagingCursor(cursor); 
    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 dateId = cursor.getColumnIndex(android.provider.CallLog.Calls.DATE); 
    int numTypeId = cursor 
      .getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE); 

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

    ArrayList<String> callList = new ArrayList<String>(); 
    cursor.moveToFirst(); 

    String contactNumber = cursor.getString(numberColumnId); 
    String contactName = cursor.getString(contactNameId); 
    String duration = cursor.getString(durationId); 
    String callDate = DateFormat.getDateInstance().format(dateId); 
    String numType = cursor.getString(numTypeId); 

    ContentValues values = 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", duration); 
    values.put("date", callDate); 
    values.put("current_time", currTime); 
    values.put("cont", 1); 
    getBaseContext().getContentResolver().notifyChange(
      android.provider.CallLog.Calls.CONTENT_URI, 
      new RatedCallsContentObserver(handler)); 
    db.insert(CallDataHelper.TABLE_NAME, null, values); 
    Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG); 
    callList.add("Contact Number: " + contactNumber + "\nContact Name: " 
      + contactName + "\nDuration: " + duration + "\nDate: " 
      + callDate); 

    setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem, 
      callList)); 
    ListView lv = getListView(); 
    lv.setTextFilterEnabled(true); 

    lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 

      Toast.makeText(getApplicationContext(), 
        ((TextView) view).getText(), Toast.LENGTH_SHORT).show(); 

     } 
    }); 
} 
} 

Répondre

2

Vous modifiez le contenu DB intérieur le fillList(), alors RatedCallsContentObserver.onChange() est appelé encore et encore ...

1

comprennent une vérification de la date dans cette requête .. android.provider.CallLog.Calls.DATE> dernière date

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

espère que cela vous aidera

+0

Où dois-je ajouter la vérification de la date? Dois-je faire comme ça? Curseur cursor = getContentResolver(). Query (android.provider.CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE + ">?", Nouvelle chaîne [] {lastDate}, null, null, null) – rogcg

+0

Je ne pense pas que cela fonctionnera car il ne recevra les appels avec une date plus élevée que la dernière date. Mais si c'est le même jour. Et si je viens de faire un appel, et que je veux en faire un autre – rogcg

+0

Vérifiez les arguments dans query(), vous pouvez mettre une condition sur cela. Ce problème est-il résolu? – Eby