Android ContentObserver从未停止过

发布于 2024-10-08 05:30:14 字数 4224 浏览 2 评论 0原文

我实现了一个 ContentObserver,它工作得很好。但现在每次 ContentObserver 收到有关 CallLog.Calls 内容提供程序中的某些更改的通知时,它都会不间断地运行 onChange() 方法。

我希望我的观察者为内容提供者中已更改的每个项目运行一次。因此,如果已将 5 个新项目添加到 CallLog.Calls 内容提供程序中,则必须通知观察者 5 次,并且对于每次通知观察者,都必须对 onChange() 方法进行新的调用。

这是我的代码。

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();

        }
    });
}   
}

I implemented a ContentObserver and it worked fine. But now everytime the ContentObserver is notified for some changes in the CallLog.Calls content provider, it runs the onChange() method without stopping.

I'd like that my observer runs once for each item that has changed in the content provider. So, if 5 new items have been added to the CallLog.Calls content provider, the observer must be notified 5 times, and for each notify to the observer, a new call to the onChange() method must happen.

Here is my 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();

        }
    });
}   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美胚控场 2024-10-15 05:30:14

您更改了 fillList() 内部的数据库内容,因此一次又一次调用 RatedCallsContentObserver.onChange()...

You change DB content inside of the fillList(), so RatedCallsContentObserver.onChange() is called again and again...

给妤﹃绝世温柔 2024-10-15 05:30:14

在此查询中包含日期检查.. android.provider.CallLog.Calls.DATE >最后一次约会

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

希望这对你有帮助

include a date check in this query.. android.provider.CallLog.Calls.DATE > last date

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

hope this will help you

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文