Indentation and changes that I do not remember
authorgumartinm <gustavo@gumartinm.name>
Sat, 17 Nov 2012 19:21:26 +0000 (20:21 +0100)
committergumartinm <gustavo@gumartinm.name>
Sat, 17 Nov 2012 19:21:26 +0000 (20:21 +0100)
Android/MobiAdsReloaded/project.properties
Android/MobiAdsReloaded/src/de/android/mobiads/batch/MobiAdsBatch.java

index 0840b4a..e484b3c 100644 (file)
@@ -11,4 +11,4 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-15
+target=Google Inc.:Google APIs:16
index 42d0ac1..72d409c 100644 (file)
@@ -12,6 +12,7 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
@@ -24,6 +25,7 @@ import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONTokener;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -36,282 +38,295 @@ import de.android.mobiads.MobiAdsService;
 import de.android.mobiads.provider.Indexer;
 
 public class MobiAdsBatch {
-       private static final String TAG = "MobiAdsBatch";
-       private static final int tasksMax = 10;
-       private final ExecutorService exec = Executors.newFixedThreadPool(tasksMax);
-       private final AndroidHttpClient httpClient;
-       private final Context context;
-       private final String mobiAdsCookie;
-       private static final String USERS_SERVER = "http://companies.mobiads.gumartinm.name/uploads/images/";
-       
-       
-       public MobiAdsBatch (String userAgent, String encoded, Context context, String cookie) {
-               this.context = context;
-               this.httpClient = AndroidHttpClient.newInstance(userAgent);
-               this.mobiAdsCookie = cookie;
-               this.httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, encoded);
-               this.httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
-               
-       }
-       
-       
-       public void makeUseOfNewLocation(Location location) {
-       
-       final String latitude = Double.toString(location.getLatitude());
-       final String longitude = Double.toString(location.getLongitude());
+    private static final String TAG = "MobiAdsBatch";
+    private static final int tasksMax = 10;
+    private final ExecutorService exec = Executors.newFixedThreadPool(tasksMax);
+    private final AndroidHttpClient httpClient;
+    private final Context context;
+    private final String mobiAdsCookie;
+    private static final String USERS_SERVER = "http://companies.mobiads.gumartinm.name/uploads/images/";
+
+
+    public MobiAdsBatch (final String userAgent, final String encoded, final Context context, final String cookie) {
+        this.context = context;
+        this.httpClient = AndroidHttpClient.newInstance(userAgent);
+        this.mobiAdsCookie = cookie;
+        this.httpClient.getParams().setParameter(CoreProtocolPNames.HTTP_CONTENT_CHARSET, encoded);
+        this.httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
+
+    }
+
+
+    public void makeUseOfNewLocation(final Location location) {
+
+        final String latitude = String.valueOf(location.getLatitude());
+        final String longitude = String.valueOf(location.getLongitude());
         final String latitudeReplace = latitude.replace(".", ",");
         final String longitudeReplace = longitude.replace(".", ",");
-       final String URLAuth = "http://users.mobiads.gumartinm.name/userfront.php/api/" + latitudeReplace + "/" + longitudeReplace + "/gpsads.json";
-       URL url = null;
-       
-               try {
-                       //RESTful WebService
-                       url = new URL(URLAuth);
-               } catch (MalformedURLException e) {
-                       Log.e(TAG, "Error while creating a URL", e);
-                       return;
-               }
-               
-               final Batch batch = new Batch(url);
-               
-               this.exec.execute(batch);
-       }
-       
-       
-       public void endBatch() {
-               this.exec.shutdown();
-               this.httpClient.close();
-       }
-
-       
-       private class Batch implements Runnable {
-               private final URL url;
-               
-               private Batch (URL url) {
-                       this.url = url;
-               }
-
-               @Override
-               public void run() {
-                       ResponseHandler<StringBuilder> handler = new ResponseHandler<StringBuilder>() {
-                           public StringBuilder handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
-                               //There could be a null as return value in case of not receiving any data from the server, 
-                               //although the HTTP connection was OK.
-                               return sortResponse(response);
-                           }
-                       };
-                       
-                       try {
-                               final HttpGet httpGet = new HttpGet();
-                               
-                               httpGet.setHeader("Cookie", MobiAdsBatch.this.mobiAdsCookie);
-                               try {
-                                       httpGet.setURI(this.url.toURI());
-                                       StringBuilder builder = httpClient.execute(httpGet, handler);
-                                       JSONTokener tokener = new JSONTokener(builder.toString());
-                                       JSONArray finalResult = new JSONArray(tokener);
-                                       Uri uriInsert = null;
-                                       
-                                       //TODO: finalResult.length() -1? Maybe I should remove the last semicolon in the JSON response.
-                                       for (int i = 0; i < (finalResult.length() -1); i++) {
-                                               JSONObject objects = finalResult.getJSONObject(i);
-                                               if ((uriInsert = updatedIndexer(objects)) != null) {
-                                                       try {
-                                                               downloadAds((String)objects.get("image"), (String) objects.get("id"));
-                                                               
-                                                               //Update view on activities.
-                                                               Intent updateList = new Intent("de.android.mobiads.MOBIADSLISTRECEIVER");
-                                                               MobiAdsBatch.this.context.sendBroadcast(updateList);
-                                                               
-                                                               //Change notification (if there is one)
-                                                               ((MobiAdsService)MobiAdsBatch.this.context).updateNotification();
-
-                                                       } catch (Throwable e1) {
-                                                               //In case of any error, remove the index database and the file
-                                                               //or chunk successfully stored before the error.
-                                                               try {
-                                                                       MobiAdsBatch.this.context.getContentResolver().delete(uriInsert, null, null);
-                                                                       MobiAdsBatch.this.context.deleteFile((String) objects.get("id"));
-                                                               } catch (Throwable e2) {
-                                                                       // Log this exception. The original exception (if there is one) is more
-                                                                       // important and will be thrown to the caller.
-                                                                       Log.w(TAG, "Error removing content after an exception.", e2);
-                                                               }
-                                                               
-                                                               //Besides throw the original exception.
-                                                               if (e1 instanceof Error) {
-                                                                       throw (Error) e1;
-                                                               }
-                                                               if (e1 instanceof RuntimeException) {
-                                                                       throw (RuntimeException) e1;
-                                                               }
-                                                               if (e1 instanceof IOException) {
-                                                                       throw (IOException) e1;
-                                                               }
-                                                               //throwing Throwable. At least the original exception is not lost :/
-                                                               throw new UndeclaredThrowableException(e1);
-                                                       }
-                                               }
-                                               
-                                       }
-                               } catch (URISyntaxException e) {
-                                       Log.e(TAG, "Error while creating URI from URL.", e);
-                               } catch (ClientProtocolException e) {
-                                       Log.e(TAG, "Error while executing HTTP client connection.", e);
-                               } catch (UnsupportedEncodingException e) {
-                                       Log.e(TAG, "Error  InputStreamReader.", e);
-                               } catch (IOException e) {
-                                       Log.e(TAG, "Error while executing HTTP client connection.", e);
-                               } catch (JSONException e) {
-                                       Log.e(TAG, "Error while parsing JSON response.", e);
-                               }
-                       } catch (Throwable e) {
-                               //Not sure if it is "legal" to catch Throwable...
-                               Log.e(TAG, "Caught exception, something went wrong", e);
-                       }
-               }
-               
-               public StringBuilder sortResponse(HttpResponse httpResponse) throws IOException {
-                       StringBuilder builder = null;
-                       
-                       if (httpResponse != null) {
-                               switch (httpResponse.getStatusLine().getStatusCode()) {
-                               case HttpStatus.SC_OK:
-                                       //OK
-                                       HttpEntity entity = httpResponse.getEntity();
-                                       if (entity != null) {
-                                               //outside try/catch block.
-                                               //In case of exception it is thrown, otherwise instream will not be null and we get into the try/catch block.
-                                               InputStreamReader instream = new InputStreamReader(entity.getContent()/*, entity.getContentEncoding().getValue()*/);
-                                               try {
-                                                       BufferedReader reader = new BufferedReader(instream);
-                                                       builder = new StringBuilder();
-                                                       String currentLine = null;
-                                                       currentLine = reader.readLine();
-                                                       while (currentLine != null) {
-                                                               builder.append(currentLine).append("\n");
-                                                               currentLine = reader.readLine();
-                                                       }
-                                               } finally {
-                                                       //instream will never be null in case of reaching this code, cause it was initialized outside try/catch block.
-                                                       //In case of exception here, it is thrown to the upper layer.
-                                                       instream.close();
-                                               }
-                                       }
-                                       break;
-                               case HttpStatus.SC_UNAUTHORIZED:
-                                       //ERROR IN USERNAME OR PASSWORD
-                                       throw new SecurityException("Unauthorized access: error in username or password.");
-                               case HttpStatus.SC_BAD_REQUEST:
-                                       //WHAT THE HECK ARE YOU DOING?
-                                       throw new IllegalArgumentException("Bad request.");
-                               default:
-                                       throw new IllegalArgumentException("Error while retrieving the HTTP status line.");
-                               }
-                       }
-                       return builder; 
-               }
-               
-               public void downloadAds(String image, String path)
-                               throws MalformedURLException, URISyntaxException, FileNotFoundException, IOException {
-                       final HttpGet httpGet = new HttpGet();
-                       final String URLAd = USERS_SERVER + image;
-                       HttpResponse httpResponse = null;
-                       URL url = null;
-                       OutputStream outputStream = null;
-                       
-                       try {
-                               url = new URL(URLAd);
-                               httpGet.setURI(url.toURI());
-                               //By default max 2 connections at the same time per host.
-                               //and infinite time out (we could wait here forever if we do not use a timeout see: 2.1. Connection parameters
-                               //http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html) The same for execute with handler.
-                               httpResponse = MobiAdsBatch.this.httpClient.execute(httpGet);
-                               
-                               if (httpResponse != null) {
-                                       switch (httpResponse.getStatusLine().getStatusCode()) {
-                                       case HttpStatus.SC_OK:
-                                               outputStream = MobiAdsBatch.this.context.openFileOutput(path, Context.MODE_PRIVATE);
-                                               try {
-                                                       httpResponse.getEntity().writeTo(outputStream);
-                                               } finally {
-                                                       //Closing the outputStream
-                                                       outputStream.close();
-                                               }
-                                               break;
-                                       case HttpStatus.SC_UNAUTHORIZED:
-                                               //ERROR IN USERNAME OR PASSWORD
-                                               throw new SecurityException("Unauthorized access: error in username or password.");
-                                       case HttpStatus.SC_BAD_REQUEST:
-                                               //WHAT THE HECK ARE YOU DOING?
-                                               throw new IllegalArgumentException("Bad request.");
-                                       default:
-                                               throw new IllegalArgumentException("Error while retrieving the HTTP status line.");
-                                       }
-                               }
-                       } finally {
-                               try {
-                                       if (httpResponse != null) {
-                                               HttpEntity entity = httpResponse.getEntity();
-                                               if (entity != null) {
-                                                       entity.consumeContent();
-                                               }
-                                       }
-                               } catch (IOException e) {
-                                       // Log this exception. The original exception (if there is one) is more
-                                       // important and will be thrown to the caller. See: {@link AbstractHttpClient}
-                                       Log.w("Error consuming content after an exception.", e);
-                               }
-                       }
-               }
-               
-               public Uri updatedIndexer (JSONObject objects) throws JSONException {
-                       Uri updated = null;
-                       Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + objects.get("id"));
-                       
-                       synchronized (MobiAdsBatch.this) {
-                               //getContentResolver().query method never returns Cursor with null value.
-                               //TODO: review my code in order to find more cases like this. :(
-                               //Be aware with the RunTimeExceptions. Apparently Java needs try/catch blocks in everywhere...
-                               //TODO this method outside updatedIndexer. It is all about semantic and good design. No time sorry...
-                               //Open an issue about improving my code some day...
-                               Cursor cursor = MobiAdsBatch.this.context.getContentResolver().query(uri, null, null, null, null);
-                               try {
-                                       if (!cursor.moveToFirst()) {
-                                               //If the advertisement was not stored on the database
-                                               ContentValues values = new ContentValues();
-                                               values.put(Indexer.Index.COLUMN_NAME_ID_AD, new Integer((String) objects.get("id")));
-                                               values.put(Indexer.Index.COLUMN_NAME_PATH, (String) objects.get("id"));
-                                               values.put(Indexer.Index.COLUMN_NAME_TEXT, (String) objects.get("text"));
-                                               values.put(Indexer.Index.COLUMN_NAME_URL, (String) objects.get("link"));
-                                               values.put(Indexer.Index.COLUMN_NAME_AD_NAME, (String) objects.get("adname"));
-                                               values.put(Indexer.Index.COLUMN_NAME_IS_READ, new Integer(0));
-                                               //This method may throw SQLiteException (as a RunTimeException). So, without a try/catch block
-                                               //there could be a leaked cursor...
-                                               //TODO: review code looking for more cases like this one...
-                                               updated = MobiAdsBatch.this.context.getContentResolver().insert(Indexer.Index.CONTENT_ID_URI_BASE, values);
-                                       }
-                               } finally {
-                                       cursor.close();
-                               }
-                       }
-                       return updated;
-               }
-       }
-       
-       
-       public int noReadAdsCount() {
-               Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/isRead/");
-               
-               Cursor cursor = MobiAdsBatch.this.context.getContentResolver().query(uri, null, null, null, null);
-               int count = 0; 
-               
-               try {
-                       count = cursor.getCount();
-               } finally {
-                       cursor.close();
-               }
-               
-               return count;
-       }
+        final String URLAuth = "http://users.mobiads.gumartinm.name/userfront.php/api/" + latitudeReplace + "/" + longitudeReplace + "/gpsads.json";
+        URL url = null;
+
+        try {
+            //RESTful WebService
+            url = new URL(URLAuth);
+        } catch (final MalformedURLException e) {
+            Log.e(TAG, "Error while creating a URL", e);
+            return;
+        }
+
+        final Batch batch = new Batch(url);
+
+        this.exec.execute(batch);
+    }
+
+
+    public void endBatch() {
+        this.exec.shutdown();
+        this.httpClient.close();
+    }
+
+
+    private class Batch implements Runnable {
+        private final URL url;
+
+        private Batch (final URL url) {
+            this.url = url;
+        }
+
+        @Override
+        public void run() {
+            final ResponseHandler<StringBuilder> handler = new ResponseHandler<StringBuilder>() {
+                @Override
+                public StringBuilder handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
+                    //There could be a null as return value in case of not receiving any data from the server,
+                    //although the HTTP connection was OK.
+                    return sortResponse(response);
+                }
+            };
+
+            try {
+                final HttpGet httpGet = new HttpGet();
+
+                httpGet.setHeader("Cookie", MobiAdsBatch.this.mobiAdsCookie);
+                try {
+                    httpGet.setURI(this.url.toURI());
+                    final StringBuilder builder = httpClient.execute(httpGet, handler);
+                    final JSONTokener tokener = new JSONTokener(builder.toString());
+                    final JSONArray finalResult = new JSONArray(tokener);
+                    Uri uriInsert = null;
+
+                    //TODO: finalResult.length() -1? Maybe I should remove the last semicolon in the JSON response.
+                    for (int i = 0; i < (finalResult.length() -1); i++) {
+                        final JSONObject objects = finalResult.getJSONObject(i);
+                        if ((uriInsert = updatedIndexer(objects)) != null) {
+                            try {
+                                downloadImage((String)objects.get("image"), (String) objects.get("id"));
+
+                                //Update view on activities.
+                                final Intent updateList = new Intent("de.android.mobiads.MOBIADSLISTRECEIVER");
+                                MobiAdsBatch.this.context.sendBroadcast(updateList);
+
+                                //Change notification (if there is one)
+                                ((MobiAdsService)MobiAdsBatch.this.context).updateNotification();
+
+                            } catch (final Throwable e1) {
+                                //In case of any error, remove the index database and the file
+                                //or chunk successfully stored before the error.
+                                try {
+                                    MobiAdsBatch.this.context.getContentResolver().delete(uriInsert, null, null);
+                                    MobiAdsBatch.this.context.deleteFile((String) objects.get("id"));
+                                } catch (final Throwable e2) {
+                                    // Log this exception. The original exception (if there is one) is more
+                                    // important and will be thrown to the caller.
+                                    Log.w(TAG, "Error removing content after an exception.", e2);
+                                }
+
+                                //Besides throw the original exception.
+                                if (e1 instanceof Error) {
+                                    throw (Error) e1;
+                                }
+                                if (e1 instanceof RuntimeException) {
+                                    throw (RuntimeException) e1;
+                                }
+                                if (e1 instanceof Exception) {
+                                    throw (Exception) e1;
+                                }
+                                //throwing Throwable. At least the original exception is not lost :/
+                                throw new UndeclaredThrowableException(e1);
+                            }
+                        }
+
+                    }
+                } catch (final URISyntaxException e) {
+                    Log.e(TAG, "Error while creating URI from URL.", e);
+                } catch (final ClientProtocolException e) {
+                    Log.e(TAG, "Error while executing HTTP client connection.", e);
+                } catch (final UnsupportedEncodingException e) {
+                    Log.e(TAG, "Error  InputStreamReader.", e);
+                } catch (final IOException e) {
+                    Log.e(TAG, "Error while executing HTTP client connection.", e);
+                } catch (final JSONException e) {
+                    Log.e(TAG, "Error while parsing JSON response.", e);
+                }
+            } catch (final Throwable e) {
+                //Not sure if it is "legal" to catch Throwable...
+                Log.e(TAG, "Caught exception, something went wrong", e);
+            }
+        }
+
+        public StringBuilder sortResponse(final HttpResponse httpResponse) throws IOException {
+            StringBuilder builder = null;
+
+            if (httpResponse != null) {
+                switch (httpResponse.getStatusLine().getStatusCode()) {
+                    case HttpStatus.SC_OK:
+                        //OK
+                        final HttpEntity entity = httpResponse.getEntity();
+                        if (entity != null) {
+                            //outside try/catch block.
+                            //In case of exception it is thrown, otherwise instream will not be null and we get into the try/catch block.
+                            final InputStreamReader instream = new InputStreamReader(entity.getContent()/*, entity.getContentEncoding().getValue()*/);
+                            try {
+                                final BufferedReader reader = new BufferedReader(instream);
+                                builder = new StringBuilder();
+                                String currentLine = null;
+                                currentLine = reader.readLine();
+                                while (currentLine != null) {
+                                    builder.append(currentLine).append("\n");
+                                    currentLine = reader.readLine();
+                                }
+                            } finally {
+                                //instream will never be null in case of reaching this code, cause it was initialized outside try/catch block.
+                                //In case of exception here, it is thrown to the upper layer.
+                                instream.close();
+                            }
+                        }
+                        break;
+                    case HttpStatus.SC_UNAUTHORIZED:
+                        //ERROR IN USERNAME OR PASSWORD
+                        throw new SecurityException("Unauthorized access: error in username or password.");
+                    case HttpStatus.SC_BAD_REQUEST:
+                        //WHAT THE HECK ARE YOU DOING?
+                        throw new IllegalArgumentException("Bad request.");
+                    default:
+                        throw new IllegalArgumentException("Error while retrieving the HTTP status line.");
+                }
+            }
+            return builder;
+        }
+
+        public void downloadImage(final String image, final String path)
+                throws MalformedURLException, URISyntaxException, FileNotFoundException, IOException {
+            final HttpGet httpGet = new HttpGet();
+            final String URLAd = USERS_SERVER + image;
+            HttpResponse httpResponse = null;
+            URL url = null;
+
+            url = new URL(URLAd);
+            httpGet.setURI(url.toURI());
+            //By default max 2 connections at the same time per host.
+            //and infinite time out (we could wait here forever if we do not use a timeout see: 2.1. Connection parameters
+            //http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html) The same for execute with handler.
+            httpResponse = MobiAdsBatch.this.httpClient.execute(httpGet);
+
+            try {
+                saveImage (httpResponse, path);
+            } finally {
+                try {
+                    if (httpResponse != null) {
+                        final HttpEntity entity = httpResponse.getEntity();
+                        if (entity != null) {
+                            entity.consumeContent();
+                        }
+                    }
+                } catch (final IOException e) {
+                    // TODO: Find out what the hell happens when cosumeContent fails.
+                    // The current downloaded data are OK but I do not know if this will stop me of downloading more data.
+                    // If it hurts so bad, I should remove this catch and let this exception go forward. :/
+                    // Log this exception. The original exception (if there is one) is more
+                    // important and will be thrown to the caller.
+
+                    // When getting into a finally block because of exception was thrown from saveImage method,
+                    // even if consumeContent throws another exception and we catch it here, the original one
+                    // does not disappear.
+                    Log.w("Error consuming content after an exception.", e);
+                }
+            }
+        }
+
+        public void saveImage (final HttpResponse httpResponse, final String path) throws FileNotFoundException, IOException {
+            OutputStream outputStream = null;
+
+            if (httpResponse != null) {
+                switch (httpResponse.getStatusLine().getStatusCode()) {
+                    case HttpStatus.SC_OK:
+                        outputStream = MobiAdsBatch.this.context.openFileOutput(path, Context.MODE_PRIVATE);
+                        try {
+                            httpResponse.getEntity().writeTo(outputStream);
+                        } finally {
+                            //Closing the outputStream
+                            outputStream.close();
+                        }
+                        break;
+                    case HttpStatus.SC_UNAUTHORIZED:
+                        //ERROR IN USERNAME OR PASSWORD
+                        throw new SecurityException("Unauthorized access: error in username or password.");
+                    case HttpStatus.SC_BAD_REQUEST:
+                        //WHAT THE HECK ARE YOU DOING?
+                        throw new IllegalArgumentException("Bad request.");
+                    default:
+                        throw new IllegalArgumentException("Error while retrieving the HTTP status line.");
+                }
+            }
+        }
+
+        public Uri updatedIndexer (final JSONObject objects) throws JSONException {
+            Uri updated = null;
+            final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + objects.get("id"));
+
+            synchronized (MobiAdsBatch.this) {
+                //getContentResolver().query method never returns Cursor with null value.
+                //TODO: review my code in order to find more cases like this. :(
+                //Be aware with the RunTimeExceptions. Apparently Java needs try/catch blocks in everywhere...
+                //TODO this method outside updatedIndexer. It is all about semantic and good design. No time sorry...
+                //Open an issue about improving my code some day...
+                final Cursor cursor = MobiAdsBatch.this.context.getContentResolver().query(uri, null, null, null, null);
+                try {
+                    if (!cursor.moveToFirst()) {
+                        //If the advertisement was not stored on the database
+                        final ContentValues values = new ContentValues();
+                        values.put(Indexer.Index.COLUMN_NAME_ID_AD, new Integer((String) objects.get("id")));
+                        values.put(Indexer.Index.COLUMN_NAME_PATH, (String) objects.get("id"));
+                        values.put(Indexer.Index.COLUMN_NAME_TEXT, (String) objects.get("text"));
+                        values.put(Indexer.Index.COLUMN_NAME_URL, (String) objects.get("link"));
+                        values.put(Indexer.Index.COLUMN_NAME_AD_NAME, (String) objects.get("adname"));
+                        values.put(Indexer.Index.COLUMN_NAME_IS_READ, new Integer(0));
+                        //This method may throw SQLiteException (as a RunTimeException). So, without a try/catch block
+                        //there could be a leaked cursor...
+                        //TODO: review code looking for more cases like this one...
+                        updated = MobiAdsBatch.this.context.getContentResolver().insert(Indexer.Index.CONTENT_ID_URI_BASE, values);
+                    }
+                } finally {
+                    cursor.close();
+                }
+            }
+            return updated;
+        }
+    }
+
+
+    public int noReadAdsCount() {
+        final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/isRead/");
+
+        final Cursor cursor = MobiAdsBatch.this.context.getContentResolver().query(uri, null, null, null, null);
+        int count = 0;
+
+        try {
+            count = cursor.getCount();
+        } finally {
+            cursor.close();
+        }
+
+        return count;
+    }
 }