Android学习五:Content Provider 使用
1ContentProvider相关知识
1.1在安卓应用中,通过文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。可以看出虽然它们 可以对外共享数据,但数据访问方式会因数据存储的方式而不同。
在安卓中使用ContentProvider共享数据在不同的应用程序之间共享数据,底层的操作是透明的,对外提供统一接口,并可以让其它应用轻松访问该数据。
1.2ContentProvider使用表的形式来组织数据,无论数据的来源是什么,都会认为是一种表,然后把数据组织成表格。并且提供了查询(query)、插入(insert)、更新(update)、删除(delete)、获取数据类型(getType)以及创建数据时调用的回调函数(onCreate)等操作。另外每个ContentProvider都有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。Android所提供的ContentProvider都存放在android.provider包当中。
2代码
2.1访问系统中的联系人
public class MainActivity extends Activity { private ListView listView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView) this.findViewById(R.id.listView); // 查询系统中的所有联系人 Uri uri = Uri.parse("content://com.android.contacts/contacts"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); // 根据Cursor创建SimpleCursorAdapter对象 SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, new String[] { ContactsContract.Contacts.DISPLAY_NAME }, new int[] { android.R.id.text1 }, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); // 在ListVIew中显示联系人列表 listView.setAdapter(simpleCursorAdapter); } }
同时需要在清单文件加入访问通讯许可请求
<uses-permission android:name="android.permission.READ_CONTACTS" />
2.2程序的Content Provider
这个例子是对数据库实现的操作,数据库的操作是上一篇中的内容
数据库操作类
public class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(Context context) { /** * postgrade.db 数据库的名字 ;null 表示使用默认的游标工厂 ;1 表示一开始的版本,建议设置为1 */ super(context, "postgrade.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { // 该方法在第一次创建数据库的时候被调用 // 因此可以在这个地方创建表之类的操作 db.execSQL("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 修改数据库的版本会触发此函数 // 在这里可以添加新的表或者修改表的字段 } }
自定义的content provider
public class StuProvider extends ContentProvider { private DBOpenHelper dbOpenHelper = null; private static final UriMatcher MATCHER; private static final int STU = 0;// 匹配成功后的返回值 private static final String AUTHORITY;// 域名[主机名] private static final String STUDENT;// 路径名 static { // 在不匹配的时候,返回-1,即UriMatcher.NO_MATCH MATCHER = new UriMatcher(UriMatcher.NO_MATCH); AUTHORITY = "org.tonny.providers.stuprovider"; STUDENT = "student"; MATCHER.addURI(AUTHORITY, STUDENT, STU); } @Override public boolean onCreate() { // 在创建实例的时候调用,只会被调用一次;用作数据的初始化操作 dbOpenHelper = new DBOpenHelper(getContext()); return false; } @Override public String getType(Uri uri) { // 返回当前要操作的数据的内容类型如txt-->plain/text html -->html/text return null; } @Override public Uri insert(Uri uri, ContentValues values) { // 允许外部的应用向内容提供者插入数据 SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); switch (MATCHER.match(uri)) { case STU: // 調用自身的方法,第二個參數爲插入空值时候的列名 long rowId = db.insert("student", null, values); Uri insertUri = ContentUris.withAppendedId(uri, rowId); // 也可以使用这种方式 // Uri insertUri = // Uri.parse("content://org.tonny.test.providers.stuprovider/student/"+ // rowId); return insertUri; default: throw new IllegalArgumentException("This is an unknown Uri:" + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } }
model层
package org.tonny.domain; public class Student { private int id; private String name; public Student() { } public Student(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
表相关操作
public class StudentService { private DBOpenHelper dbHelper = null; public StudentService(Context context) { this.dbHelper = new DBOpenHelper(context); } public void insert(Student stu) { // 内部有緩存功能,使用的是同一個句柄,如果数据库满了,则返回一个只读的句柄 SQLiteDatabase db = dbHelper.getWritableDatabase(); // 使用占位符號‘?’,防止特殊字符 db.execSQL("INSERT INTO student VALUES(?,?)", new Object[] { stu.getId(), stu.getName() }); } public void delete(Integer id) { SQLiteDatabase db = dbHelper.getReadableDatabase(); db.execSQL("DELETE FROM student WHERE id = ?", new String[] { String.valueOf(id) }); } public void update(Student stu) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.execSQL("UPDATE student SET name = ? WHERE id = ?", new String[] { stu.getName(), String.valueOf(stu.getId()) }); } public Student query(Integer id) { SQLiteDatabase db = dbHelper.getReadableDatabase(); String sql = "SELECT * FROM student WHERE id = ?"; Cursor cursor = db.rawQuery(sql, new String[] { String.valueOf(id) }); if (cursor.moveToFirst()) { int stuId = cursor.getInt(cursor.getColumnIndex("id")); String stuName = cursor.getString(cursor.getColumnIndex("name")); return new Student(stuId, stuName); } return null; } }
activity操作
public class MainActivity extends Activity { private EditText _txtId = null; private EditText _txtName = null; private StudentService _service = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); _txtId = (EditText) this.findViewById(R.id.txtId); _txtName = (EditText) this.findViewById(R.id.txtName); _service = new StudentService(getApplicationContext()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void onBtnOK(View v) { int id = Integer.valueOf(_txtId.getText().toString()); String name = _txtName.getText().toString(); Student stu = new Student(id, name); _service.insert(stu); } }
清单文件中对uri的说明
<provider android:name="org.tonny.db.StuProvider" android:authorities="org.tonny.providers.stuprovider" android:exported="true" tools:ignore="ExportedContentProvider" />
3.总结
到今天,已经感觉是时候去找些业务研究研究了