Android组件之contentProvider
来源:互联网 发布:app推荐软件 编辑:程序博客网 时间:2024/05/29 04:51
先上文档contentProvider
啥都不说,我们先到文档中查看
文档大致是这么说的:
ContentProvider是android应用程序的构建基础之一,它们封装数据并通过单一的ContentResolver接口提供给应用程序,如果你想要在多个应用程序之间共享数据,ContentProvider是必须需要的,例如,联系人数据由多个应用程序使用,必须存储在内容提供者中。如果不需要在多个应用程序之间共享数据,那么可以通过SQLiteDatabase直接使用数据库
当请求通过ContentResolver完成时,系统将检查给定URI的权限,并将请求传递给在权限内注册的内容提供者。内容提供程序可以解释它想要的其他URI。UriMatcher类有助于解析uri。
在使用ContentProvider时,我们需要继承一下几个方法
1. onCreate()
2.query(Uri, String[], String, String[], String)
3.insert(Uri, ContentValues)
4update(Uri, ContentValues, String, String[])
5.delete(Uri, String, String[])
6.getType(Uri)
ps:数据访问方法(如insert(Uri,ContentValues)和 update(Uri,ContentValues,String,String[]))可以同时从多个线程调用,而且必须是线程安全的
oncreate()方法必须在主线程中被调用
下面我们一个一个搞他们
1.oncreate()
在这里我们对ContentProvider进行初始化,在这里我们不能执行耗时操作,如果我们使用数据库,通常在这里我们使用DatabaseHelper来创建数据库的帮助类,成功返回true
2.query()
在这我们去处理客户端发送的请求命令。
3.insert()
处理插入请求,在调用之后,需要调用notifyChange()通知数据更改
4.update()
处理更新请求,通过selection和selectArgs参数约束更新行,需要调用notifyChange()通知数据更改
5.delete()
处理删除请求,通过selection和selectArgs参数约束更新行,需要调用notifyChange()通知数据更改
6.getType()
用于获取Uri对象所对应的MIME类型,一个内容Uri所对应的MIME字符串有以下三部分组成
1.必须以vnd开头
2如果内容Uri以路径结尾,最后接android.curosr.dir/,如果以id结尾,
最后接android.cursor.item/
3之后接上vnd.< authority>.< path>
所以,对于contnent://com.example.myapplication/table1
这个Uri就可以写成 vnd.android.curosr.dir/vnd.com.example.myapplication.table1
对于contnent://com.example.myapplication/table1/1就可以写成
vnd.android.cursor.item/vnd.com.example.myapplicaion.table1
现在我们来具体实现一下
创建数据库帮助类
package com.example.myapplication;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * Created by fang on 2017/11/13. */public class MyDatabaseHelper extends SQLiteOpenHelper { String create="create table book(id integer primary key autoincrement,name text,price real,author text)"; public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(create); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
创建ContentProvider
package com.example.myapplication;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.util.Log;/** * Created by fang on 2017/11/13. */public class MyContentProvider extends ContentProvider { String TAG = "TAG"; MyDatabaseHelper helper; public static UriMatcher uriMatcher; public static final int BOOK_DIR = 0; public static final int BOOK_ITEM = 1; public static final String AUTHORITY = "com.example.myapplication"; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR); uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM); } @Override public boolean onCreate() { helper = new MyDatabaseHelper(getContext(), "bookStore.db", null, 1); return true; } @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { SQLiteDatabase database = helper.getReadableDatabase(); Cursor cursor = null; switch (uriMatcher.match(uri)) { case BOOK_DIR: { cursor = database.query("book", projection, selection, selectionArgs, null, null, sortOrder); break; } case BOOK_ITEM: { String id = uri.getPathSegments().get(1); //getPathSegments()返回的是将Path部分的内容按照"/"分割并转成List集合,get(1)返回ID Log.d(TAG, "id=" + id + " path=" + uri.getPathSegments().get(0)); cursor = database.query("book", projection, "id=?", new String[]{id}, null, null, sortOrder); break; } } return cursor; } @Nullable @Override public String getType(@NonNull Uri uri) { switch (uriMatcher.match(uri)) { case BOOK_DIR: { return "vnd.android.cursor.dir/vnd.com.example.myapplication.book"; } case BOOK_ITEM: { return "vnd.android.cursor.item/vnd.com.example.myapplication.book"; } } return null; } /** * c插入数据,并不需要ID,同一张表,一次插入就行 * * @param uri * @param values * @return */ @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { SQLiteDatabase database = helper.getWritableDatabase(); Uri uriId = null; switch (uriMatcher.match(uri)) { case BOOK_DIR: case BOOK_ITEM: long newbookId = database.insert("book", null, values); uriId = Uri.parse("content://" + AUTHORITY + "/book/" + newbookId); break; } return uriId; } @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { SQLiteDatabase database = helper.getWritableDatabase(); int row = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: { row = database.delete("book", selection, selectionArgs); break; } case BOOK_ITEM: { String bookid = uri.getPathSegments().get(1); row = database.delete("book", "id=?", new String[]{bookid}); break; } } return row; } @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { SQLiteDatabase database = helper.getWritableDatabase(); int row = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: { database.update("book", values, selection, selectionArgs); break; } case BOOK_ITEM: { String id = uri.getPathSegments().get(1); database.update("book", values, "id=?", new String[]{id}); break; } } return row; }}
Avtivity
package com.example.myapplication;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button delete; Button query; Button insert; Button update; String path = "content://com.example.myapplication"; String TAG = "TAG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); delete = (Button) findViewById(R.id.delete); query = (Button) findViewById(R.id.query); insert = (Button) findViewById(R.id.insert); update = (Button) findViewById(R.id.update); delete.setOnClickListener(this); query.setOnClickListener(this); insert.setOnClickListener(this); update.setOnClickListener(this); } @Override public void onClick(View v) { if (v == delete) { int newId = 0; getContentResolver().delete(Uri.parse(path+"/book/"+newId),null,null); } if (v == query) { Cursor cursor = getContentResolver().query(Uri.parse(path + "/book"), null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex("name")); String author = cursor.getString(cursor.getColumnIndex("author")); int price = cursor.getInt(cursor.getColumnIndex("price")); Log.d(TAG, "name=" + name); Log.d(TAG, "author" + author); Log.d(TAG, "price" + price); Log.d(TAG, "======================="); } } } if (v == insert) { //create table book(id integer primary key autoincrement,name text,price real,author text ContentValues contentValues = new ContentValues(); contentValues.put("name", "第一行代码"); contentValues.put("price", 50); contentValues.put("author", "郭霖"); getContentResolver().insert(Uri.parse(path + "/book"), contentValues); ContentValues contentValues1 = new ContentValues(); contentValues1.put("name", "Effective java"); contentValues1.put("price", 40); contentValues1.put("author", "Joshua Bloch"); getContentResolver().insert(Uri.parse(path + "/book"), contentValues1); } if (v == update) { int newID = 2; ContentValues contentValues1 = new ContentValues(); contentValues1.put("name", "JAVA编程思想"); contentValues1.put("price", 89); contentValues1.put("author", "Bruce Eckel"); getContentResolver().update(Uri.parse(path + "/book/" + newID), contentValues1, null, null); } }}
主布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.myapplication.MainActivity"> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="delete" /> <Button android:id="@+id/query" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="query" /> <Button android:id="@+id/insert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="insert" /> <Button android:id="@+id/update" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="update" /></LinearLayout>
现在我们就创建了一个自己的内容提供者
一般来说我们不会将数据暴露出去,相反我们却需要系统提供给我们提供数据,这时候我们就需要知道系统常见的查询条件
在下面我们列出一些
电话联系人:
Uri: ContactsContract.Contacts.CONTENT_URI
String[] columns={“_id”,”display_name”,”has_phone_number”};
不知道固列的。可以使用Contact点出来,就是一堆常量
Uri:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
String[] phone_cols={ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
};
使用CommonDataKinds点出来
图片:
Uri:MediaStore.Images.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA};
音频:
Uri:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.SIZE};
视频:
Uri:MediaStore.Video.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATA};
短信:
Uri:(Uri.parse(“content://sms/”)
String[] cols={“address”,”type”,”body”,”date”};
通话记录:
Uri:CallLog.Calls.CONTENT_URI
String[] cols={
CallLog.Calls.NUMBER,//电话号码
CallLog.Calls.CACHED_NAME,//联系人名
CallLog.Calls.TYPE,//通话类型:1:已接,2:已拨,3:未接
CallLog.Calls.DATE,//通话日期时间
CallLog.Calls.DURATION//通话时长
};
常用的系统权限<uses-permission android:name="android.permission.INTERNET"/>访问网络<uses-permission android:name="android.permission.CALL_PHONE"/> 拨打电话<uses-permission android:name="android.permission.SEND_SMS"/>发送信息<uses-permission android:name="android.permission.READ_CONTACTS"/>读取联系人<uses-permission android:name="android.permission.READ_SMS"/>读取信息 <uses-permission android:name="android.permission.RECORD_AUDIO"/>录制声音<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>读取手机状态<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 对外存进行读写
下面我们进行演示部分上面的操作
package com.example.fang.myapplication;import android.database.Cursor;import android.provider.ContactsContract;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button button; String TAG = "TAG"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.select); button.setOnClickListener(this); } @Override public void onClick(View v) { String[] column = {"_id", "display_name", "has_phone_number"};//查询联系人 Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, column, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { Log.d(TAG, "id-----------------------" + cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID))); Log.d(TAG, "display_name-------------" + cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))); Log.d(TAG, "has_phone_number---------" + cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));//代表有没有号码1代表有0代表无 } } }}
其他的查询也一样,就不演示了,上面是一些基本的常量,直接用就是了
- Android组件之ContentProvider
- Android之ContentProvider组件
- android组件之ContentProvider
- Android组件之contentProvider
- Android四大组件之ContentProvider
- android四大组件之ContentProvider
- android四大组件之 ContentProvider
- Android四大组件之ContentProvider
- Android四大组件之ContentProvider
- android 四大组件之ContentProvider
- Android四大组件之ContentProvider
- Android四大组件之ContentProvider
- Android组件之自定义ContentProvider
- Android组件之自定义ContentProvider
- Android组件之自定义ContentProvider
- Android组件之自定义ContentProvider
- Android组件之自定义ContentProvider
- Android组件之自定义ContentProvider
- 使用vscode 搭建 typescript 的nodejs 自动编译自动启动服务
- javaweb学习总结(四十四)——监听器(Listener)学习
- Python学习_我应该怎么快速创建数字列表
- [转载]分类和聚类的区别及各自的常见算法
- 在Win7x64上加载无签名驱动以及让PatchGuard失效(Win7x64内核越狱)
- Android组件之contentProvider
- uva10048
- Makefile中 = ?= += :=的区别
- js相关知识
- SpringMVC中的requstMapping注解用法详解
- Python凸优化库cvxopt、cvxpy安装
- HDU
- Excel组件Aspose.Cells 系列介绍 | 附下载
- 配置pom.xml