Retrieving cookie from Service.
authorgumartinm <gustavo@gumartinm.name>
Sun, 16 Dec 2012 00:43:44 +0000 (01:43 +0100)
committergumartinm <gustavo@gumartinm.name>
Sun, 16 Dec 2012 00:43:44 +0000 (01:43 +0100)
Using Android inter process communication.

Android/MobiAdsReloaded/gen/de/android/mobiads/R.java
Android/MobiAdsReloaded/res/values/strings.xml
Android/MobiAdsReloaded/src/de/android/mobiads/MobiAdsService.java
Android/MobiAdsReloaded/src/de/android/mobiads/MobiAdsSettings.java
Android/MobiAdsReloaded/src/de/android/mobiads/batch/MobiAdsBatch.java
Android/MobiAdsReloaded/src/de/android/mobiads/list/MobiAdsList.java

index 6a5ece9..7603546 100644 (file)
@@ -49,44 +49,42 @@ public final class R {
         public static final int alert_dialog_not_logged=0x7f060005;
         public static final int app_description=0x7f060003;
         public static final int app_name=0x7f060002;
-        public static final int button_cancel=0x7f060011;
-        public static final int button_localads=0x7f060012;
+        public static final int button_cancel=0x7f06000f;
+        public static final int button_localads=0x7f060010;
         public static final int button_login=0x7f06000a;
-        public static final int button_messagebind=0x7f06000b;
-        public static final int button_messagelistlocalads=0x7f06000f;
-        public static final int button_messagestartservice=0x7f06000e;
-        public static final int button_messagestopservice=0x7f06000d;
-        public static final int button_messageunbind=0x7f06000c;
-        public static final int button_ok=0x7f060010;
-        public static final int desc=0x7f060020;
-        public static final int encoded_web_service=0x7f06001f;
+        public static final int button_messagelistlocalads=0x7f06000d;
+        public static final int button_messagestartservice=0x7f06000c;
+        public static final int button_messagestopservice=0x7f06000b;
+        public static final int button_ok=0x7f06000e;
+        public static final int desc=0x7f06001e;
+        public static final int encoded_web_service=0x7f06001d;
         public static final int error_dialog_connection_error=0x7f060006;
-        public static final int error_dialog_no_local_ads=0x7f060024;
+        public static final int error_dialog_no_local_ads=0x7f060022;
         public static final int error_dialog_userpwd_error=0x7f060007;
         public static final int header_bar=0x7f060000;
-        public static final int menuads_login=0x7f060023;
-        public static final int menuads_remove=0x7f060021;
-        public static final int menuads_settings=0x7f060022;
-        public static final int meters_update_rate_preference_summary=0x7f060028;
-        public static final int meters_update_rate_preference_title=0x7f060027;
+        public static final int menuads_login=0x7f060021;
+        public static final int menuads_remove=0x7f06001f;
+        public static final int menuads_settings=0x7f060020;
+        public static final int meters_update_rate_preference_summary=0x7f060026;
+        public static final int meters_update_rate_preference_title=0x7f060025;
         public static final int new_ads=0x7f060001;
         public static final int password=0x7f060009;
-        public static final int remote_service_content_empty_notification=0x7f060016;
-        public static final int remote_service_content_notification=0x7f060015;
-        public static final int remote_service_new_ads=0x7f060013;
-        public static final int remote_service_received_ad_notification=0x7f060014;
-        public static final int remote_service_started_notification=0x7f060017;
-        public static final int remote_service_stopped_notification=0x7f060018;
-        public static final int remote_service_title_notification=0x7f060019;
-        public static final int service_preference_title=0x7f060025;
-        public static final int service_preference_title_summary=0x7f060026;
-        public static final int time_update_rate_preference_summary=0x7f06002a;
-        public static final int time_update_rate_preference_title=0x7f060029;
-        public static final int url_api_web_services=0x7f06001b;
-        public static final int url_images=0x7f06001c;
-        public static final int url_login_web_service=0x7f06001a;
-        public static final int url_web=0x7f06001d;
-        public static final int user_agent_web_service=0x7f06001e;
+        public static final int remote_service_content_empty_notification=0x7f060014;
+        public static final int remote_service_content_notification=0x7f060013;
+        public static final int remote_service_new_ads=0x7f060011;
+        public static final int remote_service_received_ad_notification=0x7f060012;
+        public static final int remote_service_started_notification=0x7f060015;
+        public static final int remote_service_stopped_notification=0x7f060016;
+        public static final int remote_service_title_notification=0x7f060017;
+        public static final int service_preference_title=0x7f060023;
+        public static final int service_preference_title_summary=0x7f060024;
+        public static final int time_update_rate_preference_summary=0x7f060028;
+        public static final int time_update_rate_preference_title=0x7f060027;
+        public static final int url_api_web_services=0x7f060019;
+        public static final int url_images=0x7f06001a;
+        public static final int url_login_web_service=0x7f060018;
+        public static final int url_web=0x7f06001b;
+        public static final int user_agent_web_service=0x7f06001c;
         public static final int username=0x7f060008;
     }
     public static final class xml {
index 050cfd3..eb33824 100644 (file)
@@ -11,8 +11,6 @@
     <string name="username">Username</string>
     <string name="password">Password</string>
     <string name="button_login">Log In</string>
-    <string name="button_messagebind">Bind Service</string>
-    <string name="button_messageunbind">Unbind Service</string>
     <string name="button_messagestopservice">Stop Application</string>
     <string name="button_messagestartservice">Start Application</string>
     <string name="button_messagelistlocalads">List Your Ads</string>
index 8553316..258d8a3 100644 (file)
@@ -1,7 +1,5 @@
 package de.android.mobiads;
 
-import java.util.ArrayList;
-
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -14,48 +12,38 @@ import android.location.Criteria;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
+import android.util.Log;
 import de.android.mobiads.batch.MobiAdsBatch;
 import de.android.mobiads.list.MobiAdsLatestList;
 
 public class MobiAdsService extends Service {
+    private static final String TAG = "MobiAdsService";
     private MobiAdsBatch mobiAdsBatch;
     /** For showing and hiding our notification. */
     NotificationManager notificationManager;
-    /**
-     * Command to the service to register a client, receiving callbacks
-     * from the service.  The Message's replyTo field must be a Messenger of
-     * the client where callbacks should be sent.
-     */
-    public static final int MSG_REGISTER_CLIENT = 1;
 
     /**
-     * Command to the service to unregister a client, ot stop receiving callbacks
-     * from the service.  The Message's replyTo field must be a Messenger of
-     * the client as previously given with MSG_REGISTER_CLIENT.
+     * Command to service to retrieve the current cookie value.  This can be sent to the
+     * service to retrieve the cookie value, and will be sent by the service to
+     * any registered clients with the current value used by the service in order
+     * to connect with the Web Service.
      */
-    public static final int MSG_UNREGISTER_CLIENT = 2;
+    public static final int MSG_GET_VALUE = 1;
 
     /**
-     * Command to service to set a new value.  This can be sent to the
-     * service to supply a new value, and will be sent by the service to
-     * any registered clients with the new value.
+     * Stores the current cookie value.
      */
-    public static final int MSG_SET_VALUE = 3;
+    private String cookie = "WTF";
 
     private LocationManager locationManager;
     private LocationListener locationListener;
 
-    private final ArrayList<Messenger> mClients = new ArrayList<Messenger>();
-    /** Holds last value set by a client. */
-    int mValue = 0;
-
     /**
      * Meters update rate value used by LocationManager
      * and the user may change it using the settings activity.
@@ -68,16 +56,6 @@ public class MobiAdsService extends Service {
      */
     private long timeUpdateRateValue = 0;
 
-    /**
-     * Class for clients to access.  Because we know this service always
-     * runs in the same process as its clients, we don't need to deal with
-     * IPC.
-     */
-    public class LocalBinder extends Binder {
-        MobiAdsService getService() {
-            return MobiAdsService.this;
-        }
-    }
 
     private final BroadcastReceiver receiver = new BroadcastReceiver() {
 
@@ -87,7 +65,7 @@ public class MobiAdsService extends Service {
             //This will be run in the main thread of this service. It might be interesting to use a Handler
             //for this receiver implementing its own thread. :/
             //TODO: If I do not want to have any trouble, to use a synchronize to access this code here and when
-            //receiving new ads. Besides you are using the same code xD. No time right now. I must improve my code
+            //receiving new ads in MobiAdsBatch class. Besides you are using the same code xD. No time right now. I must improve my code
             //but I am in a hurry.
             if(action.equals("de.android.mobiads.MOBIADSSERVICERECEIVER")){
                 updateNotification();
@@ -97,7 +75,7 @@ public class MobiAdsService extends Service {
 
     @Override
     public int onStartCommand(final Intent intent, final int flags, final int startId) {
-        final String cookie = intent.getStringExtra("cookie");
+        cookie = intent.getStringExtra("cookie");
         metersUpdateRateValue = Float.parseFloat(intent.getStringExtra("meters_update_rate_value"));
         timeUpdateRateValue = 60 * 1000 * Integer.parseInt(intent.getStringExtra("time_update_rate_value"));
 
@@ -136,6 +114,7 @@ public class MobiAdsService extends Service {
 
             @Override
             public void onStatusChanged(final String provider, final int status, final Bundle extras) {
+                //TODO:
                 //1. Find out the provider state. (see Copilot.java code GPSLocationListener)
                 //2. If it is TEMPORARILY_UNAVAILABLE:
                 //2.1. locationManager.removeUpdates(locationListener); <--- Stop wasting GPS or GSM connections
@@ -248,24 +227,15 @@ public class MobiAdsService extends Service {
         @Override
         public void handleMessage(final Message msg) {
             switch (msg.what) {
-                case MSG_REGISTER_CLIENT:
-                    mClients.add(msg.replyTo);
-                    break;
-                case MSG_UNREGISTER_CLIENT:
-                    mClients.remove(msg.replyTo);
-                    break;
-                case MSG_SET_VALUE:
-                    mValue = msg.arg1;
-                    for (int i=mClients.size()-1; i>=0; i--) {
-                        try {
-                            mClients.get(i).send(Message.obtain(null,
-                                    MSG_SET_VALUE, mValue, 0));
-                        } catch (final RemoteException e) {
-                            // The client is dead.  Remove it from the list;
-                            // we are going through the list from back to front
-                            // so this is safe to do inside the loop.
-                            mClients.remove(i);
-                        }
+                case MSG_GET_VALUE:
+                    try {
+                        final Bundle data = new Bundle();
+                        data.putString("cookie", MobiAdsService.this.cookie);
+                        final Message returnMessage = Message.obtain(null, MSG_GET_VALUE);
+                        returnMessage.setData(data);
+                        msg.replyTo.send(returnMessage);
+                    } catch (final RemoteException e) {
+                        Log.wtf(TAG, "Client is dead", e);
                     }
                     break;
                 default:
index 18bd3c9..37cf164 100644 (file)
@@ -5,22 +5,13 @@ import android.app.ActivityManager;
 import android.app.ActivityManager.RunningServiceInfo;
 import android.app.DialogFragment;
 import android.app.FragmentManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
-import android.widget.TextView;
-import android.widget.Toast;
 import de.android.mobiads.list.MobiAdsList;
 
 public class MobiAdsSettings extends Activity {
@@ -69,7 +60,6 @@ public class MobiAdsSettings extends Activity {
                             intent.putExtra("cookie", Cookie.getCookie());
                             intent.putExtra("meters_update_rate_value", metersUpdateRate.getValue());
                             intent.putExtra("time_update_rate_value", timeUpdateRate.getValue());
-                            //((MobiAdsSettings)getActivity()).doBindService();
                             getActivity().startService(intent);
                         }
                         else {
@@ -79,7 +69,6 @@ public class MobiAdsSettings extends Activity {
                         }
                     }
                     else {
-                        //((MobiAdsSettings)getActivity()).doUnbindService();
                         getActivity().stopService(new Intent(getActivity(), MobiAdsService.class));
                     }
                     return false;
@@ -97,125 +86,4 @@ public class MobiAdsSettings extends Activity {
             return false;
         }
     }
-
-
-
-
-
-
-
-
-    /** Messenger for communicating with service. */
-    Messenger mService = null;
-    /** Flag indicating whether we have called bind on the service. */
-    boolean mIsBound;
-    /** Some text view we are using to show state information. */
-    TextView mCallbackText;
-
-    /**
-     * Handler of incoming messages from service.
-     */
-    class IncomingHandler extends Handler {
-        @Override
-        public void handleMessage(final Message msg) {
-            switch (msg.what) {
-                case MobiAdsService.MSG_SET_VALUE:
-                    mCallbackText.setText("Received from service: " + msg.arg1);
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-    }
-
-    /**
-     * Target we publish for clients to send messages to IncomingHandler.
-     */
-    final Messenger mMessenger = new Messenger(new IncomingHandler());
-
-    /**
-     * Class for interacting with the main interface of the service.
-     */
-    private final ServiceConnection mConnection = new ServiceConnection() {
-
-        @Override
-        public void onServiceConnected(final ComponentName className,
-                final IBinder service) {
-            // This is called when the connection with the service has been
-            // established, giving us the service object we can use to
-            // interact with the service.  We are communicating with our
-            // service through an IDL interface, so get a client-side
-            // representation of that from the raw service object.
-            mService = new Messenger(service);
-            mCallbackText.setText("Attached.");
-
-            // We want to monitor the service for as long as we are
-            // connected to it.
-            try {
-                Message msg = Message.obtain(null,
-                        MobiAdsService.MSG_REGISTER_CLIENT);
-                msg.replyTo = mMessenger;
-                mService.send(msg);
-
-                // Give it some value as an example.
-                msg = Message.obtain(null,
-                        MobiAdsService.MSG_SET_VALUE, this.hashCode(), 0);
-                mService.send(msg);
-            } catch (final RemoteException e) {
-                // In this case the service has crashed before we could even
-                // do anything with it; we can count on soon being
-                // disconnected (and then reconnected if it can be restarted)
-                // so there is no need to do anything here.
-            }
-
-            // As part of the sample, tell the user what happened.
-            Toast.makeText(MobiAdsSettings.this, R.string.button_messagebind,
-                    Toast.LENGTH_SHORT).show();
-        }
-
-        @Override
-        public void onServiceDisconnected(final ComponentName className) {
-            // This is called when the connection with the service has been
-            // unexpectedly disconnected -- that is, its process crashed.
-            mService = null;
-            mCallbackText.setText("Disconnected.");
-
-            // As part of the sample, tell the user what happened.
-            Toast.makeText(MobiAdsSettings.this, R.string.button_messageunbind,
-                    Toast.LENGTH_SHORT).show();
-        }
-    };
-
-    private void doBindService() {
-        // Establish a connection with the service.  We use an explicit
-        // class name because there is no reason to be able to let other
-        // applications replace our component.
-        bindService(new Intent(this,
-                MobiAdsService.class), mConnection, Context.BIND_AUTO_CREATE);
-        mIsBound = true;
-        mCallbackText.setText("Binding.");
-    }
-
-    private void doUnbindService() {
-        if (mIsBound) {
-            // If we have received the service, and hence registered with
-            // it, then now is the time to unregister.
-            if (mService != null) {
-                try {
-                    final Message msg = Message.obtain(null,
-                            MobiAdsService.MSG_UNREGISTER_CLIENT);
-                    msg.replyTo = mMessenger;
-                    mService.send(msg);
-                } catch (final RemoteException e) {
-                    // There is nothing special we need to do if the service
-                    // has crashed.
-                }
-            }
-
-            // Detach our existing connection.
-            unbindService(mConnection);
-            mIsBound = false;
-            mCallbackText.setText("Unbinding.");
-        }
-    }
 }
index aeb8a75..18413df 100644 (file)
@@ -45,7 +45,6 @@ public class MobiAdsBatch {
     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) {
index 18ae170..46536aa 100644 (file)
@@ -6,8 +6,11 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+
 import android.app.ActionBar;
 import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.DialogFragment;
@@ -23,11 +26,17 @@ import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.Loader;
+import android.content.ServiceConnection;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseBooleanArray;
@@ -41,492 +50,580 @@ import android.widget.ListView;
 import android.widget.SearchView;
 import android.widget.SearchView.OnQueryTextListener;
 import de.android.mobiads.Cookie;
+import de.android.mobiads.MobiAdsService;
 import de.android.mobiads.R;
 import de.android.mobiads.provider.Indexer;
 
 public class MobiAdsList extends Activity {
-       private BroadcastReceiver mReceiver;
-       
-       
-       @Override
-    protected void onCreate(Bundle savedInstanceState) {
+    private static final String TAG = "MobiAdsList";
+    private BroadcastReceiver mReceiver;
+
+    /**
+     * Target we publish for clients to send messages to IncomingHandler.
+     */
+    private final Messenger mMessenger = new Messenger(new IncomingHandler());
+
+    @Override
+    protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
         final ActionBar actionBar = getActionBar();
         final MobiAdsListFragment list = new MobiAdsListFragment();
-        
+
         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
         actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE, ActionBar.DISPLAY_SHOW_TITLE);
         actionBar.setTitle(getResources().getString(R.string.header_bar));
-        //actionBar.setDisplayHomeAsUpEnabled(true);
 
-        
-        
-        FragmentManager fm = getFragmentManager();
+        if (isMyServiceRunning()) {
+            this.doBindService();
+        }
+
+
+
+        final FragmentManager fm = getFragmentManager();
 
         // Create the list fragment and add it as our sole content.
         if (fm.findFragmentById(android.R.id.content) == null) {
             fm.beginTransaction().add(android.R.id.content, list).commit();
         }
-        
-        
+
+
         mReceiver = new BroadcastReceiver() {
-               
-               @Override
-               public void onReceive(Context context, Intent intent) {
-                       String action = intent.getAction();
-                       //This will be run in the main thread of this service. It might be interesting to use a Handler
-                       //for this receiver implementing its own thread. :/
-                       if(action.equals("de.android.mobiads.MOBIADSLISTRECEIVER")){
-                               getLoaderManager().restartLoader(0, null, list);
-                       }
-               }
-       };
-       
-       IntentFilter filter = new IntentFilter();
+
+            @Override
+            public void onReceive(final Context context, final Intent intent) {
+                final String action = intent.getAction();
+                //This will be run in the main thread of this service. It might be interesting to use a Handler
+                //for this receiver implementing its own thread. :/
+                if(action.equals("de.android.mobiads.MOBIADSLISTRECEIVER")){
+                    getLoaderManager().restartLoader(0, null, list);
+                }
+            }
+        };
+
+        final IntentFilter filter = new IntentFilter();
         filter.addAction("de.android.mobiads.MOBIADSLISTRECEIVER");
         registerReceiver(mReceiver, filter);
-        
+
     }
 
-       @Override
-       protected void onDestroy() {
-         unregisterReceiver(mReceiver);
-         super.onDestroy();
-       }
-       
-       @Override
-       public boolean onOptionsItemSelected(MenuItem item) {
-               super.onOptionsItemSelected(item);
-               Intent intent = null;
+    @Override
+    protected void onDestroy() {
+        unregisterReceiver(mReceiver);
+        super.onDestroy();
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(final MenuItem item) {
+        super.onOptionsItemSelected(item);
+        Intent intent = null;
         switch (item.getItemId()) {
             case R.id.menuads_settings:
-               intent = new Intent("android.intent.action.MOBIADS").
-                                                               setComponent(new ComponentName("de.android.mobiads", "de.android.mobiads.MobiAdsSettings"));
-               this.startActivity(intent);
+                intent = new Intent("android.intent.action.MOBIADS").
+                setComponent(new ComponentName("de.android.mobiads", "de.android.mobiads.MobiAdsSettings"));
+                this.startActivity(intent);
                 return true;
             case R.id.menuads_login:
-               if (Cookie.getCookie() != null) {
-                               createAlertDialog(R.string.alert_dialog_logged);
-                       }
-                       else {
-                               intent = new Intent("android.intent.action.MOBIADS").
-                               setComponent(new ComponentName("de.android.mobiads", "de.android.mobiads.MobiAdsLoginActivity"));
-                               this.startActivity(intent);
-                       }
-               return true;
+                if (Cookie.getCookie() != null) {
+                    createAlertDialog(R.string.alert_dialog_logged);
+                }
+                else {
+                    intent = new Intent("android.intent.action.MOBIADS").
+                            setComponent(new ComponentName("de.android.mobiads", "de.android.mobiads.MobiAdsLoginActivity"));
+                    this.startActivity(intent);
+                }
+                return true;
             default:
                 return false;
         }
-       }
-       
-       @Override
-       public boolean onPrepareOptionsMenu(Menu menu) {        
-               return super.onPrepareOptionsMenu(menu);
-       }
-       
-       @Override
-       public boolean onCreateOptionsMenu(Menu menu) {
-               super.onCreateOptionsMenu(menu);
-           MenuInflater inflater = getMenuInflater();
-           inflater.inflate(R.menu.menuads, menu);
-           
-           return true;
-       }
-       
-       public void onOptionsMenuClosed(Menu menu) {
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(final Menu menu) {
+        return super.onPrepareOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(final Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        final MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.menuads, menu);
+
+        return true;
+    }
+
+    @Override
+    public void onOptionsMenuClosed(final Menu menu) {
         super.onOptionsMenuClosed(menu);
     }
 
-       
-       /**
-        * A custom Loader that loads all of the installed applications.
-        */
-       public static class AdsListLoader extends AsyncTaskLoader<List<AdsEntry>> {
-               private static final String TAG = "AdsListLoader";
-               List<AdsEntry> mApps;
-
-               public AdsListLoader(Context context) {
-                       super(context);
-               }
-
-               /**
-                * This is where the bulk of our work is done.  This function is
-                * called in a background thread and should generate a new set of
-                * data to be published by the loader.
-                */
-               @Override 
-               public List<AdsEntry> loadInBackground() {
-                       // Create corresponding array of entries and load their labels.
-                       List<AdsEntry> entries = getAdsEntries();
-
-                       return entries;
-               }
-
-               private List<AdsEntry> getAdsEntries() {
-                       final List<AdsEntry> entries = new ArrayList<AdsEntry>();
-                       final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer");
-                       final ContentValues values = new ContentValues();
-       
-                       Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);
-                       try {
-                               if (cursor.moveToFirst()) {
-                                       do {
-                                               values.clear();
-                                               Bitmap bitMap = null;
-                                               FileInputStream file = null;
-                                               try {
-                                                       file = getContext().openFileInput(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_PATH)));
-                                                       bitMap = BitmapFactory.decodeStream(file);
-                                               } catch (FileNotFoundException e) {
-                                                       //Giving more chances to other ads
-                                                       continue;
-                                               } catch (IllegalArgumentException e) {
-                                                       //Giving more chances to other ads
-                                                       continue;
-                                               }
-                                               finally {
-                                                       if (file != null) {
-                                                               try {
-                                                                       file.close();
-                                                               } catch (IOException e) {
-                                                                       Log.w(TAG, "Error while closing image file.");
-                                                               }
-                                                       }
-                                               }
-                                               
-                                               boolean readStatus;
-                                               if ( cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_IS_READ)) == 0) {
-                                                       readStatus = false;
-                                               }
-                                               else {
-                                                       readStatus = true;
-                                               }
-                                                       
-                                               entries.add(new AdsEntry(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_AD_NAME)), 
-                                                               cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_TEXT)), bitMap,
-                                                               cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_ID_AD)),
-                                                               cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_URL)),
-                                                               readStatus));
-                                       }while (cursor.moveToNext());
-                               } 
-                       }finally {
-                               cursor.close();
-                       }
-
-                       return entries;
-               }
-
-               /**
-                * Called when there is new data to deliver to the client.  The
-                * super class will take care of delivering it; the implementation
-                * here just adds a little more logic.
-                */
-               @Override 
-               public void deliverResult(List<AdsEntry> apps) {
-                       mApps = apps;
-
-                       if (isStarted()) {
-                               // If the Loader is currently started, we can immediately
-                               // deliver its results.
-                               super.deliverResult(apps);
-                       }
-               }
-
-               /**
-                * Handles a request to start the Loader.
-                */
-               @Override 
-               protected void onStartLoading() {
-                       if (mApps != null) {
-                               // If we currently have a result available, deliver it
-                               // immediately.
-                               deliverResult(mApps);
-                       }
-
-                       if (takeContentChanged() || mApps == null) {
-                               // If the data has changed since the last time it was loaded
-                               // or is not currently available, start a load.
-                               forceLoad();
-                       }
-               }
-
-               /**
-                * Handles a request to cancel a load.
-                */
-               @Override 
-               public void onCanceled(List<AdsEntry> apps) {
-                       super.onCanceled(apps);
-
-                       // At this point we can release the resources associated with 'apps'
-                       // if needed.
-               }
-
-               /**
-                * Handles a request to completely reset the Loader.
-                */
-               @Override 
-               protected void onReset() {
-                       super.onReset();
-
-                       // Ensure the loader is stopped
-                       onStopLoading();
-
-                       // At this point we can release the resources associated with 'apps'
-                       // if needed.
-                       if (mApps != null) {
-                               mApps = null;
-                       }
-               }
-       }
-
-       public static class MobiAdsListFragment extends ListFragment implements OnQueryTextListener, 
-                                                                                                                       LoaderManager.LoaderCallbacks<List<AdsEntry>> {
-               AdsEntryAdapter mAdapter;
-               // If non-null, this is the current filter the user has provided.
-               String mCurFilter;
-               
-               
-                @Override 
-                public void onActivityCreated(Bundle savedInstanceState) {
-                        super.onActivityCreated(savedInstanceState);
-                        
-                        ListView listView = getListView();
-                               
-                               listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
-                               
-                               
-                               listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
-
-                                   @Override
-                                   public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
-                                       final int checkedCount = getListView().getCheckedItemCount();
-                                       switch (checkedCount) {
-                               case 0:
-                                   mode.setSubtitle(null);
-                                   break;
-                               case 1:
-                                   mode.setSubtitle("One item selected");
-                                   break;
-                               default:
-                                   mode.setSubtitle("" + checkedCount + " items selected");
-                                   break;
-                                       }
-                                   }
-
-                                   @Override
-                                   public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-                                       // Respond to clicks on the actions in the CAB
-                                       switch (item.getItemId()) {
-                                           case R.id.selectedmenu_remove:
-                                               SparseBooleanArray itemsPositions = getListView().getCheckedItemPositions();
-                                               Collection<AdsEntry> aux = new ArrayList<AdsEntry>(mAdapter.getCount());
-                                               for (int i=0; i< itemsPositions.size(); i++) {
-                                                       if (itemsPositions.valueAt(i)) {
-                                                               aux.add(mAdapter.getItem(itemsPositions.keyAt(i)));
-                                                       }
-                                               }
-                                               if (!aux.isEmpty()) {
-                                                       for(final AdsEntry entry : aux) {
-                                                               removeAd(entry);
-                                                       }
-                                               }
-                                               mode.finish(); // Action picked, so close the CAB
-                                               return true;
-                                           default:
-                                               return false;
-                                       }
-                                   }
-
-                                   /**
-                                    * When selecting an item we remove the current action bar menu and we populate it with this one.
-                                    */
-                                   @Override
-                                   public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-                                       MenuInflater inflater = mode.getMenuInflater();
-                                       inflater.inflate(R.menu.selectedmenuads, menu);
-                                       final int checkedCount = getListView().getCheckedItemCount();
-                                       switch (checkedCount) {
-                               case 0:
-                                   mode.setSubtitle(null);
-                                   break;
-                               case 1:
-                                   mode.setSubtitle("One item selected");
-                                   break;
-                               default:
-                                   mode.setSubtitle("" + checkedCount + " items selected");
-                                   break;
-                                       }
-                                       return true;
-                                   }
-
-                                   @Override
-                                   public void onDestroyActionMode(ActionMode mode) {
-                                       //Nothing to do here.
-                                   }
-
-                                   @Override
-                                   public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-                                       // Here you can perform updates to the CAB due to
-                                       // an invalidate() request
-                                       return false;
-                                   }
-                               });
-                               
-                               setEmptyText("No downloaded Ads.");
-
-                               // We have a menu item to show in action bar.
-                               setHasOptionsMenu(true);      
-
-
-                               mAdapter = new AdsEntryAdapter(getActivity(), R.layout.ads_entry_list_item);
-
-                               setListAdapter(mAdapter);
-                               // Start out with a progress indicator.
-                               setListShown(false);
-                               
-                               getLoaderManager().initLoader(0, null, this);
-                               
-                }
-               
-               @Override 
-               public void onListItemClick(ListView l, View v, int position, long id) {
-                       final AdsEntry entry = mAdapter.getItem(position);
-                       
-                       if (!entry.isRead()) {
-                               setIsReadEntry(entry);
-                       }
-                       
-                       //Change notification (if there is one)
-                       Intent updateDatabase = new Intent("de.android.mobiads.MOBIADSSERVICERECEIVER");
-                       getActivity().sendBroadcast(updateDatabase);            
-                       
-                       //This will update our view showing a nice black background for this item in our list :/
-                       mAdapter.notifyDataSetChanged();
-                       
-                       //Going to open the web navigator whatever it is... 
-                       Uri uri = Uri.parse(entry.getURL());
-                       startActivity(new Intent(Intent.ACTION_VIEW, uri));             
+
+    /**
+     * A custom Loader that loads all of the installed applications.
+     */
+    public static class AdsListLoader extends AsyncTaskLoader<List<AdsEntry>> {
+        private static final String TAG = "AdsListLoader";
+        List<AdsEntry> mApps;
+
+        public AdsListLoader(final Context context) {
+            super(context);
+        }
+
+        /**
+         * This is where the bulk of our work is done.  This function is
+         * called in a background thread and should generate a new set of
+         * data to be published by the loader.
+         */
+        @Override
+        public List<AdsEntry> loadInBackground() {
+            // Create corresponding array of entries and load their labels.
+            final List<AdsEntry> entries = getAdsEntries();
+
+            return entries;
+        }
+
+        private List<AdsEntry> getAdsEntries() {
+            final List<AdsEntry> entries = new ArrayList<AdsEntry>();
+            final Uri uri = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer");
+            final ContentValues values = new ContentValues();
+
+            final Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);
+            try {
+                if (cursor.moveToFirst()) {
+                    do {
+                        values.clear();
+                        Bitmap bitMap = null;
+                        FileInputStream file = null;
+                        try {
+                            file = getContext().openFileInput(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_PATH)));
+                            bitMap = BitmapFactory.decodeStream(file);
+                        } catch (final FileNotFoundException e) {
+                            //Giving more chances to other ads
+                            continue;
+                        } catch (final IllegalArgumentException e) {
+                            //Giving more chances to other ads
+                            continue;
+                        }
+                        finally {
+                            if (file != null) {
+                                try {
+                                    file.close();
+                                } catch (final IOException e) {
+                                    Log.w(TAG, "Error while closing image file.");
+                                }
+                            }
+                        }
+
+                        boolean readStatus;
+                        if ( cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_IS_READ)) == 0) {
+                            readStatus = false;
+                        }
+                        else {
+                            readStatus = true;
+                        }
+
+                        entries.add(new AdsEntry(cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_AD_NAME)),
+                                cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_TEXT)), bitMap,
+                                cursor.getInt(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_ID_AD)),
+                                cursor.getString(cursor.getColumnIndexOrThrow(Indexer.Index.COLUMN_NAME_URL)),
+                                readStatus));
+                    }while (cursor.moveToNext());
+                }
+            }finally {
+                cursor.close();
+            }
+
+            return entries;
+        }
+
+        /**
+         * Called when there is new data to deliver to the client.  The
+         * super class will take care of delivering it; the implementation
+         * here just adds a little more logic.
+         */
+        @Override
+        public void deliverResult(final List<AdsEntry> apps) {
+            mApps = apps;
+
+            if (isStarted()) {
+                // If the Loader is currently started, we can immediately
+                // deliver its results.
+                super.deliverResult(apps);
+            }
+        }
+
+        /**
+         * Handles a request to start the Loader.
+         */
+        @Override
+        protected void onStartLoading() {
+            if (mApps != null) {
+                // If we currently have a result available, deliver it
+                // immediately.
+                deliverResult(mApps);
+            }
+
+            if (takeContentChanged() || mApps == null) {
+                // If the data has changed since the last time it was loaded
+                // or is not currently available, start a load.
+                forceLoad();
+            }
+        }
+
+        /**
+         * Handles a request to cancel a load.
+         */
+        @Override
+        public void onCanceled(final List<AdsEntry> apps) {
+            super.onCanceled(apps);
+
+            // At this point we can release the resources associated with 'apps'
+            // if needed.
+        }
+
+        /**
+         * Handles a request to completely reset the Loader.
+         */
+        @Override
+        protected void onReset() {
+            super.onReset();
+
+            // Ensure the loader is stopped
+            onStopLoading();
+
+            // At this point we can release the resources associated with 'apps'
+            // if needed.
+            if (mApps != null) {
+                mApps = null;
+            }
+        }
+    }
+
+    public static class MobiAdsListFragment extends ListFragment implements OnQueryTextListener,
+    LoaderManager.LoaderCallbacks<List<AdsEntry>> {
+        AdsEntryAdapter mAdapter;
+        // If non-null, this is the current filter the user has provided.
+        String mCurFilter;
+
+
+        @Override
+        public void onActivityCreated(final Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            final ListView listView = getListView();
+
+            listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+
+
+            listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
+
+                @Override
+                public void onItemCheckedStateChanged(final ActionMode mode, final int position, final long id, final boolean checked) {
+                    final int checkedCount = getListView().getCheckedItemCount();
+                    switch (checkedCount) {
+                        case 0:
+                            mode.setSubtitle(null);
+                            break;
+                        case 1:
+                            mode.setSubtitle("One item selected");
+                            break;
+                        default:
+                            mode.setSubtitle("" + checkedCount + " items selected");
+                            break;
+                    }
+                }
+
+                @Override
+                public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
+                    // Respond to clicks on the actions in the CAB
+                    switch (item.getItemId()) {
+                        case R.id.selectedmenu_remove:
+                            final SparseBooleanArray itemsPositions = getListView().getCheckedItemPositions();
+                            final Collection<AdsEntry> aux = new ArrayList<AdsEntry>(mAdapter.getCount());
+                            for (int i=0; i< itemsPositions.size(); i++) {
+                                if (itemsPositions.valueAt(i)) {
+                                    aux.add(mAdapter.getItem(itemsPositions.keyAt(i)));
+                                }
+                            }
+                            if (!aux.isEmpty()) {
+                                for(final AdsEntry entry : aux) {
+                                    removeAd(entry);
+                                }
+                            }
+                            mode.finish(); // Action picked, so close the CAB
+                            return true;
+                        default:
+                            return false;
+                    }
+                }
+
+                /**
+                 * When selecting an item we remove the current action bar menu and we populate it with this one.
+                 */
+                @Override
+                public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
+                    final MenuInflater inflater = mode.getMenuInflater();
+                    inflater.inflate(R.menu.selectedmenuads, menu);
+                    final int checkedCount = getListView().getCheckedItemCount();
+                    switch (checkedCount) {
+                        case 0:
+                            mode.setSubtitle(null);
+                            break;
+                        case 1:
+                            mode.setSubtitle("One item selected");
+                            break;
+                        default:
+                            mode.setSubtitle("" + checkedCount + " items selected");
+                            break;
+                    }
+                    return true;
+                }
+
+                @Override
+                public void onDestroyActionMode(final ActionMode mode) {
+                    //Nothing to do here.
+                }
+
+                @Override
+                public boolean onPrepareActionMode(final ActionMode mode, final Menu menu) {
+                    // Here you can perform updates to the CAB due to
+                    // an invalidate() request
+                    return false;
+                }
+            });
+
+            setEmptyText("No downloaded Ads.");
+
+            // We have a menu item to show in action bar.
+            setHasOptionsMenu(true);
+
+
+            mAdapter = new AdsEntryAdapter(getActivity(), R.layout.ads_entry_list_item);
+
+            setListAdapter(mAdapter);
+            // Start out with a progress indicator.
+            setListShown(false);
+
+            getLoaderManager().initLoader(0, null, this);
+
+        }
+
+        @Override
+        public void onListItemClick(final ListView l, final View v, final int position, final long id) {
+            final AdsEntry entry = mAdapter.getItem(position);
+
+            if (!entry.isRead()) {
+                setIsReadEntry(entry);
+            }
+
+            //Change notification (if there is one)
+            final Intent updateDatabase = new Intent("de.android.mobiads.MOBIADSSERVICERECEIVER");
+            getActivity().sendBroadcast(updateDatabase);
+
+            //This will update our view showing a nice black background for this item in our list :/
+            mAdapter.notifyDataSetChanged();
+
+            //Going to open the web navigator whatever it is...
+            final Uri uri = Uri.parse(entry.getURL());
+            startActivity(new Intent(Intent.ACTION_VIEW, uri));
+        }
+
+        private void setIsReadEntry(final AdsEntry entry) {
+            final Uri uriUpdate = Uri.parse("content://" + "de.android.mobiads.provider" +
+                    "/" + "indexer/idad/" + entry.getIdAd());
+            final ContentValues values = new ContentValues();
+
+            values.put(Indexer.Index.COLUMN_NAME_IS_READ, Integer.valueOf(1));
+
+            getActivity().getContentResolver().update(uriUpdate, values, null, null);
+
+            entry.setIsRead(true);
+        }
+
+        private void removeAd(final AdsEntry entry) {
+            final int idAd = entry.getIdAd();
+            final Uri uriDelete = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + idAd);
+
+            getActivity().getContentResolver().delete(uriDelete, null, null);
+            mAdapter.remove(entry);
+
+            //Change notification (if there is one)
+            final Intent updateDatabase = new Intent("de.android.mobiads.MOBIADSSERVICERECEIVER");
+            getActivity().sendBroadcast(updateDatabase);
+
+            mAdapter.notifyDataSetChanged();
+        }
+
+        /**
+         * When setHasOptionsMenu(true) we populate the action bar with this menu. It is merged to the
+         * current action bar menu (if there is no one)
+         */
+        @Override
+        public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+            // Place an action bar item for searching.
+            final MenuItem item = menu.add("Search");
+
+            item.setIcon(android.R.drawable.ic_menu_search);
+            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+            final SearchView sv = new SearchView(getActivity());
+            sv.setOnQueryTextListener(this);
+            item.setActionView(sv);
+        }
+
+        @Override
+        public Loader<List<AdsEntry>> onCreateLoader(final int id, final Bundle args) {
+            // This is called when a new Loader needs to be created.  This
+            // sample only has one Loader with no arguments, so it is simple.
+            return new AdsListLoader(getActivity());
+        }
+
+        @Override
+        public void onLoadFinished(final Loader<List<AdsEntry>> loader, final List<AdsEntry> data) {
+            mAdapter.setData(data);
+
+            // The list should now be shown.
+            if (isResumed()) {
+                setListShown(true);
+            } else {
+                setListShownNoAnimation(true);
+            }
+        }
+
+        @Override
+        public void onLoaderReset(final Loader<List<AdsEntry>> loader) {
+            mAdapter.setData(null);
         }
-               
-               private void setIsReadEntry(final AdsEntry entry) {
-               final Uri uriUpdate = Uri.parse("content://" + "de.android.mobiads.provider" + 
-                                                                                                                       "/" + "indexer/idad/" + entry.getIdAd());
-                       final ContentValues values = new ContentValues();
-                       
-                       values.put(Indexer.Index.COLUMN_NAME_IS_READ, new Integer(1));
-
-                       getActivity().getContentResolver().update(uriUpdate, values, null, null);
-                       
-                       entry.setIsRead(true);
-               }
-               
-               private void removeAd(final AdsEntry entry) {
-               int idAd = entry.getIdAd();
-               final Uri uriDelete = Uri.parse("content://" + "de.android.mobiads.provider" + "/" + "indexer" + "/idad/" + idAd);
-               
-               getActivity().getContentResolver().delete(uriDelete, null, null);
-               mAdapter.remove(entry);
-               
-               //Change notification (if there is one)
-                       Intent updateDatabase = new Intent("de.android.mobiads.MOBIADSSERVICERECEIVER");
-                       getActivity().sendBroadcast(updateDatabase);
-                       
-               mAdapter.notifyDataSetChanged();
-           }
-               
-               /**
-                * When setHasOptionsMenu(true) we populate the action bar with this menu. It is merged to the
-                * current action bar menu (if there is no one)
-                */
-               @Override 
-               public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-                       // Place an action bar item for searching.
-                       final MenuItem item = menu.add("Search");
-                       
-                       item.setIcon(android.R.drawable.ic_menu_search);
-                       item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
-                       SearchView sv = new SearchView(getActivity());
-                       sv.setOnQueryTextListener(this);
-                       item.setActionView(sv);
-               }
-
-               @Override
-               public Loader<List<AdsEntry>> onCreateLoader(int id, Bundle args) {
-                       // This is called when a new Loader needs to be created.  This
-                       // sample only has one Loader with no arguments, so it is simple.
-                       return new AdsListLoader(getActivity());
-               }
-
-               @Override
-               public void onLoadFinished(Loader<List<AdsEntry>> loader, List<AdsEntry> data) {
-                       mAdapter.setData(data);
-
-                       // The list should now be shown.
-                       if (isResumed()) {
-                               setListShown(true);
-                       } else {
-                               setListShownNoAnimation(true);
-                       }
-               }
-
-               @Override
-               public void onLoaderReset(final Loader<List<AdsEntry>> loader) {
-                       mAdapter.setData(null);
-               }
-
-               @Override
-               public boolean onQueryTextSubmit(final String query) {
-                       // Don't care about this.
-                       return true;
-               }
-
-               @Override
-               public boolean onQueryTextChange(final String newText) {
-                       // Called when the action bar search text has changed.  Update
-                       // the search filter, and restart the loader to do a new query
-                       // with this filter.
-                       mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
-                       getLoaderManager().restartLoader(0, null, this);
-                       return true;
-               }
-       }
-       
-       private void createAlertDialog(int title) {
+
+        @Override
+        public boolean onQueryTextSubmit(final String query) {
+            // Don't care about this.
+            return true;
+        }
+
+        @Override
+        public boolean onQueryTextChange(final String newText) {
+            // Called when the action bar search text has changed.  Update
+            // the search filter, and restart the loader to do a new query
+            // with this filter.
+            mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+            getLoaderManager().restartLoader(0, null, this);
+            return true;
+        }
+    }
+
+    private void createAlertDialog(final int title) {
         final DialogFragment newFragment = AlertDialogFragment.newInstance(title);
-        
+
         newFragment.show(getFragmentManager(), "alertDialog");
     }
-       
-       //Create a helper for this or at least write its own file.
-       public static class AlertDialogFragment extends DialogFragment {
-       
-       public static AlertDialogFragment newInstance(int title) {
-               final AlertDialogFragment frag = new AlertDialogFragment();
-               
-               Bundle args = new Bundle();
-               
-               args.putInt("title", title);
-               frag.setArguments(args);
-            
-               return frag;
-               }
-
-               @Override
-               public Dialog onCreateDialog(Bundle savedInstanceState) {
-                       int title = getArguments().getInt("title");
-
-                       return new AlertDialog.Builder(getActivity())
-                                               .setIcon(android.R.drawable.ic_dialog_alert)
-                                               .setTitle(title)
-                                               .setPositiveButton(R.string.button_ok,
-                                                               new DialogInterface.OnClickListener() {
-                                                                       public void onClick(DialogInterface dialog, int whichButton) {
-                                                                               
-                                                                       }
-                                                               }
-                                               )
-                                               .create();
-           }
-   }
+
+    //Create a helper for this or at least write its own file.
+    public static class AlertDialogFragment extends DialogFragment {
+
+        public static AlertDialogFragment newInstance(final int title) {
+            final AlertDialogFragment frag = new AlertDialogFragment();
+
+            final Bundle args = new Bundle();
+
+            args.putInt("title", title);
+            frag.setArguments(args);
+
+            return frag;
+        }
+
+        @Override
+        public Dialog onCreateDialog(final Bundle savedInstanceState) {
+            final int title = getArguments().getInt("title");
+
+            return new AlertDialog.Builder(getActivity())
+            .setIcon(android.R.drawable.ic_dialog_alert)
+            .setTitle(title)
+            .setPositiveButton(R.string.button_ok,
+                    new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(final DialogInterface dialog, final int whichButton) {
+
+                }
+            }
+                    )
+                    .create();
+        }
+    }
+
+    private boolean isMyServiceRunning() {
+        final ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+        for (final RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
+            if (MobiAdsService.class.getName().equals(service.service.getClassName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Handler of incoming messages from service.
+     */
+    class IncomingHandler extends Handler {
+        //TODO: If the answer from the service takes too long (and the user is fast enough),
+        //this activity is going to think there is not cookie. Is there any solution for this issue?
+        @Override
+        public void handleMessage(final Message msg) {
+            //Running in the main thread of this activity.
+            switch (msg.what) {
+                case MobiAdsService.MSG_GET_VALUE:
+                    Cookie.setCookie(msg.getData().getString("cookie"));
+                    MobiAdsList.this.doUnbindService();
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    }
+
+    /**
+     * Class for interacting with the main interface of the service.
+     */
+    private final ServiceConnection mConnection = new ServiceConnection() {
+        /** Messenger for communicating with service. */
+        Messenger mService = null;
+
+        @Override
+        public void onServiceConnected(final ComponentName className,
+                final IBinder service) {
+            // This is called when the connection with the service has been
+            // established, giving us the service object we can use to
+            // interact with the service.  We are communicating with our
+            // service through an IDL interface, so get a client-side
+            // representation of that from the raw service object.
+            mService = new Messenger(service);
+
+            try {
+                final Message msg = Message.obtain(null, MobiAdsService.MSG_GET_VALUE);
+                msg.replyTo = mMessenger;
+                mService.send(msg);
+            } catch (final RemoteException e) {
+                Log.w(TAG, "Unexpected service crash", e);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(final ComponentName className) {
+            // This is called when the connection with the service has been
+            // unexpectedly disconnected -- that is, its process crashed.
+        }
+    };
+
+    private void doBindService() {
+        // Establish a connection with the service.  We use an explicit
+        // class name because there is no reason to be able to let other
+        // applications replace our component.
+        bindService(new Intent(this,
+                MobiAdsService.class), mConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    private void doUnbindService() {
+        // Hence registered with the service now is the time to unregister.
+        // Detach our existing connection.
+        unbindService(mConnection);
+    }
 }