0

Ok, I think this is a recurring question, sorry for that. I need to update my DB collecting some data from web and display a dialog while the data are being downloaded. I have my dialog, data comes fine and writes in database. I'm doing some improvements. Today this works starting from one Activity. My will is this occurs in all application and start after a interval. And this is the moment when problems arise. I'm using AlertManager to schedule my action. I have a BroadcastReceiver that, checks my database and starts to get data from web. At this point I'm facing problems. My progress dialog aren't shown and data doesn't come totally from web.

Code from 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();
    }
}

Reading these posts on StackOverflow and on Kam:

BroadCast receiver dialog issue in Android

AlertDialog in BroadcastReceiver

show an alert dialog in broadcast receiver after a system reboot

How to send data from BroadcastReceiver to an Activity in android?

Android: Prefer Alarms and Intent Receivers to Services <--This is Kam

My conclusions are:

  • BroadcastReceivers can't display dialogs because they aren't Activities(like Commonsware point out);
  • BroadcastReceivers can't handle orientation issues that crashes app(I fix this in my activity overriding onCreateDialog method);
  • Handlers aren't indicated to use in BroadcastReceivers;
  • Services aren't indicated to do this kind of task;

I thought a way to solve this. Creating a class that inherits from activity and inside that I handle orientation issues, schedule my broadcast in it to download the content at some time and displays dialog. And all of other classes inherits from it. This solution works I think, but it's big workaround to solve the problem.

Sorry if my question is too long. I would like to discuss some other solutions(if what I proposed is a valid solution, I didn't tested).

Community
  • 1
  • 1
learner
  • 1,311
  • 3
  • 18
  • 39

1 Answers1

0

A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.

This has important repercussions to what you can do in an onReceive(Context, Intent) implementation: anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous operation completes.

In particular, you may not show a dialog or bind to a service from within a BroadcastReceiver. For the former, you should instead use the NotificationManager API. For the latter, you can use Context.startService() to send a command to the service.

Source: http://developer.android.com/reference/android/content/BroadcastReceiver.html

Paul
  • 5,163
  • 3
  • 35
  • 43
  • thanks for your reply.This solves if my user clicks on notificationbar. My ideia is schedule the intent and trigger it when the time runs out. In this case, the code will only run if the user clicks, what is not the desired functionality. – learner Aug 20 '12 at 15:19