zoukankan      html  css  js  c++  java
  • SQLite数据库与Contentprovider(2)

    ContentProvider

    在创建ContentProvider时,需要首先使用数据库、文件系统或网络实现底层存储功能,

    然后在继承ContentProvider的类中实现基本数据操作的接口函数,包括添加、删除、查找和更新等功能。

    调用者不能够直接调用ContentProvider的接口函数,而需要使用ContentResolver对象,

    通过URI间接调用ContentProvider。下图是ContentProvider调用关系。

    URI

    URI是通用资源标志符(Uniform Resource Identifier),用来定位任何远程或本地的可用资源

    ContentProvider使用的URI语法结构如下

    content://<authority>/<data_path>/<id>

    content://是通用前缀,表示该URI用于ContentProvider定位资源,无需修改。

    <authority>是授权者名称,用来确定具体由哪一个ContentProvider提供资源。因此,一般<authority>都由类的小写全称组成,以保证唯一性。

    <data_path>是数据路径,用来确定请求的是哪个数据集。

    例如:

    content://edu.hrbeu.peopleprovider/people/3

    可以省略id(/3)部分那么意味着整个数据。

    UriMatcher:

    在新构造的ContentProvider类中,通过构造一个UriMatcher,判断URI是单条数据还是多条数据。

    public void  addURI  (String authority, String path, int code)

    authority表示匹配的授权者名称

    path表示数据路径

    #可以代表任何数字 (content://<authority>/<data_path>/#

    code表示返回代码uriMatcher.match(uri))的返回值

    注册ContentProvider

    <provider android:name = ".PeopleProvider" android:authorities = "edu.hrbeu.peopleprovider"/> 

    实例:

    ContentProvider一般用于两个不同的进程之间的数据共享。

    1. 假设我们有一个新的工程(app),在此工程中创建一个people.db数据库,然后通过自定义了一个ContentProvider来共享数据库中的data。
    2. 我们可以通过注册provider时用到的authority在配合db path之类的来连接(content://<authority>/<data_path>/#)读取内容提供者(不同进程)的数据。

    首先是步骤1:

    *只要在AndroidManifast中注册provider就会执行对应的provider类。无需再MainActivity中调用或无需直接调用自定义的new provider。

    即系统自动会加载调用PeopleProvider类。

    <provider android:name = ".PeopleProvider" android:authorities = "edu.hrbeu.peopleprovider"/> 

    继承ContentProvider时代码如下:

    import android.content.*;
    import android.database.Cursor;
    import android.net.Uri;
     
    public class PeopleProvider extends ContentProvider{
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public String getType(Uri uri) {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public boolean onCreate() {
            // TODO Auto-generated method stub
            return false;
        }
             @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                String[] selectionArgs) {
            // TODO Auto-generated method stub
            return 0;
        }
    }

    类似数据库操作。可以这么理解,相对来说好理解。

    开始贴代码。。。

    package edu.hrbeu.contentproviderdemo;
     
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.database.sqlite.SQLiteQueryBuilder;
    import android.net.Uri;
    
    public class PeopleProvider extends ContentProvider {
        
        private static final String DB_NAME = "people.db";
        private static final String DB_TABLE = "peopleinfo";
        private static final int DB_VERSION = 1;
        
        private SQLiteDatabase db;
        private DBOpenHelper dbOpenHelper;
        
        private static final int MULTIPLE_PEOPLE = 1;
        private static final int SINGLE_PEOPLE = 2;
        private static final UriMatcher uriMatcher;
        static {
             uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
             uriMatcher.addURI(People.AUTHORITY, People.PATH_MULTIPLE, MULTIPLE_PEOPLE);
             uriMatcher.addURI(People.AUTHORITY, People.PATH_SINGLE, SINGLE_PEOPLE);
        }
    
        @Override
        public boolean onCreate() {
            // TODO Auto-generated method stub
            Context context = getContext();
            dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION);
            db = dbOpenHelper.getWritableDatabase();
     
            if (db == null)
                return false;
            else 
                return true;    
    
        }
    
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
            // TODO Auto-generated method stub
            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
            qb.setTables(DB_TABLE);
            switch(uriMatcher.match(uri)){
                case SINGLE_PEOPLE:
                    qb.appendWhere(People.KEY_ID + "=" + uri.getPathSegments().get(1));
                    break;
                default:
                    break;
            }
            Cursor cursor = qb.query(db, 
                    projection, 
                    selection, 
                    selectionArgs, 
                    null, 
                    null, 
                    sortOrder);
            cursor.setNotificationUri(getContext().getContentResolver(), uri);
            return cursor;
    
        }
    
        @Override
        public String getType(Uri uri) {
            // TODO Auto-generated method stub
            switch(uriMatcher.match(uri)){
            case MULTIPLE_PEOPLE:
        return People.MINE_TYPE_MULTIPLE;
            case SINGLE_PEOPLE:
        return People.MINE_TYPE_SINGLE;
            default:
                    throw new IllegalArgumentException("Unkown uri:"+uri);
    }
    
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues values) {
            // TODO Auto-generated method stub
            long id = db.insert(DB_TABLE, null, values);
            if ( id > 0 ){
                Uri newUri = ContentUris.withAppendedId(People.CONTENT_URI, id);
                getContext().getContentResolver().notifyChange(newUri, null);
                return newUri;
            }
            throw new SQLException("Failed to insert row into " + uri);
    
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            int count = 0;
            switch(uriMatcher.match(uri)){
        case MULTIPLE_PEOPLE:
               count = db.delete(DB_TABLE, selection, selectionArgs);
               break;
                      case SINGLE_PEOPLE:
               String segment = uri.getPathSegments().get(1);
                             count = db.delete(DB_TABLE, People.KEY_ID + "=" + segment, selectionArgs);
               break;
       default:
               throw new IllegalArgumentException("Unsupported URI:" + uri);
    }
            getContext().getContentResolver().notifyChange(uri, null); 
            return count;
    
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
            // TODO Auto-generated method stub
            int count;
            switch(uriMatcher.match(uri)){
                     case MULTIPLE_PEOPLE:
                            count = db.update(DB_TABLE, values, selection, selectionArgs);
                            break;
                                         case SINGLE_PEOPLE:
                                                 String segment = uri.getPathSegments().get(1);
                            count = db.update(DB_TABLE, values, People.KEY_ID+"="+segment, selectionArgs);
                               break;
                                         default:
                throw new IllegalArgumentException("Unknow URI:" + uri);     
            }
            getContext().getContentResolver().notifyChange(uri, null);
            return count;
    
        }
        
          private static class DBOpenHelper extends SQLiteOpenHelper {
              
              public DBOpenHelper(Context context, String name, CursorFactory factory, int version) {
                super(context, name, factory, version);
              }
              private static final String DB_CREATE = "create table " + 
                        DB_TABLE + " (" + People.KEY_ID + " integer primary key autoincrement, " +
                               People.KEY_NAME+ " text not null, " + People.KEY_AGE+ " integer," + People.KEY_HEIGHT + " float);";
            @Override
            public void onCreate(SQLiteDatabase _db) {
                // TODO Auto-generated method stub
                _db.execSQL(DB_CREATE);
            }
            @Override
            public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
                // TODO Auto-generated method stub
                _db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
                   onCreate(_db);
    
            }
    
          }
        
    }
    package edu.hrbeu.contentproviderdemo;
    import android.net.Uri;
     
    public class People{
        
        public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";
        public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";
        public static final String MINE_ITEM = "vnd.hrbeu.people";
        
        public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MINE_ITEM;
        public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MINE_ITEM;
        public static final String AUTHORITY = "edu.hrbeu.peopleprovider";
        public static final String PATH_SINGLE = "people/#";
        public static final String PATH_MULTIPLE = "people";
        public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
        public static final Uri  CONTENT_URI = Uri.parse(CONTENT_URI_STRING); 
        
        public static final String KEY_ID = "_id";
        public static final String KEY_NAME = "name";
        public static final String KEY_AGE = "age";
        public static final String KEY_HEIGHT = "height";
    }

    MainActivity是空的。。。不贴出来了。

    运行结果没有任何内容,因为仅是添加了一个provider。

    看一下步骤2:

    在另一个App中调用此ContentProvider。

    无需再AndroidManifast中注册provider。

    只需对应步骤1中的People类里的静态变量是完全匹配的就是可以了。

    也就是说URI需要与我们自定义的ContentProvider保持一致。

    package edu.hrbeu.contentresolverdemo;
    import android.net.Uri;
     
    public class People{
        
        public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";
        public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";
        public static final String MINE_ITEM = "vnd.hrbeu.people";
        
        public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MINE_ITEM;
        public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MINE_ITEM;
        public static final String AUTHORITY = "edu.hrbeu.peopleprovider";
        public static final String PATH_SINGLE = "people/#";
        public static final String PATH_MULTIPLE = "people";
        public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE;
        public static final Uri  CONTENT_URI = Uri.parse(CONTENT_URI_STRING); 
        
        public static final String KEY_ID = "_id";
        public static final String KEY_NAME = "name";
        public static final String KEY_AGE = "age";
        public static final String KEY_HEIGHT = "height";
    }

    操作Contentpriver提供的数据我们需要用到ContentResolver:

    package edu.hrbeu.contentresolverdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;
    
    public class ContentResolverDemo extends Activity {
    
        private EditText nameText;
        private EditText ageText;
        private EditText heightText;
        private EditText idEntry;
    
        private TextView labelView;
        private TextView displayView;
    
        private ContentResolver resolver;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_content_resolver_demo);
            nameText = (EditText) findViewById(R.id.name);
            ageText = (EditText) findViewById(R.id.age);
            heightText = (EditText) findViewById(R.id.hight);
            idEntry = (EditText) findViewById(R.id.id);
    
            labelView = (TextView) findViewById(R.id.label);
            displayView = (TextView) findViewById(R.id.display);
            Button addButton = (Button) findViewById(R.id.button1);
            Button queryAllButton = (Button) findViewById(R.id.button2);
            Button clearButton = (Button) findViewById(R.id.button3);
            Button queryButton = (Button) findViewById(R.id.button6);
            Button deleteButton = (Button) findViewById(R.id.button5);
            Button updateButton = (Button) findViewById(R.id.button7);
    
            resolver = this.getContentResolver();
            addButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    ContentValues values = new ContentValues();
    
                    values.put(People.KEY_NAME, nameText.getText().toString());
                    values.put(People.KEY_AGE,
                            Integer.parseInt(ageText.getText().toString()));
                    values.put(People.KEY_HEIGHT,
                            Float.parseFloat(heightText.getText().toString()));
    
                    Uri newUri = resolver.insert(People.CONTENT_URI, values);
                    labelView.setText("添加成功,URI:" + newUri);
    
                }
            });
            queryAllButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Cursor cursor = resolver.query(People.CONTENT_URI,
                            new String[] { People.KEY_ID, People.KEY_NAME,
                                    People.KEY_AGE, People.KEY_HEIGHT }, null,
                            null, null);
                    if (cursor == null) {
                        labelView.setText("数据库中没有数据");
                        return;
                    }
                    labelView.setText("数据库:" + String.valueOf(cursor.getCount())
                            + "条记录");
    
                    String msg = "";
                    if (cursor.moveToFirst()) {
                        do {
                            msg += "ID:"
                                    + cursor.getInt(cursor
                                            .getColumnIndex(People.KEY_ID)) + ",";
                            msg += "姓名:"
                                    + cursor.getString(cursor
                                            .getColumnIndex(People.KEY_NAME)) + ",";
                            msg += "年龄:"
                                    + cursor.getInt(cursor
                                            .getColumnIndex(People.KEY_AGE)) + ", ";
                            msg += "身高:"
                                    + cursor.getFloat(cursor
                                            .getColumnIndex(People.KEY_HEIGHT))
                                    + "
    ";
                        } while (cursor.moveToNext());
                    }
    
                    displayView.setText(msg);
    
                }
            });
    
            clearButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    displayView.setText("");
                }
            });
    
            queryButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/"
                            + idEntry.getText().toString());
                    Cursor cursor = resolver.query(uri, new String[] {
                            People.KEY_ID, People.KEY_NAME, People.KEY_AGE,
                            People.KEY_HEIGHT }, null, null, null);
                    if (cursor == null) {
                        labelView.setText("数据库中没有数据");
                        return;
                    }
    
                    String msg = "";
                    if (cursor.moveToFirst()) {
                        msg += "ID:"
                                + cursor.getInt(cursor
                                        .getColumnIndex(People.KEY_ID)) + ",";
                        msg += "姓名:"
                                + cursor.getString(cursor
                                        .getColumnIndex(People.KEY_NAME)) + ",";
                        msg += "年龄:"
                                + cursor.getInt(cursor
                                        .getColumnIndex(People.KEY_AGE)) + ", ";
                        msg += "身高:"
                                + cursor.getFloat(cursor
                                        .getColumnIndex(People.KEY_HEIGHT)) + "
    ";
                    }
    
                    labelView.setText("数据库:");
                    displayView.setText(msg);
    
                }
            });
            deleteButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/"
                            + idEntry.getText().toString());
                    int result = resolver.delete(uri, null, null);
                    String msg = "删除ID为" + idEntry.getText().toString() + "的数据"
                            + (result > 0 ? "成功" : "失败");
                    labelView.setText(msg);
                }
            });
    
            updateButton.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    ContentValues values = new ContentValues();
                    values.put(People.KEY_NAME, nameText.getText().toString());
                    values.put(People.KEY_AGE,
                            Integer.parseInt(ageText.getText().toString()));
                    values.put(People.KEY_HEIGHT,
                            Float.parseFloat(heightText.getText().toString()));
    
                    Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/"
                            + idEntry.getText().toString());
                    int result = resolver.update(uri, values, null, null);
    
                    String msg = "更新ID为" + idEntry.getText().toString() + "的数据"
                            + (result > 0 ? "成功" : "失败");
                    labelView.setText(msg);
    
                }
            });
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.content_resolver_demo, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
            if (id == R.id.action_settings) {
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    }

    事成相识的布局文件也附上:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="edu.hrbeu.contentresolverdemo.ContentResolverDemo" >
    
        <TextView android:id="@+id/Username" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:text="用户名:">
        </TextView>
    
        <EditText
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/Username" >
    
        </EditText>
    
        <TextView android:id="@+id/Userage" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/name"
            android:text="年龄:">
        </TextView>
        <EditText android:id="@+id/age" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/Userage">
        </EditText>
        
         <TextView android:id="@+id/Userhight" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/age"
            android:text="身高:">
        </TextView>
        <EditText android:id="@+id/hight" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/Userhight">
        </EditText>
    
        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button1"
            android:layout_alignBottom="@+id/button1"
            android:layout_centerHorizontal="true"
            android:text="全部显示" />
    
        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button2"
            android:layout_alignBottom="@+id/button2"
            android:layout_alignRight="@+id/hight"
            android:text="清除显示" />
        
        <TextView android:id="@+id/Userid" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/button1"
            android:text="ID:">
        </TextView>
        <EditText android:id="@+id/id" 
            android:layout_height="wrap_content" 
            android:layout_width="fill_parent" 
            android:layout_below="@id/Userid">
        </EditText>
    
        <Button
            android:id="@+id/button6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button5"
            android:layout_alignBottom="@+id/button5"
            android:layout_alignLeft="@+id/button2"
            android:text="ID查询" />
    
        <Button
            android:id="@+id/button7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/button6"
            android:layout_alignBottom="@+id/button6"
            android:layout_alignLeft="@+id/button3"
            android:text="ID更新" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/hight"
            android:text="添加数据" />
    
        <Button
            android:id="@+id/button5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/id"
            android:layout_below="@+id/id"
            android:text="ID删除" />
    
        <TextView
            android:id="@+id/display"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/label"
            android:layout_below="@+id/label"
            android:layout_marginTop="23dp" />
    
        <TextView
            android:id="@+id/label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/button5"
            android:layout_below="@+id/button6"
            android:layout_marginTop="14dp" />
    
    </RelativeLayout>

    运行结果:

  • 相关阅读:
    WCF 第十三章 可编程站点 为站点创建操作
    WCF 第十三章 可编程站点 所有都与URI相关
    WCF 第十二章 对等网 使用自定义绑定实现消息定向
    WCF 第十三章 可编程站点 使用WebOperationContext
    Using App.Config for user defined runtime parameters
    WCF 第十三章 可编程站点
    WCF 第十三章 可编程站点 使用AJAX和JSON进行网页编程
    WCF 第十二章 总结
    WCF 第十三章 可编程站点 使用WebGet和WebInvoke
    WCF 第十三章 可编程站点 URI和UriTemplates
  • 原文地址:https://www.cnblogs.com/hongguang-kim/p/5631952.html
Copyright © 2011-2022 走看看