码迷,mamicode.com
首页 > 其他好文 > 详细

使用ContentProvider

时间:2016-06-12 02:36:45      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

转载请注明出处: http://blog.csdn.net/a992036795/article/details/51610936

一、简介:
ContentProvider 在android中的作用是对外共享数据,也就是说可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对应用中的数据进行增、删、该、查。使用ContentProvider的好处是,统一了数据的访问方式。
ContentProvider的体层实现实际是Binder。

二、使用:
一般ContentProvider的实现都是对SqliteOpenHelp的进一步包装,通过Uri映射来判断选择需要操作数据库中的那个表,并且进行增、删、改、查处理。

我们先来看以一下ContentProvider的定义:

**
 * Content providers are one of the primary building blocks of Android applications, providing
 * content to applications. They encapsulate data and provide it to applications through the single
 * {@link ContentResolver} interface. A content provider is only required if you need to share
 * data between multiple applications. For example, the contacts data is used by multiple
 * applications and must be stored in a content provider. If you don‘t need to share data amongst
 * multiple applications you can use a database directly via
 * {@link android.database.sqlite.SQLiteDatabase}.
 *
 * <p>When a request is made via
 * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
 * request to the content provider registered with the authority. The content provider can interpret
 * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
 * URIs.</p>
 *
 * <p>The primary methods that need to be implemented are:
 * <ul>
 *   <li>{@link #onCreate} which is called to initialize the provider</li>
 *   <li>{@link #query} which returns data to the caller</li>
 *   <li>{@link #insert} which inserts new data into the content provider</li>
 *   <li>{@link #update} which updates existing data in the content provider</li>
 *   <li>{@link #delete} which deletes data from the content provider</li>
 *   <li>{@link #getType} which returns the MIME type of data in the content provider</li>
 * </ul></p>
 *
 * <p class="caution">Data access methods (such as {@link #insert} and
 * {@link #update}) may be called from many threads at once, and must be thread-safe.
 * Other methods (such as {@link #onCreate}) are only called from the application
 * main thread, and must avoid performing lengthy operations.  See the method
 * descriptions for their expected thread behavior.</p>
 *
 * <p>Requests to {@link ContentResolver} are automatically forwarded to the appropriate
 * ContentProvider instance, so subclasses don‘t have to worry about the details of
 * cross-process calls.</p>
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For more information about using content providers, read the
 * <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
 * developer guide.</p>
 */
public abstract class ContentProvider implements ComponentCallbacks2 {
    private static final String TAG = "ContentProvider";

通过注释我们大概可以了解到:
我们自定义一个ContentProvider,需要实现它的onCreate、query、insert、update、delete、getType方法。
因为它底层实现是Binder、其实对源码进行分析的话、可以看到如果是夸进程调用的话,OnCreate将发生在主线程、而其他方法将发生在Binder线程池中。
这一点,我们可以通过在方法打印进程名会得到证实。

06-08 01:46:21.903 3016-3016/com.blueberry.process1 I/SimpleContentProvider: onCreate: current thread: main
06-08 01:46:21.920 3016-3032/com.blueberry.process1 I/SimpleContentProvider: insert: current thread: Binder_2
06-08 01:46:22.968 3016-3032/com.blueberry.process1 I/SimpleContentProvider: query: current thread: Binder_2

这是我写的一个例子的测试结果。下面我们将自己写一个ContentProvider。
首先我们先定义个SQLiteOpenHelp,来创建1个数据库,其中存在2张表。
下面给出类的定义:


/**
 * Created by blueberry on 2016/6/7.
 */
public class UserInfoDbHelper extends SQLiteOpenHelper {

    private static final String TAG = "UserInfoDbHelper";

    private static final String DB_NAME = "userinfo.db"; /*数据库名*/
    private static final int DB_VERSION = 1;/*版本号*/

    public static final String TABLE_USER_INFO = "userinfo";/*用户信息表*/
    public static final String TABLE_COMPANY = "company";/*公司表*/

    public static final String TEL_COLUMN = "tel_num";/*电话号码*/
    public static final String DESC_COLUMN = "desc";/*描述*/
    public static final String COMP_ID_COLUMN = "comp_id";/*公司id*/

    public static final String ID_COLUMN = "id";/*公司的id*/
    public static final String BUSINESS_COLUMN = "business";/*公司的业务*/
    public static final String ADDR_COLUMN = "addr";/*公司位置*/

    //  表 userinfo
    //  | 字段名            | 类型          |意义             |
    //  | Tel_num           | TEXT         |电话号码          |
    //  | Desc              | TEXT         |描述              |
    //  | comp_id           | INTEGER      | 公司id           |
    //

    //  表 company
    //  |字段名              |类型           |意义             |
    //  |Id                 |INTEGER        |公司的id          |
    //  |Business           | TEXT          |公司的业务        |
    //  | Addr              | TEXT          | 公司位置         |


    private static final String POSTCODE_TABLE_SQL ="CREATE TABLE IF NOT EXISTS "+TABLE_USER_INFO +" ("
            +TEL_COLUMN+" TEXT ,"
            +COMP_ID_COLUMN+" INTEGER ,"
            +DESC_COLUMN+" TEXT"
            +")" ;
    private static final String COMPANY_TABLE_SQL ="CREATE TABLE IF NOT EXISTS "+TABLE_COMPANY+" ("
            +ID_COLUMN +" INTEGER PRIMEARY KEY ,"
            +BUSINESS_COLUMN+" TEXT ,"
            +ADDR_COLUMN+" TEXT" +")" ;


    public UserInfoDbHelper(Context context) {
        super(context, DB_NAME , null, DB_VERSION);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(POSTCODE_TABLE_SQL);
        db.execSQL(COMPANY_TABLE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

可以看到创建了2张表,一张为userinfo 一张为 company。字段名已在注释列出。

下面继续给出自定一ContentProvider的定义:

/**
 * Created by blueberry on 2016/6/7.
 */
public class SimpleContentProvider extends ContentProvider {

    private static final String TAG = "SimpleContentProvider";

    public static final String AUTHORITY = "com.blueberry.test08.provider";

    /*该ContentProvider返回的数据类型定义,数据集合*/
    private static final String CONTENT_TYPE ="vnd.android.cursor.dir/vnd."+AUTHORITY;
    /*单项数据*/
    private static final String CONTNET_TYPE_ITEM ="vnd.android.cursor.item/vnd."+AUTHORITY ;

    public static final Uri USERINFO_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
            + UserInfoDbHelper.TABLE_USER_INFO);
    public static final Uri COMPANY_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
            + UserInfoDbHelper.TABLE_COMPANY);

    public static final int USERINFO_CODE = 0;
    public static final int USERINFO_ITEM_CODE = 1;
    public static final int COMPANY_CODE = 2;
    public static final int COMPANY_ITEM_CODE = 3;

    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        /**
         * 这里使用2种通配符 "*"表示匹配任意长度的任意字符,"#"表示匹配任意长度的数字
         * 因此,content://com.blueberry.test08.provider/company 表示查询company表中的所有数据
         * 而 conent://com.blueberry.test08.provider/company/# 表示根据一个数字id 查询一条信息
         */
        sUriMatcher.addURI(AUTHORITY, "userinfo", USERINFO_CODE);
        sUriMatcher.addURI(AUTHORITY, "userinfo/*", USERINFO_ITEM_CODE);
        sUriMatcher.addURI(AUTHORITY, "company", COMPANY_CODE);
        sUriMatcher.addURI(AUTHORITY, "company/#", COMPANY_ITEM_CODE);
    }

    private SQLiteDatabase mDatabase;

    /**
     * 夸进程时发生在主线程
     *
     * @return
     */
    @Override
    public boolean onCreate() {
        Log.i(TAG, "onCreate: current thread: " + Thread.currentThread().getName());
        /*返回一个可读写的数据库*/
        mDatabase = new UserInfoDbHelper(getContext()).getWritableDatabase();
        return true;
    }

    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param projection
     * @param selection
     * @param selectionArgs
     * @param sortOrder
     * @return
     */
    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Log.i(TAG, "query: current thread: " + Thread.currentThread().getName());
        Cursor cursor = null;
        switch (sUriMatcher.match(uri)) {
            case USERINFO_CODE:
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case USERINFO_ITEM_CODE:
                String tel = uri.getPathSegments().get(1);
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO, projection, "tel_num = ?", new String[]{tel}, null, null, sortOrder);
                break;
            case COMPANY_CODE:
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_COMPANY, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case COMPANY_ITEM_CODE:
                String cid = uri.getPathSegments().get(1);
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_COMPANY, projection, "id = ?", new String[]{cid}, null, null, sortOrder);
                break;
        }
        return cursor;
    }

    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param values
     * @return
     */
    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.i(TAG, "insert: current thread: " + Thread.currentThread().getName());
        long newId = 0;
        Uri newUri = null;
        switch (sUriMatcher.match(uri)) {
            case USERINFO_CODE:
                newId = mDatabase.insert(UserInfoDbHelper.TABLE_USER_INFO, null, values);
                newUri = Uri.parse("content://" + AUTHORITY + "/" + UserInfoDbHelper.TABLE_USER_INFO + "/" + newId);
                break;
            case COMPANY_CODE:
                newId = mDatabase.insert(UserInfoDbHelper.TABLE_COMPANY, null, values);
                newUri = Uri.parse("content://" + AUTHORITY + "/" + UserInfoDbHelper.TABLE_COMPANY + "/" + newId);
                break;
        }

        if (newId > 0) return newUri;
        throw new IllegalArgumentException("Failed to insert row info" + uri);
    }


    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @return
     */
    @Nullable
    @Override
    public String getType(Uri uri) {
        Log.i(TAG, "getType: current thread: " + Thread.currentThread().getName());
        switch (sUriMatcher.match(uri)){
            case USERINFO_CODE:
            case COMPANY_CODE:
                return CONTENT_TYPE;
            case USERINFO_ITEM_CODE:
            case COMPANY_ITEM_CODE:
                return CONTNET_TYPE_ITEM;
            default:
                throw new RuntimeException("错误的 uri");
        }
    }

    @Nullable
    @Override
    public Bundle call(String method, String arg, Bundle extras) {
        return super.call(method, arg, extras);
    }

    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Log.i(TAG, "delete: current thread: " + Thread.currentThread().getName());
        return 0;
    }

    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param values
     * @param selection
     * @param selectionArgs
     * @return
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        Log.i(TAG, "update: current thread: " + Thread.currentThread().getName());
        return 0;
    }
}

我这里只是测试,所以只实现了query和inser方法。这里主要用了一个 UriMatcher类。

这里对上面的程序简要分析一下:
我们先来简要看一下Uri,Uri代表了要操作的数据表的绝对路径,Uri主要包含两部分信息,一是需要操作的ContentProvider,二是对ContentProvider中的哪个表进行操作。一个Uri的组成为:
技术分享
ContentProvider的Schema已经由Android固定设置为content://, Authority用于唯一标示这个ContentProvider,外部调用者可以根据这个标示来找到它,这里的path就是要查询的数据表,最后的id是可选字段,例如,我们操作特定的数据项时就会指定一个查询条件,如果所有联系人的uri为 content://contacts/people,某个联系人的Uri:content://contacts/people/5,这个5 就是联系人的id,也就对应了查询的关键字。

这里我们的Authority为 com.blueberry.test08.provider。

接下来我们看以UriMatcher
我们来看一下这个类的定义:

/**
Utility class to aid in matching URIs in content providers.

<p>To use this class, build up a tree of <code>UriMatcher</code> objects.
For example:
<pre>
    private static final int PEOPLE = 1;
    private static final int PEOPLE_ID = 2;
    private static final int PEOPLE_PHONES = 3;
    private static final int PEOPLE_PHONES_ID = 4;
    private static final int PEOPLE_CONTACTMETHODS = 7;
    private static final int PEOPLE_CONTACTMETHODS_ID = 8;

    private static final int DELETED_PEOPLE = 20;

    private static final int PHONES = 9;
    private static final int PHONES_ID = 10;
    private static final int PHONES_FILTER = 14;

    private static final int CONTACTMETHODS = 18;
    private static final int CONTACTMETHODS_ID = 19;

    private static final int CALLS = 11;
    private static final int CALLS_ID = 12;
    private static final int CALLS_FILTER = 15;

    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static
    {
        sURIMatcher.addURI("contacts", "people", PEOPLE);
        sURIMatcher.addURI("contacts", "people/#", PEOPLE_ID);
        sURIMatcher.addURI("contacts", "people/#/phones", PEOPLE_PHONES);
        sURIMatcher.addURI("contacts", "people/#/phones/#", PEOPLE_PHONES_ID);
        sURIMatcher.addURI("contacts", "people/#/contact_methods", PEOPLE_CONTACTMETHODS);
        sURIMatcher.addURI("contacts", "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);
        sURIMatcher.addURI("contacts", "deleted_people", DELETED_PEOPLE);
        sURIMatcher.addURI("contacts", "phones", PHONES);
        sURIMatcher.addURI("contacts", "phones/filter/*", PHONES_FILTER);
        sURIMatcher.addURI("contacts", "phones/#", PHONES_ID);
        sURIMatcher.addURI("contacts", "contact_methods", CONTACTMETHODS);
        sURIMatcher.addURI("contacts", "contact_methods/#", CONTACTMETHODS_ID);
        sURIMatcher.addURI("call_log", "calls", CALLS);
        sURIMatcher.addURI("call_log", "calls/filter/*", CALLS_FILTER);
        sURIMatcher.addURI("call_log", "calls/#", CALLS_ID);
    }
</pre>
<p>Starting from API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, paths can start
 with a leading slash.  For example:
<pre>
        sURIMatcher.addURI("contacts", "/people", PEOPLE);
</pre>
<p>Then when you need to match against a URI, call {@link #match}, providing
the URL that you have been given.  You can use the result to build a query,
return a type, insert or delete a row, or whatever you need, without duplicating
all of the if-else logic that you would otherwise need.  For example:
<pre>
    public String getType(Uri url)
    {
        int match = sURIMatcher.match(url);
        switch (match)
        {
            case PEOPLE:
                return "vnd.android.cursor.dir/person";
            case PEOPLE_ID:
                return "vnd.android.cursor.item/person";
... snip ...
                return "vnd.android.cursor.dir/snail-mail";
            case PEOPLE_ADDRESS_ID:
                return "vnd.android.cursor.item/snail-mail";
            default:
                return null;
        }
    }
</pre>
instead of:
<pre>
    public String getType(Uri url)
    {
        List<String> pathSegments = url.getPathSegments();
        if (pathSegments.size() >= 2) {
            if ("people".equals(pathSegments.get(1))) {
                if (pathSegments.size() == 2) {
                    return "vnd.android.cursor.dir/person";
                } else if (pathSegments.size() == 3) {
                    return "vnd.android.cursor.item/person";
... snip ...
                    return "vnd.android.cursor.dir/snail-mail";
                } else if (pathSegments.size() == 3) {
                    return "vnd.android.cursor.item/snail-mail";
                }
            }
        }
        return null;
    }
</pre>
*/
public class UriMatcher
{

可以看到,注释中已经把他的用法说的查不到了。
UriMather 会根据uri来匹配出对应的 code来使得我们判断该查询那张表,

这里我们定义了四个 code. 分别对用与 用户信息查询、单个用户信息查询、公司查询、单个公司查询。

 public static final int USERINFO_CODE = 0;
    public static final int USERINFO_ITEM_CODE = 1;
    public static final int COMPANY_CODE = 2;
    public static final int COMPANY_ITEM_CODE = 3;

我们通过如下方法将 对应信息添加进去:


    static {
        /**
         * 这里使用2种通配符 "*"表示匹配任意长度的任意字符,"#"表示匹配任意长度的数字
         * 因此,content://com.blueberry.test08.provider/company 表示查询company表中的所有数据
         * 而 conent://com.blueberry.test08.provider/company/# 表示根据一个数字id 查询一条信息
         */
        sUriMatcher.addURI(AUTHORITY, "userinfo", USERINFO_CODE);
        sUriMatcher.addURI(AUTHORITY, "userinfo/*", USERINFO_ITEM_CODE);
        sUriMatcher.addURI(AUTHORITY, "company", COMPANY_CODE);
        sUriMatcher.addURI(AUTHORITY, "company/#", COMPANY_ITEM_CODE);
    }

我们接着来看一下getType方法,根据UriMather推荐的方法,如果查询的是数据集合, 我们返回的类型应该是 vnd.android.cursor.dir/….. 如果是查询单个数据我们返回的类型应该是 vnd.android.cursor.item/….

  /*该ContentProvider返回的数据类型定义,数据集合*/
    private static final String CONTENT_TYPE ="vnd.android.cursor.dir/vnd."+AUTHORITY;
    /*单项数据*/
    private static final String CONTNET_TYPE_ITEM ="vnd.android.cursor.item/vnd."+AUTHORITY ;


 /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @return
     */
    @Nullable
    @Override
    public String getType(Uri uri) {
        Log.i(TAG, "getType: current thread: " + Thread.currentThread().getName());
        switch (sUriMatcher.match(uri)){
            case USERINFO_CODE:
            case COMPANY_CODE:
                return CONTENT_TYPE;
            case USERINFO_ITEM_CODE:
            case COMPANY_ITEM_CODE:
                return CONTNET_TYPE_ITEM;
            default:
                throw new RuntimeException("错误的 uri");
        }
    }

接着来看 他的query 和 insert方法:

 /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param projection
     * @param selection
     * @param selectionArgs
     * @param sortOrder
     * @return
     */
    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Log.i(TAG, "query: current thread: " + Thread.currentThread().getName());
        Cursor cursor = null;
        switch (sUriMatcher.match(uri)) {
            case USERINFO_CODE:
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case USERINFO_ITEM_CODE:
                String tel = uri.getPathSegments().get(1);
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_USER_INFO, projection, "tel_num = ?", new String[]{tel}, null, null, sortOrder);
                break;
            case COMPANY_CODE:
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_COMPANY, projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case COMPANY_ITEM_CODE:
                String cid = uri.getPathSegments().get(1);
                cursor = mDatabase.query(UserInfoDbHelper.TABLE_COMPANY, projection, "id = ?", new String[]{cid}, null, null, sortOrder);
                break;
        }
        return cursor;
    }

    /**
     * 夸进程时发生在工作线程
     *
     * @param uri
     * @param values
     * @return
     */
    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.i(TAG, "insert: current thread: " + Thread.currentThread().getName());
        long newId = 0;
        Uri newUri = null;
        switch (sUriMatcher.match(uri)) {
            case USERINFO_CODE:
                newId = mDatabase.insert(UserInfoDbHelper.TABLE_USER_INFO, null, values);
                newUri = Uri.parse("content://" + AUTHORITY + "/" + UserInfoDbHelper.TABLE_USER_INFO + "/" + newId);
                break;
            case COMPANY_CODE:
                newId = mDatabase.insert(UserInfoDbHelper.TABLE_COMPANY, null, values);
                newUri = Uri.parse("content://" + AUTHORITY + "/" + UserInfoDbHelper.TABLE_COMPANY + "/" + newId);
                break;
        }

        if (newId > 0) return newUri;
        throw new IllegalArgumentException("Failed to insert row info" + uri);
    }

可以看到,利用UriMatcher得到要怎样查询,然后代用了 database的方法。

最后说一个方法:

 @Nullable
    @Override
    public Bundle call(String method, String arg, Bundle extras) {
        return super.call(method, arg, extras);
    }

可以利用这个方法,扩展出一些查询方式。

最后我们来看以下在清单文件中的注册:

  <provider
            android:authorities="com.blueberry.test08.provider"
            android:name=".SimpleContentProvider"
            android:permission="com.blueberry.permission.provider"
            android:process="com.blueberry.process1"
            android:multiprocess="false"
            >

        </provider>

这里主要的字段为 authorities ,他是ContentProvider的唯一标识。
permission,它分为 读权限,和写权限 对应为 android:readpermission 和
android:writepermission 。 multiprocess如果设置为true标识每个调用进程都拥有一个示例,负责只有所有进程只有一个示例。process字段使得它运行在一个名为com.blueberry.process1的进程中。

最后我们来看一下调用程序:

public class MainActivity extends AppCompatActivity {

    private EditText etUserDesc,etUserPhoneNumber,etUserCompanyId;
    private EditText etCompanyId,etCompanyBussiness,etCompanyAddress ;
    private Button btnSubmitUserInfo,btnSubmitCompany;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etUserDesc = (EditText) findViewById(R.id.et_user_desc);
        etUserPhoneNumber = (EditText) findViewById(R.id.et_user_phone_number);
        etUserCompanyId = (EditText) findViewById(R.id.et_user_company_id);

        etCompanyId = (EditText) findViewById(R.id.et_company_id);
        etCompanyBussiness  = (EditText) findViewById(R.id.et_company_bussiness);
        etCompanyAddress = (EditText) findViewById(R.id.et_company_address);

        btnSubmitUserInfo = (Button) findViewById(R.id.btn_save_userinfo);
        btnSubmitCompany = (Button) findViewById(R.id.btn_save_company);

        btnSubmitUserInfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //存数用户信息数据
                saveUserInfoRecord();
                btnSubmitUserInfo.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        queryUserInfo();
                    }
                },1000);
            }
        });


        btnSubmitCompany.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                saveCompanyInfo();
                btnSubmitCompany.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      queryCompanyInfo();
                    }
                },1000) ;
            }
        });
    }

    /**
     * 通过电话号码查询相关信息
     */
    private void queryUserInfo() {
        Uri queryUri = Uri.parse("content://com.blueberry.test08.provider/userinfo/123456") ;
        Cursor cursor = getContentResolver().query(queryUri,
                new String[]{UserInfoDbHelper.DESC_COLUMN,UserInfoDbHelper.COMP_ID_COLUMN,UserInfoDbHelper.TEL_COLUMN}
                ,null,null,null);
        if(cursor.moveToFirst()){
            Toast.makeText(this,
                    " 描述信息"+cursor.getString(0)
                    +" 公司id"+cursor.getString(1)
                    +" 电话来自"+cursor.getString(2),Toast.LENGTH_SHORT).show();
        }
        cursor.close();
    }

    /**
     * 存储用户信息到ContentProvider
     */
    private void saveUserInfoRecord() {
        ContentValues newRecord = new ContentValues();
        newRecord.put(UserInfoDbHelper.DESC_COLUMN,etUserDesc.getText().toString());
        newRecord.put(UserInfoDbHelper.COMP_ID_COLUMN,etUserCompanyId.getText().toString());
        newRecord.put(UserInfoDbHelper.TEL_COLUMN,etUserPhoneNumber.getText().toString());
        getContentResolver().insert(SimpleContentProvider.USERINFO_CONTENT_URI,newRecord) ;
    }

    private void saveCompanyInfo() {
        ContentValues newRecord = new ContentValues();
        newRecord.put(UserInfoDbHelper.ID_COLUMN,etCompanyId.getText().toString());
        newRecord.put(UserInfoDbHelper.BUSINESS_COLUMN,etCompanyBussiness.getText().toString());
        newRecord.put(UserInfoDbHelper.ADDR_COLUMN,etCompanyAddress.getText().toString());
        getContentResolver().insert(SimpleContentProvider.COMPANY_CONTENT_URI,newRecord);
    }

    private void queryCompanyInfo(){
        Cursor cursor = getContentResolver().query(SimpleContentProvider.COMPANY_CONTENT_URI,
                new String[]{UserInfoDbHelper.ID_COLUMN,UserInfoDbHelper.BUSINESS_COLUMN,UserInfoDbHelper.ADDR_COLUMN}
                ,null,null,null);
        StringBuffer sb = new StringBuffer();
        while (cursor.moveToNext()){
            sb.append("id: "+cursor.getString(0)+" business: "+cursor.getString(1)+" address: "+cursor.getString(2));
            sb.append("\n");
        }
        Toast.makeText(this,sb.toString(),Toast.LENGTH_LONG).show();
    }
}

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="com.blueberry.test08.MainActivity">


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_user_desc"
        android:hint="请输入用户描述信息"
        android:contentDescription="用户描述信息"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_user_phone_number"
        android:hint="输入用户电话号码"
        android:contentDescription="用户电话号码"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_user_company_id"
        android:hint="用户公司id"
        android:contentDescription="用户公司id"
        />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btn_save_userinfo"
        android:text="存储用户信息"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_company_id"
        android:hint="公司id"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_company_bussiness"
        android:hint="请输入公司业务"
        android:contentDescription="公司业务"
        />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_company_address"
        android:hint="请输入公司地址"
        android:contentDescription="请输入公司地址"
        />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btn_save_company"
        android:text="保存公司信息"
        />
</LinearLayout>

技术分享

使用ContentProvider

标签:

原文地址:http://blog.csdn.net/a992036795/article/details/51610936

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!