Android ContentProvider学习

来源:互联网 发布:js 隐藏鼠标 编辑:程序博客网 时间:2024/05/22 16:50

ContentProvider介绍:

Android ContentProvider是数据对外的接口,我们只需通过使用ContentProvider访问数据而不需要关心数据具体的存储及访问过程,这样既提高了数据的访问效率,同时也保护了数据。Activity类中有一个继承自ContentWapper的getContentResolver()无参数方法,该方法返回一个ContentResolver对象,通过调用其query、insert、update、delete方法访问数据。这几个方法的第一个参数均为URI型,用来标识资源。

总结:
1、ContentProvider为存储和读取数据提供了统一的接口
2、使用ContentProvider,应用程序可以实现数据共享
3、android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)

Uri介绍:

1、每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据
2、Android所提供的ContentProvider都存放在andriod.provider这个包里面

Android的ContentProviderURI有固定的形式:content://contract/people

前缀:固定为content: //
认证:contract资源的唯一标识符
路径:people具体的资源类型

在Android中广泛应用URI,而不是URL。URL标识资源的物理位置,相当于文件的路径;而URI则是标识资源的逻辑位置,并不提供资源的具体位置。比如说电话薄中的数据,如果用URL来标识的话,可能会是一个很复杂的文件结构,而且一旦文件的存储路径改变,URL也必须得改动。但是若是URI,则可以用诸如content://contract/people这样容易记录的逻辑地址来标识,而且并不需要关心文件的具体位置,即使文件位置改动也不需要做变化,当然这都是对于用户来说,后台程序中URI到具体位置的映射还是需要程序员来改动的。

ContentProvider提供的函数:

1、query()查询
2、insert()插入
3、update()更新
4、delete() 删除
5、getType()得到数据类型
6、onCreate()创建时的回调函数

实现ContentProvider的过程:

1、定义一个COTENT_URI常量
2、定义一个类,继承ContentProvider
3、实现query(),delete(),update(),insert(),onCreate(),getType()方法
4、在AndroidMainfest.xml中申明

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

ContentProvider所在的应用

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

package com.yyl.android;

  

import android.net.Uri;

import android.provider.BaseColumns;

  

public class MyUsers {

  

    public static final String AUTHORITY = "com.yyl.android.MyContentProvider";

  

    // BaseColumn类中已经包含了_id字段

    public static final class User implements BaseColumns {

        // 定义Uri

        public static final Uri CONTENT_URI = Uri.parse("content://"

                + AUTHORITY);

        // 定义数据表列

        public static final String USER_NAME = "USER_NAME";

    }

  

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

package com.yyl.android;

  

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;

  

/**

 * 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) {

            // 在数据库里生成一张表

            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) {

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        SQLiteDatabase db = dbHelper.getReadableDatabase();

        qb.setTables(TABLE_NAME);

        Cursor c = qb.query(db, projection, selection, null, null, null,

                sortOrder);

        c.setNotificationUri(getContext().getContentResolver(), uri);

        return c;

    }

  

    // 取得类型

    @Override

    public String getType(Uri uri) {

        return null;

    }

  

    // 插入数据

    @Override

    public Uri insert(Uri uri, ContentValues contentvalues) {

        sqlDB = dbHelper.getWritableDatabase();

        long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues);

        if (rowId > 0) {

            Uri rowUri = ContentUris.appendId(

                    MyUsers.User.CONTENT_URI.buildUpon(), rowId).build();

            getContext().getContentResolver().notifyChange(rowUri, null);

            return rowUri;

        }

        throw new SQLException("Failed to insert row into" + uri);

    }

  

    // 删除数据

    @Override

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

        return 0;

    }

  

    // 更新数据

    @Override

    public int update(Uri uri, ContentValues values, String selection,

            String[] selectionArgs) {

        return 0;

    }

  

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

package com.yyl;

  

import com.yyl.android.MyUsers;

import android.app.Activity;

import android.content.ContentValues;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.widget.Toast;

  

public class MyContentDemo extends Activity {

  

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        insertRecord("MyUser");

        insertRecord("YangYuLin");

        displayRecords();

    }

  

    private void insertRecord(String userName) {

        ContentValues values = new ContentValues();

        values.put(MyUsers.User.USER_NAME, userName);

        getContentResolver().insert(MyUsers.User.CONTENT_URI, values);

    }

  

    private void displayRecords() {

        String columns[] = new String[] { MyUsers.User._ID,

                MyUsers.User.USER_NAME };

        Uri myUri = MyUsers.User.CONTENT_URI;

        Cursor cur = managedQuery(myUri, columns, null, null, null);

        if (cur.moveToFirst()) {

            String id = null;

            String userName = null;

            do {

                id = cur.getString(cur.getColumnIndex(MyUsers.User._ID));

                userName = cur.getString(cur

                        .getColumnIndex(MyUsers.User.USER_NAME));

                Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG)

                        .show();

            } while (cur.moveToNext());

        }

    }

}

4、在AndroidMainfest.xml里注册

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.yyl" android:versionCode="1" android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <provider android:name=".android.MyContentProvider"

            android:authorities="com.yyl.android.MyContentProvider" />

        <activity android:name=".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>

    <uses-sdk android:minSdkVersion="7" />

</manifest>

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

package yyl.client;

  

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.view.View;

import android.widget.Button;

import android.widget.EditText;

  

public class CPClientActitity extends Activity {

  

    public static final String AUTHORITY = "com.yyl.android.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", "USER_NAME" }, null, null, null);

  

        // 循环打印ContentProvider的数据

        if (c.moveToFirst()) {

            String _id = null;

            String user_name = null;

  

            do {

                // 得到_id列,USER_NAME列

                _id = c.getString(c.getColumnIndex("_id"));

                user_name = c.getString(c.getColumnIndex("USER_NAME"));

  

                System.out.println("_id = " + _id + ", user_name = "

                        + user_name);

  

            } while (c.moveToNext());

        }

  

        // 根据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();

                // 生成一个ContentResolver对象

                ContentResolver cr = getContentResolver();

                // 生成一个ContentValues对象

                ContentValues values = new ContentValues();

                // 将EditText输入的值,保存到ContentValues对象中

                values.put("USER_NAME", username);

                // 插入数据

                cr.insert(CONTENT_URI, values);

            }

        });

    }

}