Tobias Moe Thorstensen
Tobias Moe Thorstensen

Reputation: 8981

BroadcastReceiver is called infinite times

I have a BroadcastReceiver which will monitor the state of my connection to Wifi or Mobile network. The whole point of this BroadcastReceiver is to access a SQLite Database when the handset has established a connection.

So in my onPause method, I register the Reciever:

networkMonitor = new CaseQueueReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);        
registerReceiver(networkMonitor, filter);

and in my onDestory method, I unregister it

unregisterReceiver(networkMonitor);

Over to this networkMonitor receiver

public class CaseQueueReceiver extends BroadcastReceiver {

    public boolean available;
    DatabaseHandler db;
    QueueDB queueDB; 
    HashMap<String, String> queueHashMap;

    public CaseQueueReceiver() {
        db = new DatabaseHandler(ContextHelper.context());
        queueDB = new QueueDB(ContextHelper.context()); 
        queueHashMap = new HashMap<String, String>(); 
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
            NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
            String typeName = info.getTypeName();
            String subtypeName = info.getSubtypeName();
            available = info.isAvailable();
            Log.i("Network Monitor", "Network Type: " + typeName 
                + ", subtype: " + subtypeName
                + ", available: " + available);

          //call a method which will get all the unsent cases from the database, and update their field of sent status
         //in order to do so, add an extra column in the database, also remember to delete the cases.    

         if(available) {

             int count = queueDB.countUnsentCases();
             Log.i("Count unsentCases: ", Integer.toString(count));
             queueDB.getUnsetCases();

            // Iterator<Entry<String, String>> it = queueHashMap.entrySet().iterator();
//           while (it.hasNext()) {
//                  Map.Entry pairs = (Map.Entry)it.next();
//                  Log.i("In the Queue: ", "PCN: " + pairs.getKey() + " Nist-File: " + pairs.getValue());
//           }

         }
        }
    }

And my two methods from the QueueDB

public int countUnsentCases() {

        String SQLQuery = "SELECT COUNT(" + PCN + ") FROM "
                + TABLE_CASES_IN_QUEUE + ";";
        SQLiteDatabase db = this.getWritableDatabase();

        Cursor cursor = db.rawQuery(SQLQuery, null);
        cursor.moveToFirst();
        int count = cursor.getInt(0);
        cursor.close();
        db.close();

        return count;
    }

    public HashMap<String, String> getUnsetCases() {

        HashMap<String, String> queueHashMap = new HashMap<String, String>();

        SQLiteDatabase db = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_CASES_IN_QUEUE + ";";
        Cursor cursor = db.rawQuery(query, null);

        if (cursor.moveToFirst()) {
            do {

                Log.i("CURSOR(0)", cursor.getString(0));
                // queueHashMap.put(cursor.getString(0), cursor.getString(1));
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();

        return queueHashMap;
    }

The problem that I'm experiencing is that the onReceive method will be called infinite when I have Wifi turned on. This will not cause any exception, my application will just hang, and eating memory of the heap. I am aware that I should to reading/writing to the database in a Thread. Can anyone explain to why this onReceive method will be called so many times? What is the best approach to solve this problem?

Thanks in advance!

Upvotes: 0

Views: 323

Answers (1)

RAW
RAW

Reputation: 7825

public static final String CONNECTIVITY_ACTION

Added in API level 1
A change in network connectivity has occurred. A connection has either been established or lost. The NetworkInfo for the affected network is sent as an extra; it should be consulted to see what kind of connectivity event occurred.

If this is a connection that was the result of failing over from a disconnected network, then the FAILOVER_CONNECTION boolean extra is set to true.

For a loss of connectivity, if the connectivity manager is attempting to connect (or has already connected) to another network, the NetworkInfo for the new network is also passed as an extra. This lets any receivers of the broadcast know that they should not necessarily tell the user that no data traffic will be possible. Instead, the reciever should expect another broadcast soon, indicating either that the failover attempt succeeded (and so there is still overall data connectivity), or that the failover attempt failed, meaning that all connectivity has been lost.

For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY is set to true if there are no connected networks at all.

Constant Value: "android.net.conn.CONNECTIVITY_CHANGE"

Upvotes: 2

Related Questions