Планирование обновления базы данных и отображение диалогового окна

Хорошо, я думаю, что это повторяющийся вопрос, извините за это. Мне нужно обновить мою БД, собирая некоторые данные из Интернета, и отображать диалоговое окно во время загрузки данных. У меня есть мой диалог, данные приходят нормально и записываются в базу данных. Я делаю некоторые улучшения. Сегодня это работает, начиная с одного Activity. Я хочу, чтобы это происходило во всех приложениях и запускалось через определенный промежуток времени. И это момент, когда возникают проблемы. Я использую AlertManager для планирования своих действий. У меня есть BroadcastReceiver, который проверяет мою базу данных и начинает получать данные из Интернета. На данный момент я сталкиваюсь с проблемами. Мой диалог прогресса не отображается, и данные не поступают полностью из Интернета.

Код от BroadcastReceiver:

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

public class SchedulerUpdate extends BroadcastReceiver {
    private Handler mHandler = null;

    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            mHandler = new Handler();
            Log.i("INFO", "SCHEDULED");
            if(checkDataBase(context)){
                updateData(context);
            }
        }
        catch (Exception e) {       
            e.printStackTrace();
        }
    }

    private boolean checkDataBase(Context context){
        String path = "/data/data/"+context.getPackageName()+"/databases/mdsdacpdatabase.db";
        SQLiteDatabase database = null;

        boolean result = false;
        try{
            database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.CREATE_IF_NECESSARY);
            database.close();
            result = true;
        }
        catch(SQLiteException e){
        }

        return result;
    }

    private void updateData(final Context context) {
        ((Activity)context.getApplicationContext()).showDialog(ID_DIALOG_PROGRESS_DOWNLOAD);
        Runnable runnable = new Runnable(){
            public void run(){
                Log.i("INFO", "RUNNING");
                ...
                mHandler.post(new Runnable() {
                    public void run() {
                        ((Activity)context).dismissDialog(ID_DIALOG_PROGRESS_DOWNLOAD);
                        Log.i("INFO", "DONE");
                    }
                });
            };
        };
        new Thread(runnable).start();
    }
}

Читая эти сообщения на StackOverflow и на Kam:

проблема с диалоговым окном приемника BroadCast в Android

AlertDialog в BroadcastReceiver

показать диалоговое окно предупреждения в широковещательном приемнике после того, как система перезагрузить

Как отправить данные из BroadcastReceiver в Activity в андроид?

Android: предпочитать будильники и Получатели намерений для сервисов ‹ -- Это Кам

Мои выводы:

  • BroadcastReceivers не могут отображать диалоги, потому что они не являются действиями (как указывает Commonsware);
  • BroadcastReceivers не может обрабатывать проблемы с ориентацией, которые приводят к сбою приложения (я исправляю это в своей деятельности, переопределяя метод onCreateDialog);
  • Обработчики не предназначены для использования в BroadcastReceivers;
  • Службы не предназначены для выполнения такого рода задач;

Я думал, как это решить. Создание класса, который наследуется от активности, и внутри которого я решаю проблемы с ориентацией, планирую свою трансляцию в нем, чтобы загружать контент в какое-то время и отображать диалог. И все остальные классы наследуются от него. Я думаю, что это решение работает, но это большой обходной путь для решения проблемы.

Извините, если мой вопрос слишком длинный. Я хотел бы обсудить некоторые другие решения (если то, что я предложил, является допустимым решением, я не проверял).


person learner    schedule 19.08.2012    source источник


Ответы (1)


Объект BroadcastReceiver действителен только на время вызова onReceive(Context, Intent). Как только ваш код возвращается из этой функции, система считает, что объект завершен и больше не активен.

Это имеет важные последствия для того, что вы можете сделать в реализации onReceive(Context, Intent): все, что требует асинхронной операции, недоступно, потому что вам нужно будет вернуться из функции для обработки асинхронной операции, но в этот момент BroadcastReceiver больше не активен, и, таким образом, система может завершить свой процесс до завершения асинхронной операции.

В частности, вы не можете отображать диалоговое окно или привязываться к службе из BroadcastReceiver. В первом случае вам следует использовать API NotificationManager. В последнем случае вы можете использовать Context.startService() для отправки команды службе.

Источник: http://developer.android.com/reference/android/content/BroadcastReceiver.html

person Paul    schedule 19.08.2012
comment
спасибо за ваш ответ. Это решает, если мой пользователь нажимает на панель уведомлений. Моя идея заключается в том, чтобы планировать намерение и запускать его, когда время истекает. В этом случае код будет работать только в том случае, если пользователь нажмет, что не является желаемой функциональностью. - person learner; 20.08.2012