[安卓基礎]學習第九天
阿新 • • 發佈:2019-01-03
一、為什麼需要內容提供者
1-1.回憶定義資料庫
- 新建一個類繼承SQLiteOpenHelper
public class MyOpenHelper extends SQLiteOpenHelper {
public MyOpenHelper(Context context) {
super(context, "test.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),money varchar(20))" );
db.execSQL("insert into info(name,money) values(?,?)", new String[]{"張三","5000"});
db.execSQL("insert into info(name,money) values(?,?)", new String[]{"李四","3000"});
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
- 開啟資料庫
MyOpenHelper myOpenHelper = new MyOpenHelper(this);
SQLiteDatabase db = myOpenHelper.getWritableDatabase();
- 讀取資料庫
Cursor cursor = db.query("info", null, null, null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("___" + name + ": " + phone);
}
}
- chmod linux下修改文改檔案的許可權
二、內容提供者的原理
- 內容提供者把資料進行封裝,其他應用都是用過內容解析者來訪問
- 定義內容提供者,定義一個類繼承ContentProvider
三、實現內容提供者的步驟
- 定義一個類繼承ContentProvider
public class TestdbProvider extends ContentProvider {
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@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;
}
}
- 在清單檔案進行配置
<provider
android:name="com.elnui.day09_db.TestdbProvider"
android:authorities="com.elnui.testdbprovider"
android:exported="true"
android:enabled="true">
</provider>
- 寫一個靜態程式碼塊,新增匹配規則
static
{
/**
* authority 和清單檔案裡面定義的要一樣
* path 任意的路徑
*
* com.elnui.provider/query
* */
sUriMather.addURI("com.elnui.provider", "query", QUERY_SUCCESS);
}
[完整的TestdbProvider類程式碼]
public class TestdbProvider extends ContentProvider {
// 定義一個urimatcher,路徑匹配器
private static final UriMatcher sUriMather = new UriMatcher(UriMatcher.NO_MATCH);
private static final int QUERY_SUCCESS = 1;
private MyOpenHelper myOpenHelper;
// 定義靜態程式碼塊,新增匹配規則,規則可以多個
static
{
/**
* authority 和清單檔案裡面定義的要一樣
* path 任意的路徑
*
* com.elnui.provider/query
* */
sUriMather.addURI("com.elnui.testdbprovider", "query", QUERY_SUCCESS);
}
@Override
public boolean onCreate() {
myOpenHelper = new MyOpenHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int code = sUriMather.match(uri);
if(code == QUERY_SUCCESS){ // 說明路徑匹配成功
/**
* 資料庫的查詢
* */
SQLiteDatabase db = myOpenHelper.getReadableDatabase();
/**
* table 表名
* columns 查詢的列,由引數String[] projection給出
* selection 查詢的條件
* selectionArgs 查詢的條件引數
* */
Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
// 注意,這裡的Cursor不能關
return cursor;
}else{
throw new IllegalArgumentException("路徑不匹配,請檢查");
}
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
- 解析
Uri uri = Uri.parse("content://com.elnui.testdbprovider/query"); // 路徑和內容提供者路徑一樣,前面還應加協議content://
/**
* uri
* projection 查詢列
* selection
* selectionArgs
* sortOrder
* */
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if(cursor != null){
while(cursor.moveToNext()){
String name = cursor.getString(1);
String phone = cursor.getString(2);
System.out.println("___2" + name + ": " + phone);
}
}
四、備份簡訊案例
public void click1(View v){
try {
// 獲取XmlSerializer序列化例項
XmlSerializer serializer = Xml.newSerializer();
// 設定序列化引數
File file = new File(Environment.getExternalStorageDirectory().getPath(),"backup.xml");
FileOutputStream fos = new FileOutputStream(file);
serializer.setOutput(fos, "utf-8");
// 開始寫
serializer.startDocument("utf-8", true);
serializer.startTag(null, "smss");
// 使用內容解析者去解析即可
Uri uri = Uri.parse("content://sms/inbox");
Cursor cursor = getContentResolver().query(uri, new String[]{"address","date","body"}, null, null, null);
if(cursor != null){
while(cursor.moveToNext()){
String addr = cursor.getString(0);
String date = cursor.getString(1);
String body = cursor.getString(2);
System.out.println("___" + addr + date + body);
// 寫sms節點
serializer.startTag(null, "sms");
// address
serializer.startTag(null, "address");
serializer.text(addr);
serializer.endTag(null, "address");
// body
serializer.startTag(null, "body");
serializer.text(body);
serializer.endTag(null, "body");
// date
serializer.startTag(null, "date");
serializer.text(date);
serializer.endTag(null, "date");
serializer.endTag(null, "sms");
}
serializer.endTag(null, "smss");
serializer.endDocument();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
五、利用內容提供者插入簡訊
public void click1(View v){
Uri uri = Uri.parse("content://sms");
ContentValues values = new ContentValues();
values.put("address","10086");
values.put("body","你的花費餘額不足!");
values.put("date", System.currentTimeMillis());
getContentResolver().insert(uri, values);
}
六、讀取聯絡人的案例
6-1. 三張重要的表
data表
- raw_contact_id ,實際上是raw_contacts表
- mimetype_id ,1-email, 2-im, 3-nickname,5-phone, 7-name, 8-address,實際上對應mimetype表
raw_contacts表
- mimetypes
6-2.實現步驟
- 讀raw_contacts表的contact_id欄位,獲取聯絡人總數
- 根據raw_contacts_id讀取data表的data1列和mimetype列
6-3.小細節
getContentResolver().query(data_uri, new String[]{"data1","mimetype_id"}, "raw_contact_id=?", new String[]{contact_id}, null);
查詢的不是data表,查詢的是view_data的檢視
七、插入聯絡人
- 先往raw_contact表,contact_id列插入元素
- 同步到data表,data1列存所以聯絡人資料
public void click1(View v){
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri data_uri = Uri.parse("content://com.android.contacts/data");
String name = et_name.getText().toString().trim();
String address = et_address.getText().toString().trim();
String emall = et_email.getText().toString().trim();
String phone = et_phone.getText().toString().trim();
// 查詢raw_contacts中共幾條資料
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
int count = cursor.getCount();
int countid = count+1;
ContentValues values = new ContentValues();
values.put("contact_id", countid);
getContentResolver().insert(uri, values);
////////////////////////////////////////////////////////////////////////
// 插入名字
ContentValues valuesName = new ContentValues();
valuesName.put("data1", name); //把資料插入到data1列
valuesName.put("raw_contact_id", countid);//插入的資料屬於那條聯絡人
valuesName.put("mimetype","vnd.android.cursor.item/name"); //插入的 資料的資料型別是名字
getContentResolver().insert(data_uri, valuesName);
// 插入地址
ContentValues valuesAddress = new ContentValues();
valuesAddress.put("data1", address); //把資料插入到data1列
valuesAddress.put("raw_contact_id", countid);//插入的資料屬於那條聯絡人
valuesAddress.put("mimetype","vnd.android.cursor.item/postal-address_v2"); //插入的 資料的資料型別是名字
getContentResolver().insert(data_uri, valuesAddress);
// 插入email
ContentValues valuesMail = new ContentValues();
valuesMail.put("data1", emall); //把資料插入到data1列
valuesMail.put("raw_contact_id", countid);//插入的資料屬於那條聯絡人
valuesMail.put("mimetype","vnd.android.cursor.item/email_v2"); //插入的 資料的資料型別是名字
getContentResolver().insert(data_uri, valuesMail);
// 插入號碼
ContentValues valuesPhone = new ContentValues();
valuesPhone.put("data1", phone); //把資料插入到data1列
valuesPhone.put("raw_contact_id", countid);//插入的資料屬於那條聯絡人
valuesPhone.put("mimetype","vnd.android.cursor.item/phone_v2"); //插入的 資料的資料型別是名字
getContentResolver().insert(data_uri, valuesPhone);
}
八、內容觀察者
==內容提供者==是四大元件,需要在清單檔案配置
8-1.被觀察的提供者中新增
// 資料庫被改了,自己傳送訊息
getContext().getContentResolver().notifyChange(uri, null);
8-2.內容觀察者
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 註冊記憶體觀察者
Uri uri = Uri.parse("content://com.elnui.testdbprovider");
getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()));
}
private class MyObserver extends ContentObserver{
public MyObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
System.out.println("___[ContentObserver]資料被修改了");
super.onChange(selfChange);
}
}