Sqlite 数据库更新触发服务通过 Content Observer 更新

Posted

技术标签:

【中文标题】Sqlite 数据库更新触发服务通过 Content Observer 更新【英文标题】:Sqlite Database updates triggers Service to update via Content Observer 【发布时间】:2012-08-10 06:38:56 【问题描述】:

当我的应用程序中的 sqlite 数据库发生任何更改时,我正在尝试使用 Content Observer 来更新服务。

我不知道该怎么做,所以我在下面整理了一些代码。通常,Content Observers 与带有后台服务的联系人或媒体播放器一起使用。在我的研究中,我读到它可以与手机上的 sqlite 数据库一起使用。

问题: 1.由于Sqlite数据库没有uri,我在People.CONTENT_URI中替换什么信息

this.getContentResolver().registerContentObserver (People.CONTENT_URI, true, contentObserver);

2。在我的研究中,我没有找到任何可以进入数据库类的代码来提醒 ContentObserver。 Content Observer 的所有代码都在服务类中工作吗?

请注意,此问题类似于android SQLite DB notifications 和 how to listen for changes in Contact Database 这两个问题都没有明确回答我的问题。如果您有解释这一点的代码,那将非常有帮助。

下面是我的半pusedo 代码。这是行不通的。我正在使用它来了解如何在数据库信息更改时更新服务。

package com.example.com.test.content.observer;

import java.sql.Date;
import java.util.Calendar;
import java.util.List;

import com.google.android.gcm.demo.app.Alerts.AlarmsService;
import com.google.android.gcm.demo.app.Alerts.Alerts;
import com.google.android.gcm.demo.app.sqllite.DatabaseSqlite;

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.provider.Contacts.People;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.database.ContentObserver;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.support.v4.app.NavUtils;

public class AlarmService extends Service


    Handler mHandler = new Handler();
    DatabaseSqlite db = new DatabaseSqlite(this);
    List<Alerts> listAlerts;
    PendingIntent pendingIntent;


    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.getApplicationContext()
                .getContentResolver()
                .registerContentObserver(?????, true,
                        contentObserver);
    


    public int onStartCommand(Intent intent, int flags, int startId) 
        Log.d("TAG", "started onstart command Created from Alerts service .");
        return super.onStartCommand(intent, flags, startId);// START_STICKY;
    

    @Override
    public void onStart(final Intent intent, int startId) 
        super.onStart(intent, startId);

         runThread();
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
    

    @Override
    public IBinder onBind(Intent intent) 
        return null;
    

    private class MyContentObserver extends ContentObserver 

        @SuppressLint("ParserError")
        public MyContentObserver(Handler mHandler) 
            super(mHandler);
        

        @Override
        public void onChange(boolean selfChange) 

             runThread();

            super.onChange(selfChange);
        



        public void runThread()

            Thread thread = new Thread() 
                @Override
                public void run() 

                    Boolean x = true;
                    while (x) 

                        db.open();
                        listAlerts = db.getAlarmsForService();
                        db.close();
                        int alerts=listAlerts.size();
                        for (int i = 0; i < alerts; i++) 
                            Alerts item = listAlerts.get(i);
                            item.getRowId();
                            item.getRemoteServerId();
                        String alertInMills = item.getAlertDateInMills();
                        String alertDuration = item.getAlertDurationInMinutes();
                        String eventName = item.getEventName();


                        long longAlertInMills = Long.parseLong(alertInMills);



                         pendingIntent = PendingIntent.getService(AlarmsService.this, 0,intent, 0);

                         AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

                         Calendar calendar = Calendar.getInstance();

                        // go to data base for time in mills

                         calendar.setTimeInMillis(longAlertInMills);

                         alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                         pendingIntent);
                        //
                         System.out.println(calendar.toString());

                        

                        //
                        System.out.println("thread");
                        x = false;

                    

                
            ;

            thread.start();
        

        


    MyContentObserver contentObserver = new MyContentObserver(mHandler);

    this.getContentResolver().registerContentObserver (People.CONTENT_URI, true, contentObserver);




【问题讨论】:

你有什么解决办法吗? 【参考方案1】:

一般来说,有两个部分来处理这个问题:ContentObserver 需要注册以接收更改,正如您所指出的那样,SQLiteDatabase 必须通知已注册的观察者任何更改.如果这是您拥有的数据库,您可以创建可用于侦听的 URI。

(1) 首先定义您的 URI,通常在您的数据库定义文件中。

public static final Uri CONTENT_URI = Uri.parse("mycontent://packagename/something");

(2) 为您的数据库内容提供者:

每个数据库函数(插入、更新、删除)在完成操作后都应该调用notifyChange(),以便通知观察者发生了变化。

    rowId = db.insert(tableName, null, cv);
    ...
    getContext().getContentResolver().notifyChange(newUri, null);

(3) 在服务中创建并注册您的ContentObserver,如same link you provided above 中所述(请记住覆盖deliverSelfNotifications() 以返回true)

public class MyService extends Service 
    private MyContentObserver mObserver;

    @Override
    public void onStartCommand(Intent intent, int flags, int startId) 
        ...
        mObserver = new MyContentObserver();
        getContentResolver().registerContentObserver(Dbfile.CONTENT_URI, null, mObserver);
    

    @Override
    public void onDestroy() 
        ...
        if (mObserver != null) 
            getContentResolver().unregisterContentObserver(mObserver);
            mObserver = null;
        
    

    // define MyContentObserver here

(4) 在您的ContentObserver.onChange() 中,您可以在服务中发布一些内容或在可能的情况下处理更改。

此外,如果它对您的事业有帮助,您可以自定义 URI 定义以处理您正在观察的不同类型的数据,为每个 URI 注册您的观察者,然后覆盖 ContentObserver.onChange(boolean, Uri)。

希望这会有所帮助!

【讨论】:

以上是关于Sqlite 数据库更新触发服务通过 Content Observer 更新的主要内容,如果未能解决你的问题,请参考以下文章

当 PHP 提交更新时为 C++ 应用程序调用 SQLite 触发器

有没有办法对通过 Azure 移动服务同步更新的本地 Sqlite 做出反应?

我可以在sqlite中插入触发器之前更新New in吗?

在 SQLite 中为全文搜索索引创建 SQL 触发器

SQLite复杂表的更新方式

SQLite 3.8.8 发布,数据库服务器