As one of the Android ContentProvider four components, mainly for sharing data between applications. More common development is the use of the operating system getContentResolver multimedia database (MediaProvider). This paper describes how to customize ContentProvider and precautions.
A custom SimpleContentProvider.java, inherited ContentProvider.
code show as below:
public class SimpleContentProvider the extends the ContentProvider { Private static Final String the TAG = "SimpleContentProvider" ; // if using matching UriMatcher.NO_MATCH (-1) Returns Private static Final UriMatcher Matcher = new new UriMatcher (UriMatcher.NO_MATCH); Private static Final int CODE_NOPARAM = 1; // no arguments // matching code Private static Final int CODE_PARAM = 2; // parameters static { //Waiting for the URI matching the unmatched operations must comply com.test.providers.SimpleContentProvider / artical format // returned matches CODE_NOPARAM, mismatch return -1 MATCHER.addURI ( "com.test.providers.SimpleContentProvider", "Artical" , CODE_NOPARAM); // # represents a number com.test.providers.SimpleContentProvider / Artical / 10 // returned matches CODE_PARAM, mismatch return -1 MATCHER.addURI ( "com.test.providers.SimpleContentProvider", "Artical / #" , CODE_PARAM); } Private dBOpenHelper dbOpenHelper; // database operation Private Final String ARTICAL_TABLE = "Artical" ; @Override public boolean onCreate() { //Auto-Generated Method Stub the TODO dbOpenHelper = new new DBOpenHelper (the getContext ()); return to true ; } @Override public Uri INSERT (Uri URI, ContentValues CV) { // the TODO Auto-Generated Method Stub Log.i (the TAG, "INSERT ( ) " ); the SQLiteDatabase DB = dbOpenHelper.getWritableDatabase (); Switch (MATCHER.match (URI)) { Case CODE_NOPARAM: Long ID = db.insert (ARTICAL_TABLE, null , CV); // if the primary key is the increment, then returns the primary key value; otherwise, the line number Uri insertUri = ContentUris.withAppendedId(uri, id); return insertUri; default: throw new IllegalArgumentException("This is unknow uri: " + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub Log.i(TAG, "delete()"); SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case CODE_NOPARAM: return db.delete(ARTICAL_TABLE, selection, selectionArgs); //删除所有记录 case CODE_PARAM: long id = ContentUris.parseId(uri); //取得Uri后面的数字 String where = "_id = " + id; if(null != selection && !(selection.trim()).equals("")){ where += "and " + selection; } return db.delete(ARTICAL_TABLE, where, selectionArgs); default: throw new IllegalArgumentException("This is unknow uri: " + uri); } } @Override public int update(Uri uri, ContentValues cv, String selection, String[] selectionArgs) { // TODO Auto-generated method stub Log.i(TAG, "update()"); SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case CODE_NOPARAM: return db.update(ARTICAL_TABLE, cv, selection, selectionArgs); //更新所有记录 case CODE_PARAM: long id = ContentUris.parseId(uri); //取得Uri后面的数字 WHERE = String "the _id =" +ID; IF ( null !!. = Selection && (selection.trim ()) the equals ( "" )) { WHERE + = "and" + Selection; } return db.update (ARTICAL_TABLE, CV, WHERE, selectionArgs); default : the throw new new an IllegalArgumentException ( "iS unknow This URI:" + URI); } } / ** * returns the corresponding content type * set if the return type of the content, must start com.test.android.cursor.dir * If a single element, must start com.test.android.cursor.item * / @Override public String getType (Uri URI) { // TODO Auto-generated method stub Log.i(TAG, "getType()"); switch (MATCHER.match(uri)) { case CODE_NOPARAM: return "com.test.android.cursor.dir/artical"; case CODE_PARAM: return "com.test.android.cursor.item/artical"; default: throw new IllegalArgumentException("This is unknow uri: " + uri); } } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy) { // TODO Auto-generated method stub Log.i(TAG, "query()"); SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); switch (MATCHER.match(uri)) { case CODE_NOPARAM: return db.query(ARTICAL_TABLE, projection, selection, selectionArgs, null, null, orderBy); case CODE_PARAM: long id = ContentUris.parseId(uri); //取得Uri后面的数字 String where = "_id = " + id; if(null != selection && !(selection.trim()).equals("")){ where += "and " + selection; } return db.query(ARTICAL_TABLE, projection, where, selectionArgs, null, null, orderBy); default: throw new IllegalArgumentException("This is unknow uri: " + uri); } } }
This class provides the basic CRUD method, it can be seen, the actual operation of the database. Wherein DBOpenHelper SQLiteOpenHelper class is inherited from a custom class, which contains a basic database creation, create a table like operation, relatively simple, not posted code here.
Specific steps:
1, have created a custom class, you need to register it to your AndroidManifest.xml:
<! - from some of the permissions defined, you need to publish in order to be used by other applications ->
<permission Android: name = "android.permission.WRITE_SCP" />
<permission Android: name = "android.permission.READ_SCP" />
< Provider Android: name = "com.test.contentprovider.SimpleContentProvider" Android: Authorities = "com.test.providers.SimpleContentProvider" Android: exported = "to true" Android: readPermission = "android.permission.READ_SCP" Android: writePermission = "android.permission.WRITE_SCP" > <path-permission android:pathPrefix="/search_query" android:readPermission="android.permission.GLOBAL_SEARCH" /> </provider>
Description:
android: exported = "true", allows access to the Provider in other applications; if set to false, only with components of an application or an application with the same user ID to start or bind the service.
android: authorities authorization information, to distinguish itself from the ContentProvider
Android: Permissions permission access provider's statement
Permissions refinement, can be divided into the following two:
Android: readPermission for read permission,
Android: writePermission write permissions
[Questions] after granular permissions than the permission priority.
However, the test results showed that: only add readPermission or writePermission authority in another application provider can read and write, refine where that role? In the Internet-related presentation but could not find, if anyone knows, can leave a message to inform, thank you!
2, since the declaration of rights, so when other applications access to the provider, AndroidManifest.xml also need to request access otherwise inaccessible.
<uses-permission android:name="android.permission.READ_SCP"/> <uses-permission android:name="android.permission.WRITE_SCP"/>
3, the program visit:
Uri uri = Uri.parse("content://com.test.providers.SimpleContentProvider/artical"); ContentResolver resolver = getContentResolver(); ContentValues values = new ContentValues(); values.put("title", "testcase1 "); values.put("content", "ContentProvider-put"); resolver.insert(uri, values);
That is more than an example of a simple custom ContentProvider of access.
4. Summary:
Typically, the ContentProvider or database for storing data operation, but is encapsulated. Whether or custom class native type system, it is achieved using ContentProvider + SQLiteOpenHelper. (Custom class inherits ContentProvider, SQLiteOpenHelper implement custom class that inherits the corresponding database operation.) Example: system MediaProvider, SettingsProvider or custom SimpleContentProvider above is true.
However, this does not mean ContentProvider only operate databases, files, etc. can be, but I have not tested, can be independently verified interest.
Second, the expansion:
Summing up Cursor traverse ContentProvider, commonly used in several ways: in fact, use for () and the while.
. 1 the ContentResolver Resolver = getContentResolver (); 2 the Cursor Cursor = resolver.query (URI, null , null , null , null ); . 3 IF (! Cursor = null && cursor.getCount ()> 0 ) { . 4 ..... // through code position 5 } . 6 . 7 method a: . 8 for (cursor.moveToFirst ();! cursor.isAfterLast (); cursor.moveToNext ()) { . 9 ...... 10 } . 11 12 is two: 13 while(cursor.moveToNext ()) { 14 .... // specific operation 15 } 16 . 17 Method three: 18 is . 19 cursor.moveToFirst (); // to the first line; default cursor subscripts -1 20 is the while ( ! cursor.isAfterLast ()) { 21 is ....... 22 is ....... // specific operation 23 is cursor.moveToNext (); 24 } 25 26 is FOUR: 27 cursor.moveToFirst (); 28 do { 29 ...... 30 } the while (cursor.moveToNext ());
The code appears to be very simple, but in the process of self-test, it was an odd question:
While sporadic case of several missing data (ie, currently has three data, only read two; but this time (while using) if the record id to read the data can be successfully read three), the specific reasons is not found, after repeatedly testing can not reproduce, so here write down the case, the message may be there is to know this, thank you.