ContentProvider及AsnycQueryHandler的使用

1、ContentProvider的基本概念

     1> ContentProvider为存储和读取数据提供了统一的接口

     2> 使用ContentProvider,应用程序可以实现数据共享

     3> android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)

2、Uri

     1> 每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据

     2> Android所提供的ContentProvider都存放在andriod.provider这个包里面

3、ContentProvider提供的函数

     1> query() 查询

     2> insert() 插入

     3> update() 更新

     4> delete() 删除

   5> getType() 得到数据类型

     6> onCreate() 创建时的回调函数

4、实现ContentProvider的过程

    1> 定义一个COTENT_URI常量

    2> 定义一个类,继承ContentProvider

    3> 实现query(),delete(),update(),insert(),onCreate(),getType()方法

    4> 在AndroidMainfest.xml中申明

下面以两个实例(一个是ContentProvider所在的应用,另一个是使用ContentProvider的应用),说明如何使用ContentProvider

5、ContentProvider所在的应用

1>定义一个类,里面定义一些常量

package com.dxt;

import android.net.Uri;
import android.provider.BaseColumns;

public class MyUsers {
    
    public static final String AUTHORITY = "com.dxt.MyContentProvider";
//    <provider android:name=".android.MyContentProvider" android:authorities="com.dxt.android.MyContentProvider" /> 
    
    //BaseColumn类中已经包含了_id字段
    public static final class User implements BaseColumns
    {
        //定义Uri
        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
        //定义数据表列
        public static String USER_NAME = "_Name";
    	public static String USER_TEL = "_Tel";
    }

}

2>定义一个继承ContentProvider的子类,实现其方法


package com.dxt;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.util.Log;


/*
 * MyContentProvider继承ContentProvider类,实现其insert,update,delete,getType,onCreate等方法
 */
public class MyContentProvider extends ContentProvider {

    //定义一个SQLiteDatabase变量
    private SQLiteDatabase sqlDB;
    //定义一个DatabaseHelper变量
    private DatabaseHelper dbHelper;
    //数据库名
    private static final String DATABASE_NAME = "Users.db";
    //数据库版本
    private static final int DATABASE_VERSION = 1;
    //表名
    private static final String TABLE_NAME = "User";
    
    //标签
    private static final String TAG = "MyContentProvider";

    /*
     * 定义一个内部类
     * 
     * 这个内部类继承SQLiteOpenHelper类,重写其方法
     */
    public static class DatabaseHelper extends SQLiteOpenHelper {

        //构造方法
        public DatabaseHelper(Context context) {
            //父类构造方法
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        //当第一次创建数据库的时候调用该方法,可以为数据库增加一些表,和初始化一些数据
        @Override
        public void onCreate(SQLiteDatabase db) {
            //在数据库里生成一张表
        	String sql = "CREATE TABLE IF NOT EXISTS "
    				+ TABLE_NAME
    				+ " (_id integer primary key autoincrement, "+MyUsers.User.USER_NAME+" text, "+MyUsers.User.USER_TEL+" text);";
    		db.execSQL(sql);
    		Log.d(TAG, "DatabaseHelper--->oncreate");
//            db.execSQL("Create table "
//                    + TABLE_NAME
//                    + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);");
        }

        //当更新数据库版本的时候,调用该方法。可以删除,修改表的一些信息
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);

        }

    }

    //这是一个回调函数,当生成所在类的对象时,这个方法被调用,创建一个数据库
    @Override
    public boolean onCreate() {
        dbHelper = new DatabaseHelper(getContext());
        return (dbHelper == null) ? false : true;
    }

    //查询
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
  SQLiteDatabase db = dbHelper.getReadableDatabase();  
//      qb.setTables(TABLE_NAME);  
      Cursor c = db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);  
//      query(USER_TABLE, null,null, null, null, null, " _id desc");//asc  desc  
      c.setNotificationUri(getContext().getContentResolver(), uri);  
      Log.d(TAG, "query----->"+c.getCount());  
      db.close();
        return c;
    }

    //取得类型
    @Override
    public String getType(Uri uri) {
        return null;
    }

    //插入数据
    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) {
         SQLiteDatabase db = dbHelper.getWritableDatabase();  
        long rowId = db.insert(TABLE_NAME, "", contentvalues);
        db.close();
        if (rowId > 0) {
            Uri rowUri = ContentUris.appendId(
                    MyUsers.User.CONTENT_URI.buildUpon(), rowId).build();
            getContext().getContentResolver().notifyChange(rowUri, null);
            Log.d(TAG, "insert----->" + rowUri);
            return rowUri;
        }
        throw new SQLException("Failed to insert row into" + uri);
    }

    //删除数据
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
    	SQLiteDatabase db = dbHelper.getReadableDatabase(); 
         int rowId = db.delete(TABLE_NAME, selection, selectionArgs);  
         Log.i(TAG, "delete item && row id = " + rowId);  
         db.close();
        return rowId;
    }

    //更新数据
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
   SQLiteDatabase db = dbHelper.getWritableDatabase();
        int rows = db.update(TABLE_NAME, values, selection, selectionArgs);
        db.close();
		Log.i(TAG, "update item && rows = " + rows);

        return rows;
    }

}


3>定义一个默认加载的Activity,里面对ContentProvider进行数据加载

package com.dxt;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.util.Log;import android.widget.Toast;public class MyContentDemo extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        for (int i = 0; i < 500; i++) {            insertRecord("name"+ i,"100000000"+i);        }//        insertRecord("MyUser","100000000");//        insertRecord("YangYuLin","222222222");        displayRecords();    }    private void insertRecord(String userName,String telephone) {        ContentValues values = new ContentValues();        values.put(MyUsers.User.USER_NAME, userName);        values.put(MyUsers.User.USER_TEL, telephone);        getContentResolver().insert(MyUsers.User.CONTENT_URI, values);    }    private void displayRecords() {        String columns[] = new String[] { MyUsers.User._ID,                MyUsers.User.USER_NAME ,MyUsers.User.USER_TEL};        Uri myUri = MyUsers.User.CONTENT_URI;        Cursor cur = managedQuery(myUri, columns, null, null, null);        if (cur.moveToFirst()) {            String id = null;            String userName = null;            String tel = null;            do {                id = cur.getString(cur.getColumnIndex(MyUsers.User._ID));                userName = cur.getString(cur                        .getColumnIndex(MyUsers.User.USER_NAME));                tel = cur.getString(cur.getColumnIndex(MyUsers.User.USER_TEL));//                Toast.makeText(this, id + " " + userName + " " + tel, Toast.LENGTH_LONG)//                        .show();                Log.d("tag", "name = " + userName + "\ntel = " + tel);            } while (cur.moveToNext());        }    }}

4>在AndroidMainfest.xml里注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.dxt"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <provider android:name=".MyContentProvider" android:authorities="com.dxt.MyContentProvider" />
        <activity android:name="com.dxt.MyContentDemo"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest> 

6、做另一个App.使用上面ContentProvider提供的数据

package com.CPClientActitity.dxt;

import android.app.Activity;
import android.os.Bundle;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class CPClientActitity extends Activity {
   
    public static final String AUTHORITY = "com.dxt.MyContentProvider";    
    private Button insertButton = null;
    //访问ContentProvider的Uri
    Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        //得到ContentProvider对于表的所有数据,以游标格式保存
//        Cursor c = managedQuery(CONTENT_URI,new String[]{"_id","_Name","_Tel"},null,null,null);
        Cursor c = getContentResolver().query(CONTENT_URI, null, null,null, "_id desc");
        //循环打印ContentProvider的数据
        if(c.moveToFirst())
        {
            String _id = null;
            String user_name = null;
            String tel_num = null;
            do
            {
                //得到_id列,USER_NAME列
                _id = c.getString(c.getColumnIndex("_id"));
                user_name = c.getString(c.getColumnIndex("_Name"));
                tel_num = c.getString(c.getColumnIndex("_Tel"));
                Log.d("tag", "_id = " + _id +", _Name = " + user_name + "_Tel = " + tel_num);
                
            }while(c.moveToNext());
        }

  Toast.makeText(getApplicationContext(), "数据添加完成!!!", Toast.LENGTH_SHORT).show();
        if(c != null){
            Toast.makeText(getApplicationContext(), "cursor已经关闭了啊 !!!", Toast.LENGTH_SHORT).show();
            c.close();
        }
        
        //根据Id得到控件对象
        insertButton = (Button)findViewById(R.id.Insert);
        //给按钮绑定事件监听器
        insertButton.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                
                //得到EditText输入的数据
                String username = ((EditText)findViewById(R.id.userName)).getText().toString();
                String tel_num = ((EditText)findViewById(R.id.tel_num)).getText().toString();
                //生成一个ContentResolver对象
                ContentResolver cr = getContentResolver();
                //生成一个ContentValues对象
                ContentValues values = new ContentValues();
                //将EditText输入的值,保存到ContentValues对象中
                values.put("_Name", username);
                values.put("_Tel", tel_num);
                //插入数据
                cr.insert(CONTENT_URI, values);
               
            }
        });
    }
}


文章出处:http://www.cnblogs.com/-cyb/articles/2098338.html

AsyncQuerHandler 下一篇进行讲解



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值