Implementing an Android Provider.
authorgumartinm <gu.martinm@gmail.com>
Tue, 7 Feb 2012 07:07:09 +0000 (08:07 +0100)
committergumartinm <gu.martinm@gmail.com>
Tue, 7 Feb 2012 07:07:09 +0000 (08:07 +0100)
I would like to have more time to spend working
on this...

Android/Testing/Test3/AndroidManifest.xml
Android/Testing/Test3/src/de/android/test3/IndexerOpenHelper.java
Android/Testing/Test3/src/de/android/test3/IndexerProvider.java
Android/Testing/Test3/src/de/android/test3/MobieAdHttpClient.java

index 311d2f6..50a95f4 100644 (file)
                android:readPermission="android.permission.READ_MOBIADS"
                android:syncable="false"
                android:writePermission="android.permission.WRITE_MOBIADS" >
-            <grant-uri-permission 
-                android:path="string"
-                android:pathPattern="string"
-                android:pathPrefix="string" />
+            <grant-uri-permission android:pathPattern=".*" />
                </provider>
                <!--
                <provider 
index 4b6269a..e62eb23 100644 (file)
@@ -3,8 +3,12 @@ package de.android.test3;
 import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
 
 public class IndexerOpenHelper extends SQLiteOpenHelper {
+       // Used for debugging and logging
+    private static final String TAG = "IndexerOpenHelper";
+       
        private static final String DBNAME = "mobiads";
        private static final int DATABASE_VERSION = 1;
     private static final String TABLE_NAME = "indexer";
@@ -19,18 +23,34 @@ public class IndexerOpenHelper extends SQLiteOpenHelper {
     }
 
 
-    /*
-     * Creates the data repository. This is called when the provider attempts to open the
-     * repository and SQLite reports that it doesn't exist.
+    /**
+     *
+     * Creates the underlying database with table name and column names taken from the
+     * NotePad class.
      */
-       @Override
+    @Override
        public void onCreate(SQLiteDatabase db) {
                db.execSQL(TABLE_CREATE);
        }
 
-       
+
+    /**
+     *
+     * Demonstrates that the provider must consider what happens when the
+     * underlying datastore is changed. In this sample, the database is upgraded the database
+     * by destroying the existing data.
+     * A real application should upgrade the database in place.
+     */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+               // Logs that the database is being upgraded
+        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                + newVersion + ", which will destroy all old data");
+
+        // Kills the table and existing data
+        db.execSQL("DROP TABLE IF EXISTS indexer");
 
+        // Recreates the database with a new version
+        onCreate(db);
        }
 }
index a1142e2..52b1a74 100644 (file)
@@ -5,6 +5,7 @@ package de.android.test3;
 
 import android.content.ContentProvider;
 import android.content.ContentValues;
+import android.content.UriMatcher;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.net.Uri;
@@ -13,21 +14,108 @@ import android.net.Uri;
  *
  */
 public class IndexerProvider extends ContentProvider {
-       // Holds the database object
-    private SQLiteDatabase db;
-    /*
-     * Defines a handle to the database helper object. The MainDatabaseHelper class is defined
-     * in a following snippet.
-     */
+    // Creates a UriMatcher object.
+    private static final UriMatcher sUriMatcher;
+    
+    // Handle to a new DatabaseHelper.
     private IndexerOpenHelper mOpenHelper;
-
-       
-       /* (non-Javadoc)
-        * @see android.content.ContentProvider#delete(android.net.Uri, java.lang.String, java.lang.String[])
+    
+    // The incoming URI matches the Notes URI pattern
+    private static final int INDEXER = 1;
+    
+    // The incoming URI matches the Note ID URI pattern
+    private static final int INDEXER_ID = 2;
+    
+    static {
+       
+       /*
+         * Creates and initializes the URI matcher
+         */
+        // Create a new instance
+        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        
+        // Add a pattern that routes URIs terminated with "notes" to a NOTES operation
+        sUriMatcher.addURI("de.android.test3.provider", "indexer", INDEXER);
+        
+        // Add a pattern that routes URIs terminated with "notes" plus an integer
+        // to a note ID operation
+        sUriMatcher.addURI("de.android.test3.provider", "indexer/#", INDEXER_ID);
+    }
+    
+    
+    /**
+        *
+        * Initializes the provider by creating a new DatabaseHelper. onCreate() is called
+        * automatically when Android creates the provider in response to a resolver request from a
+        * client.
         */
        @Override
+       public boolean onCreate() {
+               
+      // Creates a new helper object. Note that the database itself isn't opened until
+      // something tries to access it, and it's only created if it doesn't already exist.
+      mOpenHelper = new IndexerOpenHelper(getContext());
+
+      // Assumes that any failures will be reported by a thrown exception.
+      return true;
+       }
+    
+       
+    /**
+     * This is called when a client calls
+     * {@link android.content.ContentResolver#delete(Uri, String, String[])}.
+     * Deletes records from the database. If the incoming URI matches the note ID URI pattern,
+     * this method deletes the one record specified by the ID in the URI. Otherwise, it deletes a
+     * a set of records. The record or records must also match the input selection criteria
+     * specified by where and whereArgs.
+     *
+     * If rows were deleted, then listeners are notified of the change.
+     * @return If a "where" clause is used, the number of rows affected is returned, otherwise
+     * 0 is returned. To delete all rows and get a row count, use "1" as the where clause.
+     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
+     */
+    @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
-               // TODO Auto-generated method stub
+       // Opens the database object in "write" mode.
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+       
+        String finalWhere;
+
+        int count;
+
+        // Does the delete based on the incoming URI pattern.
+        switch (sUriMatcher.match(uri)) {
+        case INDEXER_ID:
+               /*
+             * Starts a final WHERE clause by restricting it to the
+             * desired note ID.
+             */
+            finalWhere =
+                    NotePad.Notes._ID +                              // The ID column name
+                    " = " +                                          // test for equality
+                    uri.getPathSegments().                           // the incoming note ID
+                        get(NotePad.Notes.NOTE_ID_PATH_POSITION)
+            ;
+
+            // If there were additional selection criteria, append them to the final
+            // WHERE clause
+            if (where != null) {
+                finalWhere = finalWhere + " AND " + where;
+            }
+
+            // Performs the delete.
+            count = db.delete(
+                NotePad.Notes.TABLE_NAME,  // The database table name.
+                finalWhere,                // The final WHERE clause
+                whereArgs                  // The incoming where clause values.
+            );
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+       
                return 0;
        }
 
@@ -53,15 +141,8 @@ public class IndexerProvider extends ContentProvider {
 
                return null;
        }
-
-       /* (non-Javadoc)
-        * @see android.content.ContentProvider#onCreate()
-        */
-       @Override
-       public boolean onCreate() {
-               // TODO Auto-generated method stub
-               return false;
-       }
+       
+       
 
        /* (non-Javadoc)
         * @see android.content.ContentProvider#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)
index becd13f..9055d26 100644 (file)
@@ -84,15 +84,13 @@ public class MobieAdHttpClient implements Runnable
                                   //So AndroidHttpClient infinite timeout
                                   //and the connection can be kept forever.
                                   StringBuilder builder = httpClient.execute(httpGet, handler);
-                                  if (builder != null) {
-                                          JSONTokener tokener = new JSONTokener(builder.toString());
-                                          JSONArray finalResult = new JSONArray(tokener);
-                                          for (int i = 0; i < finalResult.length(); i++) {
-                                                  JSONObject objects = finalResult.getJSONObject(i);
-                                                  //Find out if that id is in the SQLite database.
-                                                  downloadAds((Integer) objects.get("id"), (String)objects.get("domain"), (String)objects.get("link"));   
-                                          }    
-                                  }  
+                                  JSONTokener tokener = new JSONTokener(builder.toString());
+                                  JSONArray finalResult = new JSONArray(tokener);
+                                  for (int i = 0; i < finalResult.length(); i++) {
+                                          JSONObject objects = finalResult.getJSONObject(i);
+                                          //Find out if that id is in the SQLite database.
+                                          downloadAds((Integer) objects.get("id"), (String)objects.get("domain"), (String)objects.get("link"));   
+                                  }    
                           } catch (URISyntaxException e) {
                                   Log.e(TAG, "Error while creating URI from URL.", e);  
                           } catch (ClientProtocolException e) {
@@ -109,6 +107,7 @@ public class MobieAdHttpClient implements Runnable
                                   //NextActivity.this.httpClient.close();
                           }   
                   } catch (Throwable e) {
+                          //Not sure if it is "legal" to catch Throwable...
                           Log.e(TAG, "Caught exception, something went wrong", e);
                   }
           }
@@ -143,13 +142,12 @@ public class MobieAdHttpClient implements Runnable
                                   break;                               
                           case HttpStatus.SC_UNAUTHORIZED:
                                   //ERROR IN USERNAME OR PASSWORD
-                                  break;                               
+                                  throw new SecurityException("Unauthorized access: error in username or password.");
                           case HttpStatus.SC_BAD_REQUEST:
                                   //WHAT THE HECK ARE YOU DOING?
-                                  break;                               
+                                  throw new IllegalArgumentException("Bad request.");                  
                           default:
-                                  Log.e(TAG, "Error while retrieving the HTTP status line.");
-                                  break;       
+                      throw new IllegalArgumentException("Error while retrieving the HTTP status line.");
                           }   
                   }