Content provider of Android's four components

Keywords: Android Database Mobile

1 Introduction

As one of the four components of Android, the main function of content provider is to expose private data for other applications. For example, an application needs to read the mobile contacts in the mobile phone for its own use. From this we can know that this is also a way of communication between processes in Android. Content providers don't write much on their own in development. Most of them are content providers who visit the system

2 simple cases

Create a new application project to realize sqllite initialization:

 public class MySqliteopenhelper extends SQLiteOpenHelper {

    public MySqliteopenhelper(Context context) {
        super(context, "test.db", null, 1);
        // TODO Auto-generated constructor stub
    }

    //Called the first time it is created
    //Ideal for initialization
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table person (_id integer primary key autoincrement,name varchar(20),age varchar(20) )");
        db.execSQL("insert into person (name,age) values('Zhao Ritian','9')");
        db.execSQL("insert into person (name,age) values('Liu Zhanxian','10')");
        db.execSQL("insert into person (name,age) values('Li zashen','7')");
        db.execSQL("insert into person (name,age) values('Wang Zhumo','8')");
    }
    //Called when the version is updated
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }
 }

To create a new ContentProvider implementation class MyProvider:

public class MyProvider extends ContentProvider {

    private static final int QUERY = 1;
    // 1. android:authorities="cn.test.provider" android 4.4 and above is required to be configured in the manifest file. android:exported="true" needs to be configured additionally 
    // 2. Add a uri matcher
    private static final UriMatcher urimatcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int INSERT = 2;
    private static final int DELETE = 3;
    private static final int UPDATE = 4;
    private MySqliteopenhelper helper;
    static {
        // authority is the Android configured in the manifest file: authorities = "CN. Test. Provider"
        // authority is equivalent to the host name www.baidu.com
        // Path the secondary path is equivalent to the news of www.baidu.com/news
        // The return code must be positive after the code matches successfully
        urimatcher.addURI("cn.test.provider", "query", QUERY);
        urimatcher.addURI("cn.test.provider", "insert", INSERT);
        urimatcher.addURI("cn.test.provider", "delete", DELETE);
        urimatcher.addURI("cn.test.provider", "update", UPDATE);
    }

    @Override
    public boolean onCreate() {
        // getContext() method for content provider to get context

        helper = new MySqliteopenhelper(getContext());
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

        // Do not operate the database until the matching uri matches successfully
        int match = urimatcher.match(uri);
        if (match == QUERY) {
            SQLiteDatabase db = helper.getReadableDatabase();
            // Project the name of the column to query
            Cursor cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder);

            //Don't turn off the data
//          db.close();
            return cursor;
        } else {
            throw new IllegalArgumentException("Xiong di!Your uri There seems to be something wrong");
        }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {

        // Judge match code
        int match = urimatcher.match(uri);
        if (match == INSERT) {
            SQLiteDatabase db = helper.getWritableDatabase();

            // insert2 data added to lines
            long insert2 = db.insert("person", null, values);
            db.close();
            return Uri.parse("cn.test/" + insert2);
        } else {
            throw new IllegalArgumentException("Big brother!Your code is not right");
        }

    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {

        if (urimatcher.match(uri) == DELETE) {
            SQLiteDatabase db = helper.getWritableDatabase();

            // Delete delete2 delete affected several lines
            int delete2 = db.delete("person", selection, selectionArgs);

            db.close();

            return delete2;
        }
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

        if (urimatcher.match(uri) == UPDATE) {
            SQLiteDatabase db = helper.getWritableDatabase();
            // Update data update 2 modify influence lines
            int update2 = db.update("person", values, selection, selectionArgs);

            db.close();
            return update2;
        }
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }
}

Registration list:

    <provider
            android:name="cn.test.whycontentprovider.MyProvider"
            android:authorities="cn.test.provider" 
            android:exported="true">
        </provider>

At this time, we will create a new application project and write four buttons to query, add, delete and modify the content provider:

//Content provider queries database of other applications

public void click1(View v) {

        // content:// uri must be added before
        Uri uri = Uri.parse("content://cn.test.provider/query");
        // Get content resolver
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);

        while (cursor.moveToNext()) {
            String _id = cursor.getString(0);
            String name = cursor.getString(1);
            String age = cursor.getString(2);
            System.out.println("Data queried by content provider" + " " + _id + " " + name + " " + age);
        }
        cursor.close();
    }

    // Content providers add databases for other applications
    public void click2(View v) {
        Uri url = Uri.parse("content://cn.test.provider/insert");
        ContentValues values = new ContentValues();
        values.put("name", "Ye Liangchen");
        values.put("age", "15");
        // Get content resolver
        Uri insert = getContentResolver().insert(url, values);
        System.out.println(insert);
    }

    // Content provider delete database of other applications
    public void click3(View v) {
        Uri url = Uri.parse("content://cn.test.provider/delete");
        int delete = getContentResolver().delete(url, "_id=?", new String[] { "2" });
        System.out.println(delete);
    }

    // Content provider modifies database of other applications
    public void click4(View v) {
        Uri url = Uri.parse("content://cn.test.provider/update");
        ContentValues values = new ContentValues();
        values.put("age", "99");
        int update = getContentResolver().update(url, values, "_id=?", new String[] { "1" });
        System.out.println(update);
    }

3 content provider case - read contact

Step:
First, query the raw contact table and find that the contact ID is the data table raw contact ID
Then query data1 and mimetype according to raw? Contact? ID
Finally, the content of data1 is distinguished according to mimetype

/**
     * Query contact through content provider
     * 
     * @param context
     *            context
     * 
     * @return Collection of contacts
     */
    public List<ContactInfo> queryContacts(Context context) {
        List<ContactInfo> infos = null;
        // 1 query raw contacts table query contact ID
        // 1> Query the uri of raw_contacts to the source code list file and the source code to find the path
        // android:authorities="contacts;com.android.contacts" contacts previously used
        // com.android.contacts new authorities
        // matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts",
        // RAW_CONTACTS);
        // 2. Query the data table for data1 according to the found contact ID, that is, raw contact ID in the data table
        // mimetype
        // 3 use mimeType? ID to distinguish the data of data1 found
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri datauri = Uri.parse("content://com.android.contacts/data");
        ///1 query raw contacts table query contact ID all
        Cursor cursor = context.getContentResolver().query(uri, new String[] { "contact_id" }, null, null, null);
        if (cursor != null && cursor.getCount() > 0) {
            // Initialize collection
            infos = new ArrayList<>();
            while (cursor.moveToNext()) {
                String contact_id = cursor.getString(0);
                System.out.println(contact_id);
                // Query all column names
                // Cursor cursor2 = getContentResolver().query(datauri, null,
                // null, null, null);
                // //Query all column names in cursor
                // String[] columnNames = cursor2.getColumnNames();
                // for (String string : columnNames) {
                // System.out.println(string);
                // }
                // If no contact ID is found, you need to query the data table for data1 and mimeType ID
                // mimetype [ID] does not exist in the data table, but has mimetype
                //Remember to make a non empty judgment. Instead of deleting this data, the database is set to null
                if (contact_id!=null) {
                    Cursor datacursor = context.getContentResolver().query(datauri,
                            new String[] { "data1", "mimetype" }, "raw_contact_id=?", new String[] { contact_id },
                            null);
                    if (datacursor != null && datacursor.getCount() > 0) {
                        // Here comes the description that the data of a contact can be used to create a contact object
                        ContactInfo info = new ContactInfo();
                        // Loop out each data
                        // Cycle out
                        while (datacursor.moveToNext()) {
                            String data1 = datacursor.getString(0);
                            String mimetype = datacursor.getString(1);
                            // 3 use mimetype to distinguish acquired data
                            if (mimetype.equals("vnd.android.cursor.item/phone_v2")) {
                                // System.out.println("contact's phone number is:" + data1);
                                info.setPhone(data1);
                            }
                            if (mimetype.equals("vnd.android.cursor.item/name")) {
                                // System.out.println("contact's name is:" + data1);
                                info.setName(data1);
                            }
                            if (mimetype.equals("vnd.android.cursor.item/nickname")) {
                                // System.out.println("the nickname of the contact is:" + data1);
                                info.setNickname(data1);
                            }
                            if (mimetype.equals("vnd.android.cursor.item/email_v2")) {
                                // System.out.println("contact's email is:" + data1);
                                info.setEmail(data1);
                            }
                        }
                        datacursor.close();
                        infos.add(info);
                    }
                }
            }
        }
        cursor.close();
        return infos;
    }

4 content observer

Content watchers are designed to notify content providers

Content usage:
      Uri uri=Uri.parse("content://cn.test.provider/query");
        //Registered content observer through content resolver
        //Notifyfordescendents ture is not very strict in detecting URIs and false is very strict in checking URIs
        getContentResolver().registerContentObserver(uri, true, new MyContenObserver(new Handler()));



 class MyContenObserver extends ContentObserver{

        //handler needs to update UI
        public MyContenObserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }

        //Whether selfChange is the content provider of its own application changes
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            System.out.println("The database has changed");
        }

    }

content provider
Data supply division

    `getContext().getContentResolver().notifyChange(uri,null);`
Whether observer specifies a dedicated observer null does not specify a dedicated observer.

Posted by sava on Sat, 02 May 2020 02:34:36 -0700