Use ContentProvider to access non-database data
Generally, ContentProvider is used to access database data, but sometimes non-database data, such as XML or local data, needs to be specially processed.
The most important thing is to customize the Cursor, because the ContentProvider's query method can only return the Cursor reference. Let's talk about the code.
- Public class MyContentProvider extends ContentProvider {
- // URI operation class
- Public static final UriMatcher uriMatcher;
- // Add a custom URI for UriMatcher
- Static {
- UriMatcher = new UriMatcher (UriMatcher. NO_MATCH );
- UriMatcher. addURI (ProviderConstant. AUTHORITIES, "/user ",
- ProviderConstant. INCOMING_USER_COLLECTION );
- UriMatcher. addURI (ProviderConstant. AUTHORITIES, "/user /#",
- ProviderConstant. INCOMING_USER_SINGLE );
- }
- Private HashMap > AllDatas = new HashMap > ();
- Private MyCursor cursor;
- Public MyContentProvider (){
- Cursor = new MyCursor ();
- LoadAllData ();
- }
- /**
- * Load our data information
- */
- Public void loadAllData (){
- AllDatas. clear ();
- For (int pos = 0; pos <5; pos ++) {// fill in 5 student data
- ArrayList DataList = new ArrayList <> ();
- DataList. add (pos + ""); // id
- DataList. add ("name" + pos); // name
- AllDatas. put (pos + "", dataList );
- }
- }
- /**
- * Delete data
- */
- @ Override
- Public int delete (Uri uri, String selection, String [] selectionArgs ){
- System. out. println ("delete ");
- Int count = 0;
- String id = getUserId (selection, selectionArgs );
- If (allDatas. containsKey (id )){
- AllDatas. remove (id );
- Count = 1;
- }
- Return count;
- }
- /**
- * Database access type
- */
- @ Override
- Public String getType (Uri uri ){
- System. out. println ("getType ");
- // Obtain the data type based on the user request
- Switch (uriMatcher. match (uri )){
- Case ProviderConstant. INCOMING_USER_COLLECTION:
- Return ProviderConstant. CONTENT_TYPE;
- Case ProviderConstant. INCOMING_USER_SINGLE:
- Return ProviderConstant. CONTENT_TYPE_ITEM;
- Default:
- Throw new IllegalArgumentException ("UnKnown URI" + uri );
- }
- }
- /**
- * Insert data
- */
- @ Override
- Public Uri insert (Uri uri, ContentValues values ){
- ArrayList Data = new ArrayList <> ();
- Int id = values. getAsInteger (ProviderConstant. ID );
- String name = values. getAsString (ProviderConstant. NAME );
- Data. add (id + "");
- Data. add (name );
- AllDatas. put (id + "", data );
- Return uri;
- }
- /**
- * Callback function called when ContentProvider is created
- */
- @ Override
- Public boolean onCreate (){
- System. out. println ("onCreate ");
- Return true;
- }
- /**
- * Query a database
- */
- @ Override
- Public Cursor query (Uri uri, String [] projection, String selection,
- String [] selectionArgs, String sortOrder ){
- // Determine whether a user request is a single query
- Switch (uriMatcher. match (uri )){
- Case ProviderConstant. INCOMING_USER_COLLECTION:
- Cursor. updateAllData (allDatas. values ());
- Break;
- Case ProviderConstant. INCOMING_USER_SINGLE:
- String id = uri. getLastPathSegment ();
- Cursor. updateUserData (allDatas. get (id ));
- Break;
- }
- Return cursor;
- }
- /**
- * Update a database
- */
- @ Override
- Public int update (Uri uri, ContentValues values, String selection,
- String [] selectionArgs ){
- System. out. println ("update ");
- String id = getUserId (selection, selectionArgs );
- Int count = 0;
- If (allDatas. containsKey (id )){
- String name = values. getAsString (ProviderConstant. NAME );
- // Index depends on the column where name is located
- AllDatas. get (id). set (cursor. getColumnIndex (ProviderConstant. NAME), name );
- Count = 1;
- }
- Return count;
- }
- /**
- * Obtain key information and user ID
- * @ Param selection
- * @ Param selectionArgs
- * @ Return
- */
- Private String getUserId (String selection, String [] selectionArgs ){
- If (selectionArgs = null | selectionArgs. length = 0 ){
- // Id is included in selection
- Return selection. substring (selection. indexOf ("=") + 1). trim ();
- } Else {
- Return selectionArgs [0];
- }
- }
- }
The above is the custom contentProvider. There are many examples and instructions on the Internet. We will not detail them here. Let's take a look at the query and I will return the custom Cursor.
Some constants are used as follows:
- Public class ProviderConstant {
- // Specify the URI. The string here must be consistent with the declared authorities.
- Public static final String AUTHORITIES = "com. zy. sports. app. MyContentProvider ";
- // Access the uri of the ContentProvider
- Public static final Uri CONTENT_URI = Uri. parse ("content: //" + AUTHORITIES + "/user ");
- // Define the data type returned by the ContentProvider
- Public static final String CONTENT_TYPE = "vnd. android. cursor. dir/vnd. myprovider. user ";
- Public static final String CONTENT_TYPE_ITEM = "vnd. android. cursor. item/vnd. myprovider. user ";
- // Access all columns in the table
- Public static final int INCOMING_USER_COLLECTION = 1;
- // Access a separate column
- Public static final int INCOMING_USER_SINGLE = 2;
- Public static final String ID = "id ";
- Public static final String NAME = "name ";
- }
The custom Cursor code is as follows:
- Public class MyCursor extends actcursor {
- Private static final String TAG = "MyCursor ";
- Private String [] columnNames = null; // when constructing a cursor, you must first input the list array to specify the number of Columns
- /**
- * Data Region
- */
- // All data
- Private ArrayList> allDatas = new ArrayList> (); // fill in the data during construction. The size of the layer data = columnNames. leng
- // Data of the current item
- Private ArrayList OneLineData = null; // fill in when onMove
- Public MyCursor (){
- // Complete column information must be constructed
- ColumnNames = new String [] {"id", "name "};
- }
- /**
- * Load our data information
- */
- Public void updateAllData (Collection> data ){
- MPos =-1;
- AllDatas. clear ();
- AllDatas. addAll (data );
- }
- /**
- * Load our data information
- */
- Public void updateUserData (ArrayList Data ){
- MPos =-1;
- AllDatas. clear ();
- AllDatas. add (data );
- }
- /**
- * Get the object of the current row, which is an oneLineDatastring []
- */
- @ Override
- Public boolean onMove (int oldPosition, int newPosition ){
- If (newPosition <0 | newPosition> = getCount ()){
- OneLineData = null;
- Return false;
- }
- Int index = newPosition;
- If (index <0 | index> = allDatas. size ()){
- Return false;
- }
- OneLineData = allDatas. get (index );
- Return super. onMove (oldPosition, newPosition );
- }
- /**
- * Get the number of cursor rows
- */
- @ Override
- Public int getCount (){
- Return allDatas. size ();
- }
- /**
- * Get the column name
- */
- @ Override
- Public String [] getColumnNames (){
- Return columnNames;
- }
- @ Override
- Public String getString (int column ){
- If (oneLineData = null ){
- Return null;
- }
- Return oneLineData. get (column );
- }
- @ Override
- Public int getInt (int column ){
- Object value = getString (column );
- Try {
- Return value! = Null? (Number) value). intValue (): null;
- } Catch (ClassCastException e ){
- If (value instanceof CharSequence ){
- Try {
- Return Integer. valueOf (value. toString ());
- } Catch (NumberFormatException e2 ){
- Log. e (TAG, "Cannotparse int value for" + value + "at key" + column );
- Return 0;
- }
- } Else {
- Log. e (TAG, "Cannotcast value for" + column + "to a int:" + value, e );
- Return 0;
- }
- }
- }
- /**
- * For the following information, see getInt (int column)
- */
- @ Override
- Public short getShort (int column ){
- Return 0;
- }
- @ Override
- Public long getLong (int column ){
- Return 0;
- }
- @ Override
- Public float getFloat (int column ){
- Return 0;
- }
- @ Override
- Public double getDouble (int column ){
- Return 0;
- }
- @ Override
- Public boolean isNull (int column ){
- Return false;
- }
- }
We can see that Cursor is an interface. We only need to inherit AbstractCursor or its subclass to redefine the Cursor method. For more information