Вопрос по android, service, sqlite, contentobserver – Обновление базы данных Sqlite вызывает обновление службы через обозреватель контента

5

Я пытаюсь использовать Content Observer для обновления Сервиса, когда в моем приложении происходят какие-либо изменения в базе данных sqlite.

Я не совсем понимаю, что делать, поэтому я собрал код ниже. Обычно Обозреватели контента используются с контактами или медиаплеером с фоновым сервисом. В своем исследовании я прочитал, что его можно использовать с базой данных sqlite на телефоне.

Вопросы: 1. Поскольку база данных Sqlite не имеет URI, какую информацию я заменяюPeople.CONTENT_URI в

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

2. В своем исследовании я не нашел ни одного кода, который бы входил в класс базы данных, который бы предупреждал ContentObserver. Работает ли весь код для Content Observer в классе обслуживания?

Обратите внимание, что этот вопрос похож наAndroid SQLite БД уведомления а также как прослушать изменения в базе данных контактов Оба вопроса не дают однозначного ответа на мой вопрос. Если у вас есть код, который объясняет это, это было бы очень полезно.

Вот мой полу-пуседо код ниже. Это не работает. Я использую его, чтобы узнать, как обновить сервис при изменении информации в базе данных.

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



}
Вы смогли найти какое-либо решение? Abhinav

Ваш Ответ

1   ответ
4

В общем, есть две части для обработки этого: у вас естьContentObserver который должен зарегистрироваться для получения изменений, как вы указали, иSQLiteDatabase который должен уведомить зарегистрированных наблюдателей о любых изменениях. Если это ваша база данных, вы можете создать URI, который вы можете использовать для прослушивания.

(1) Сначала определите свой URI, как правило, в файле определения базы данных.

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

(2) для вашей базы данных Content Provider:

Каждая функция БД (вставка, обновление, удаление) должна вызываться доnotifyChange() после завершения операции с целью информирования наблюдателей о произошедших изменениях.

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

(3) Создайте и зарегистрируйте свойContentObserver в Сервисе, как описано вта же ссылка, которую вы указали выше (не забудьте переопределитьdeliverSelfNotifications() вернуть истину)

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 (логическое значение, Uri) вместо.

Надеюсь это поможет!

Похожие вопросы