Android:内容观察者的“onChange()”方法被多次调用

发布于 2024-11-07 08:14:58 字数 156 浏览 0 评论 0原文

我正在使用 content://sms 的内容观察器。我正在将所有消息写入 SD 卡中的文本文件。但是内容观察器中的 onChange() 方法被多次调用,并且同一消息被多次写入文本文件。如何避免这种情况?我还想知道内容观察器是否会减慢手机速度。

I am using a content observer for content://sms. I am writing all the messages to a text file in SD card. But the onChange() method in the content observer is called multiple times and the same message is written multiple times to the text file. How to avoid this? Also I want to know if having the content observer will slow down the phone.

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

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

发布评论

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

评论(4

柠北森屋 2024-11-14 08:14:58

您需要重写 DeliverSelfNotifications() 以返回 true。

class ObserverSms extends ContentObserver {
private Context mContext;

public ObserverSms(Context context, Handler handler) {
    super(handler);
    mContext = context;
}

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

@Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    MyLog.logDebugInConsole(TAG, "Sms Database Changed");
}
}

You need to override deliverSelfNotifications() to return true.

class ObserverSms extends ContentObserver {
private Context mContext;

public ObserverSms(Context context, Handler handler) {
    super(handler);
    mContext = context;
}

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

@Override
public void onChange(boolean selfChange) {
    super.onChange(selfChange);
    MyLog.logDebugInConsole(TAG, "Sms Database Changed");
}
}
半暖夏伤 2024-11-14 08:14:58

Vivek,请确保每次离开活动时都取消注册内容观察器,例如在 onDestroy() 方法中调用 unregisterContentObserver()。希望这有帮助! (就我而言,它有效)

Vivek, please ensure that you unregister your content observer any time you leave the activity e.g. in onDestroy() method, call unregisterContentObserver(). Hope this help ! (in my case it worked)

节枝 2024-11-14 08:14:58

尝试这样做以避免多次执行 onChange()

private Context context;
    private static int initialPos;
    private static final String TAG = "SMSContentObserver";
    private static final Uri uriSMS = Uri.parse("content://sms/sent");

    public SmsObserver(Handler handler, Context ctx) {
        super(handler);
        context = ctx;
        trackMeData = context.getSharedPreferences("LockedSIM", 0);
        initialPos = getLastMsgId();

    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        queryLastSentSMS();
    }

    public int getLastMsgId() {

        Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
        cur.moveToFirst();
        int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
        Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
        return lastMsgId;
    }

    protected void queryLastSentSMS() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                Cursor cur =
                    context.getContentResolver().query(uriSMS, null, null, null, null);

                if (cur.moveToNext()) {



                    try {

                        String body = cur.getString(cur.getColumnIndex("body"));

                        if (initialPos != getLastMsgId()) {

                            String receiver = cur.getString(cur.getColumnIndex("address"));
                            Log.i("account", myDeviceId);
                            Log.i("date", day + "-" + month + "-" + year + " "
                                + hour + ":" + minute + ":" + seconde);
                            Log.i("sender", myTelephoneNumber);
                            Log.i("receiver", receiver );


                            // Then, set initialPos to the current position.
                            initialPos = getLastMsgId();

                            sendsmstoph(receiver, body);
                        }
                    } catch (Exception e) {
                        // Treat exception here
                    }
                }
                cur.close();
            }
        }).start();

    }

Try this to avoid multiple execution of onChange()

private Context context;
    private static int initialPos;
    private static final String TAG = "SMSContentObserver";
    private static final Uri uriSMS = Uri.parse("content://sms/sent");

    public SmsObserver(Handler handler, Context ctx) {
        super(handler);
        context = ctx;
        trackMeData = context.getSharedPreferences("LockedSIM", 0);
        initialPos = getLastMsgId();

    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        queryLastSentSMS();
    }

    public int getLastMsgId() {

        Cursor cur = context.getContentResolver().query(uriSMS, null, null, null, null);
        cur.moveToFirst();
        int lastMsgId = cur.getInt(cur.getColumnIndex("_id"));
        Log.i(TAG, "Last sent message id: " + String.valueOf(lastMsgId));
        return lastMsgId;
    }

    protected void queryLastSentSMS() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                Cursor cur =
                    context.getContentResolver().query(uriSMS, null, null, null, null);

                if (cur.moveToNext()) {



                    try {

                        String body = cur.getString(cur.getColumnIndex("body"));

                        if (initialPos != getLastMsgId()) {

                            String receiver = cur.getString(cur.getColumnIndex("address"));
                            Log.i("account", myDeviceId);
                            Log.i("date", day + "-" + month + "-" + year + " "
                                + hour + ":" + minute + ":" + seconde);
                            Log.i("sender", myTelephoneNumber);
                            Log.i("receiver", receiver );


                            // Then, set initialPos to the current position.
                            initialPos = getLastMsgId();

                            sendsmstoph(receiver, body);
                        }
                    } catch (Exception e) {
                        // Treat exception here
                    }
                }
                cur.close();
            }
        }).start();

    }
满栀 2024-11-14 08:14:58

onChange() 事件针对每个更改的列(即“正文”或“地址”)调用一次 - 因此需要多次调用。仅处理一次数据的最简单方法是存储“_id”列的值,查看它在下一次迭代中是否已更改,然后忽略。

cur.getColumnIndex("_id")

请参阅此处的示例:
Sms ContentObserver onChange() 多次触发

The onChange() event is called once for each column that changes (i.e. "body" or "address") - thus the multiple calls. The easiest way to only process the data once is to store the value of the "_id" column, see if it has changed on the next iteration and then ignore.

cur.getColumnIndex("_id")

See example here:
Sms ContentObserver onChange() fires multiple times

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