Go ContentProvider content Providers

Source: Internet
Author: User

1.1. What is a content provider

Content provider is one of the four components of Android that can share data from your app to external users

Content providers unify the way data is accessed without having to take different access policies for different data types

Content providers encapsulate data, exposing only the data we want to provide to other programs

Data changes in the content provider can be monitored

1.2. Create a content provider

Define class inheritance ContentProvider, overriding internal methods as needed

You need to specify the name and authorities property in the configuration,<provider> tag in the <application> node of the manifest file

Name is the class name, and the package name starts with the program pack, with "." Begin

Authorities: is the path to access provider, the only

The URI represents the data to be manipulated, consisting of scheme, authorites, path three parts

Content://cn.itcast.provider.itcast/person

Scheme: Fixed to content, on behalf of access provider

The Authorites property in the Authorites:<provider> node

Path: program-defined paths that can be defined according to business logic

1.3. Complete the Crud method

The URI is passed in when the program calls the Crud method

We use URIs to determine the data the caller wants to manipulate.

You can use the tool class Urimatcher to determine the URI

Adduri method to add a URI

The match method can match a URI to determine its type

Operating data based on business logic

1.4. Complete the GetType method

Y if the return data is a single data: Vnd.android.cursor.item

Y if the return data is multiple data: Vnd.android.cursor.dir

public class Personprovider extends Android.content.ContentProvider {private static final int person = 0;    private static final int person_id = 1;    Private Urimatcher Matcher;    Private Dbopenhelper Helper;        @Override public boolean onCreate () {matcher = new Urimatcher (urimatcher.no_match); Matcher.adduri ("Com.demo.sqlite.provider", "person", person);        Add a URI that can match Matcher.adduri ("Com.demo.sqlite.provider", "person/#", person_id);        Helper = new Dbopenhelper (GetContext ());    return true; @Override public Cursor query (URI uri, string[] projection, string selection, string[] Selectionargs, String Sorto Rder) {switch (Matcher.match (URI)) {//URI Match case person_id:string idselection = "ID =" +    Contenturis.parseid (URI);            Converts the last path segment to a long. Note here that the string is assembled selection = Selection = = null?        Idselection:idselection + "and" + selection;  Case Person:          Sqlitedatabase db = Helper.getreadabledatabase ();        return db.query ("person", projection, selection, Selectionargs, NULL, NULL, sortOrder);        Default:throw new IllegalArgumentException ("No Match uri" + uri);  }} @Override public uri insert (URI uri, contentvalues values) {switch (Matcher.match (URI)) {case            Person:sqlitedatabase db = Helper.getwritabledatabase ();        Long id = db.insert ("person", null, values); Use the Db.insert () method to insert data, return ID//and DB.        Excesql (SQL) to insert data, return void//Return Uri.parse ("content://com.demo.sqlite.provider/person/" + ID);        Same as the next sentence return Contenturis.withappendedid (URI, id);            Appends the given ID to the end of the path.        Default:throw new IllegalArgumentException ("No Match uri" + uri); }} @Override Public int Delete (URI Uri, String selection, string[] selectionargs) {switch (Matcher.match (URI)) {case Person_            Id:long id = contenturis.parseid (URI); Selection = Selection = = null?        "id =" + ID: "id =" +id + "and" +selection;            Case Person:sqlitedatabase db = Helper.getwritabledatabase ();         Return:the number of rows affected return Db.delete ("person", selection, Selectionargs);        Default:throw new IllegalArgumentException ("No Match uri" + uri);        }} @Override public int update (URI uri, contentvalues values, String selection, string[] Selectionargs) {            Switch (Matcher.match (URI)) {case Person_id:long ID = Contenturis.parseid (URI); Selection = Selection = = null?        "id =" + ID: "id =" + ID + "and" + selection;            Case Person:sqlitedatabase db = Helper.getwritabledatabase (); @return The number of rows AFFECTed return Db.update ("person", values, selection, Selectionargs);        Default:throw new IllegalArgumentException ("No Match uri" + uri);            }} @Override public String getType (URI uri) {switch (Matcher.match (URI)) {case PERSON_ID:        return "Vnd.android.cursor.item/person";         Case Person:return "Vnd.android.cursor.dir/person";        Default:throw new IllegalArgumentException ("No Match uri" + uri); }    }

1.5. Access to content providers

Y get Contentresolver object through context

You can access the content provider by invoking the method of the Contentresolver object

    private static final String TAG = "Providertest"; Query id = $ public void TestQuery1 () {//Contentresolver call ContentProvider provided method Contentresolver R        Esolver = GetContext (). Getcontentresolver ();        Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person");        Cursor C = resolver.query (URI, new string[] {"id", "name", "Balance"}, "id =?", new string[] {"$"}, NULL);            if (C.movetonext ()) {Person person = new Person (c.getint (0), c.getstring (1), C.getint (2));        Logger.i (TAG, person.tostring ()); }}//query all person public void TestQuery2 () {//Contentresolver call the method provided by ContentProvider Conten        Tresolver resolver = GetContext (). Getcontentresolver ();        Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person");        Cursor C = resolver.query (URI, NULL, NULL, NULL, or NULL); while (C.movetonext ()) {Person person = new Person (c.getint (0), c.getstring (1), C.getint(2));        Logger.i (TAG, person.tostring ());        }//query by the ID of the person public void TestQuery3 () {//through the Contentresolver call method provided by the ContentProvider        Contentresolver resolver = GetContext (). Getcontentresolver ();        Uri uri uri = uri.parse ("CONTENT://COM.DEMO.SQLITE.PROVIDER/PERSON/55");        Cursor C = resolver.query (URI, NULL, "name =?", new string[] {"ashia_54"}, NULL);            while (C.movetonext ()) {Person person = new Person (c.getint (0), c.getstring (1), C.getint (2));        Logger.i (TAG, person.tostring ());        }} public void Testinsert () {Contentresolver resolver = GetContext (). Getcontentresolver ();        Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person");        Contentvalues values = new Contentvalues ();        person person = new person ("Another person URI insert", 7000);        Values.put ("Name", Person.getname ());        Values.put ("Balance", person.getbalance ()); Uri reuri = Resolver.insert (URI, values);        Cursor C = resolver.query (Reuri, NULL, NULL, NULL, or NULL);            if (C.movetonext ()) {Person Reperson = new Person (c.getint (0), c.getstring (1), C.getint (2));        Logger.i (TAG, reperson.tostring ());  }} public void Testdelete () {//Contentresolver:this class provides applications access to the content        Model.                Contentresolver resolver = GetContext (). Getcontentresolver ();        Uri url = uri.parse ("content://com.demo.sqlite.provider/person/121"); Forget add =?, exception as follows//android.database.sqlite.SQLiteException:bind or column index out of range long id = RE         Solver.delete (URL, "name =?", new string[] {"Zhangsan"});                  LOGGER.I (TAG, id + "");         id = resolver.delete (URL, null, NULL);    LOGGER.I (TAG, id + "");        The public void Testdeleteall () {Contentresolver resolver = GetContext (). Getcontentresolver (); Uri url = uri.parse ("contEnt://com.demo.sqlite.provider/person ");        int deletenum = resolver.delete (URL, null, NULL);    Logger.i (TAG, Deletenum + "");        The public void Testupdate () {Contentresolver resolver = GetContext (). Getcontentresolver ();        Uri uri = uri.parse ("content://com.demo.sqlite.provider/person/122");        Contentvalues values = new Contentvalues ();        Values.put ("balance", 8000);        int update = Resolver.update (URI, values, "balance =?", new string[] {"9000"});    LOGGER.I (TAG, update + "");        The public void Testupdatebyid () {Contentresolver resolver = GetContext (). Getcontentresolver ();        Contentvalues values = new Contentvalues ();        Values.put ("Name", "new name");        Values.put ("balance", 7000);        Values.put ("id", 2);        Uri uri = uri.parse ("content://com.demo.sqlite.provider/person/123");        int update = Resolver.update (URI, values, NULL, NULL);    LOGGER.I (TAG, update + ""); }//URI write error, exception//JAVA.lang.illegalargumentexception:unknown URI//primary Key ID Duplicate, exception//Android.database.sqlite.SQLiteConstraintExceptio        n public void Testgettype () {Contentresolver resolver = GetContext (). Getcontentresolver ();        Uri uri = uri.parse ("CONTENT://COM.DEMO.SQLITE.PROVIDER/PERSON/1");        Logger.i (TAG, Resolver.gettype (URI));        URI = Uri.parse ("Content://com.demo.sqlite.provider/person");    Logger.i (TAG, Resolver.gettype (URI)); }

1.6. Monitor content provider Data changes

Y can notify other program data changes in content provider

Get Contentresolver through the Getcontentresolver () method of the context

Call its Notifychange () method to send data modification notifications

Y can monitor data changes through Contentobserver in other programs

Get Contentresolver through the Getcontentresolver () method of the context

Calls its Registercontentobserver () method to specify that a URI is registered Contentobserver

Custom Contentobserver, overriding the OnChange () method to get the data

Send data modification Notifications

    Public URI insert (URI uri, contentvalues values) {        switch (Matcher.match (URI)) {case Person        :            Sqlitedatabase db = Helper.getwritabledatabase ();            Long id = db.insert ("person", null, values);              Notify registered observers that a row is updated. Register observer            //@param observer The Observer that originated the changes, may be null            //Generate a change of observer. Here is the provider belt To change, pass null            this.getcontext (). Getcontentresolver (). Notifychange (URI, null);     Send change notification                        //return     uri.parse ("content://com.demo.sqlite.provider/person/" + ID);             Return Contenturis.withappendedid (URI, id);             Default:                throw new IllegalArgumentException ("No Match uri" + uri);        }    }

Defines a contentobserver that listens for changes to the content provider of the URI

    Protected static final String TAG = "observeractivity"; /** called when the activity is first created.        */@Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.main);  Define a CONTENTOBSERVER contentobserver observer = new Contentobserver (new Handler ()) {/** * Returns TRUE if this observer was interested in notifications for * changes made through the cursor the Observ             ER is registered with. *///whether to pass your own changes @Override public boolean deliverselfnotifications () {Retu            RN Super.deliverselfnotifications (); }/** * This method was called when a change occurs to the cursor that was * being observ             Ed.             * * @param Selfchange * True if the update is caused by a call to commit on * The CursOr is being observed.                *///when the monitored content has changed, call the method @Override public void OnChange (Boolean selfchange) {                LOGGER.I (TAG, "the supervisor hears the change");                Print out the last inserted information contentresolver resolver = Getcontentresolver ();                Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person");                SELECT * FROM person ORDER by ID DESC LIMIT 1;                Cursor C = resolver.query (URI, NULL, NULL, NULL, "ID DESC LIMIT 1"); if (C.movetonext ()) {String result = "id =" + c.getint (0) + ", name =" + c.getstring (1) + ", balance                    = "+ c.getint (2);                    LOGGER.I (TAG, result);                Toast.maketext (Observeractivity.this, result, 1). Show ();            }//Parent class did not do any implementation super.onchange (Selfchange);                }        };        Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person"); Register a contentObserver/* * @param notifyfordescendents * If true changes to URIs beginning with URI would also C          Ause notifications to be sent.          * Iffalse only changes to the exact URI specified by URI would cause notifications to be sent.         * If true, than any URI values at or below the specified URI would also trigger a match.    *///whether to listen for other URIs starting with "uri" Getcontentresolver (). Registercontentobserver (URI, TRUE, observer); }

Monitor content changes and automatically update the ListView via Contentobserver

        Bt_insert = (Button) Findviewbyid (R.id.bt_insert); Bt_insert.setonclicklistener (New Onclicklistener () {public void OnClick (View v) {Contentresolv                ER resolver = ListViewSimpleCursorAdapterActivity.this.getContentResolver ();                Uri url = uri.parse ("Content://com.demo.sqlite.provider/person");                Contentvalues values = new Contentvalues ();                Values.put ("name", "Test Name");                Values.put ("balance", 3000);            Resolver.insert (URL, values);        }        });        Lv_person.setonitemclicklistener (New Myonitemclicklistener ());        Uri uri = uri.parse ("Content://com.demo.sqlite.provider/person");    Getcontentresolver (). Registercontentobserver (URI, False, new Mycontentobserver (New Handler ())); public class Mycontentobserver extends Contentobserver {public mycontentobserver (Handler Handler) {sup        ER (handler); } @Override public void OnchaNge (Boolean Selfchange) {//When the listening content has changed, the data in the LV is updated with the Cursor c = new Persondao (Listviewsimplecursorada            pteractivity.this). Queryallcursor (); Simplecursoradapter adapter = new Simplecursoradapter (listviewsimplecursoradapteractivity.this,//R.la                    Yout.listview_item,//C,//new string[] {"_id", "name", "balance"},//            New int[] {r.id.tv_id, r.id.tv_name, r.id.tv_balance});            Lv_person.setadapter (adapter);            Lv_person.setonitemclicklistener (New Myonitemclicklistener ());            Super.onchange (Selfchange);        LOGGER.I (TAG, "OnChange"); }    }

Error

URI write error, exception Java.lang.IllegalArgumentException:Unknown URI
Duplicate primary key ID, exception android.database.sqlite.SQLiteConstraintException

The interface always closes automatically when you test a ListView update

If you are a content provider and a content observer,

When you change content in a test case, the app forces the exit

Go ContentProvider content Providers

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.