如何实现通话记录的 ContentObserver

发布于 2024-10-07 09:25:10 字数 3762 浏览 1 评论 0原文

我想知道是否有办法知道呼叫的内容提供商是否已更改。我的意思是,如果我拨打电话或接听电话,它会返回一个“标志”,表明新日志已添加到通话记录中,或者 Android 存储有关通话信息的位置。

因为,当我拨打电话时,Android 会将号码、联系人姓名(如果存在)、通话时间、持续时间……全部存储在内容提供程序中。那么有没有一种方法可以捕获这个“标志”,表明呼叫的内容提供者更大,我的意思是,新的数据已插入到内容提供者CallLog.Calls上。

所以,对于这个问题,我还是有很多疑问。我不知道在哪里注册内容观察者。我的意图是,当 CallLog 内容提供程序发生变化时,将使用代码的 insert 方法。

我的意思是,除非新数据已添加到 CallLog 内容提供程序中,否则代码不会执行任何操作。如果某些数据已添加到 CallLog 内容提供程序中,则代码将查询新数据,然后插入。我想这样做,因为如果没有内容观察器,应用程序将在每次运行应用程序时已插入的数据库中插入数据,明白了吗?

这是我的代码。如果有人可以告诉我在哪里放置 registerContentObserver() 以及其他需要的东西。

public class RatedCalls extends ListActivity {

    private SQLiteDatabase db;
    private CallDataHelper dh = null;
    StringBuilder sb = new StringBuilder();
    OpenHelper openHelper = new OpenHelper(RatedCalls.this);

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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

        dh = new CallDataHelper(this);
        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>();
        if (cursor.moveToFirst()) {
            do {
                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);

                this.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);

            } while (cursor.moveToNext());
        }
        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'd like to know if there is a way to know if the content provider of callings has changed. I mean, if I make a call, or I answer a call, it returns a "flag" that a new log has been added to the call log, or the place where Android store informations about callings.

Because, when I make a call, Android stores the number, the contact name (if exists), the hour of the calling, the duration, ..., all in the content provider. So is there a way to capture this "flag" that says the content provider of callings is bigger, I mean, that a new data has been inserted on the content provider CallLog.Calls.

So, I still have a lot of doubts related to this issue. I don't know where to register the content observer. My intention is, when something changes in the CallLog content provider, the insert method of the code will be used.

I mean, the code won't do anything unless new data has been added to the CallLog content provider. If some data has been added to the CallLog content provider, then the code will query the new data, and then will insert. I wanna do this, because without a content observer the application was inserting data in the database that was already inserted every time I run the application, got it?

So here is my code. If someone could tell me where to put registerContentObserver() and everything else that is needed.

public class RatedCalls extends ListActivity {

    private SQLiteDatabase db;
    private CallDataHelper dh = null;
    StringBuilder sb = new StringBuilder();
    OpenHelper openHelper = new OpenHelper(RatedCalls.this);

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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

        dh = new CallDataHelper(this);
        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>();
        if (cursor.moveToFirst()) {
            do {
                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);

                this.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);

            } while (cursor.moveToNext());
        }
        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-14 09:25:10

这就是答案。不要忘记用这个方法注册内容观察者:

registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

然后你可以像这样创建它。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.getApplicationContext()
    .getContentResolver()
    .registerContentObserver(
            android.provider.CallLog.Calls.CONTENT_URI, true,
            new MyContentObserver(handler)); 
}

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

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

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

        // here you call the method to fill the list
    }
}

Here is the answer. Dont forget to register the content observer with this method:

registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

And then you can create it like this.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.getApplicationContext()
    .getContentResolver()
    .registerContentObserver(
            android.provider.CallLog.Calls.CONTENT_URI, true,
            new MyContentObserver(handler)); 
}

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

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

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

        // here you call the method to fill the list
    }
}
世界如花海般美丽 2024-10-14 09:25:10

只需创建 ContentObserver 类的新子类并覆盖它的 onChange() 方法即可。 onChange() 方法将包含在内容更改时执行的所有代码。

public class MyObserver extends ContentObserver {
    public MyObserver(Handler handler) {
            super(handler);
        }

    @Override
    public void onChange(boolean selfChange) {
        this.onChange(selfChange,null);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        //Write your code here      }
}

然后您所要做的就是将您的内容提供商注册到 URI。

getContentResolver().registerContentObserver(YourURI,true,myObserver);

请记住取消注册您的内容观察者对象,否则可能会导致内存泄漏。

来源:使用 Android 的 ContentObserver 对内容更改做出反应

Simply create a new subclass of ContentObserver class and override it's onChange() method. The onChange() method will contain all the code that will be executed on content change.

public class MyObserver extends ContentObserver {
    public MyObserver(Handler handler) {
            super(handler);
        }

    @Override
    public void onChange(boolean selfChange) {
        this.onChange(selfChange,null);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {
        //Write your code here      }
}

Then all you have to do is register your content provider to the URI.

getContentResolver().registerContentObserver(YourURI,true,myObserver);

Remember to unregister your content observer object or else it can lead to memory leak.

Source: Use Android's ContentObserver To React On Content Changes

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