04Android學習從零單排之ContentProvider
讀了那麼多年的書讓我明白一個道理。人要穩重,不要想到啥就做啥。做一行越久即使你不會,幾年之後慢慢的你也會了,加上一點努力你或許你能成爲別人眼中的專家。
ContentProvider簡介
ContentProvider 在android中的作用是對外共享數據,也就是說你可以通過ContentProvider把應用中的數據共享給其他應用訪問,其他應用可以通過ContentProvider 對你應用中的數據進行添刪改查。
ContentProvider實際應用場景
ContentProvider實際應用場景,主要是通過getContentResolver來獲取安卓系統中已經通過ContentProvider共享好的數據。例如,讀取短信數據、獲取聯繫人信息,它們都是通過ContentProvider把數據庫對外提供好的,一般我們很少會ContentProvider把自己的應用程序數據暴露出去。
ContentProvider共享數據的使用步驟
1、定義一個類繼承ContentProvider,並在清單文件中配置provider和android:authorities節點。
2、定義路徑匹配規則
3、添加路徑匹配規則,以供其他應用程序訪問。
4、判斷匹配規則,和定義的匹配規則是否相同。相同數據即可不其他應用操作。
public class AccountProvider extends ContentProvider {
private static final int QUERYSUCESS = 1; //ctrl+shift+x 變成大些 ctrl+shift小寫加Y
private static final int ADDSUCESS = 2;
private static final int DELSUCESS = 3;
private static final int UPDATESUCESS = 4;
//(1) 定義路徑匹配規則
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private MyOpenHelper helper;
//(2) 添加路徑匹配規則
static{
/**
* authority 主機名 自己定義
* path 路徑
*
*/
matcher.addURI("com.itheima.account.provider", "query", QUERYSUCESS); //添加 query方法的匹配規則
matcher.addURI("com.itheima.account.provider", "add", ADDSUCESS); //添加 add方法的匹配規則
matcher.addURI("com.itheima.account.provider", "delete", DELSUCESS); //添加 add方法的匹配規則
matcher.addURI("com.itheima.account.provider", "update", UPDATESUCESS); //添加 add方法的匹配規則
}
@Override
public boolean onCreate() {
helper = new MyOpenHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//(3)獲取匹配code
int code = matcher.match(uri);
if (code == QUERYSUCESS) {
//說明匹配成功
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
}else {
throw new IllegalArgumentException("路徑不匹配 請檢查");
}
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int code = matcher.match(uri);
if (code == ADDSUCESS ) {
//匹配成功
SQLiteDatabase db = helper.getReadableDatabase();
//代表插入到了多少行
long insert = db.insert("info", null, values);
return Uri.parse("com.itheima.account.provider"+insert);
}else {
throw new IllegalArgumentException("路徑不匹配 請檢查");
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = matcher.match(uri);
if (code == DELSUCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
int delete = db.delete("info", selection, selectionArgs);
//刪除了多少行
return delete;
}else {
throw new IllegalArgumentException("路徑不匹配 請檢查");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = matcher.match(uri);
if (code == UPDATESUCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
int update = db.update("info", values, selection, selectionArgs);
//刪除了多少行
return update;
}else {
throw new IllegalArgumentException("路徑不匹配 請檢查");
}
}
}
清單文件中配置provider
<provider
android:name="com.itheima.transation.AccountProvider"
android:authorities="com.itheima.account.provider" ></provider>
以上內容在實際開發中一般不常見。下面通過案例的方式,學習並使用ContentProvider共享數據的共享的數據。
ContentProvider之短信備份案例
1、通過內容解析者getContentResolver()查詢短信數據庫。
2、把查詢出來的結果通過xml文件保存起來。
public void backsms(View view){
//寫入到xml文件中
XmlSerializer serializer = Xml.newSerializer();
File file = new File(Environment.getExternalStorageDirectory().getPath()+"/Download", "smsback.xml");
try {
FileOutputStream fos = new FileOutputStream(file);
serializer.setOutput(fos,"utf-8");
//文檔開始
serializer.startDocument("utf-8",true);
//開始節點
serializer.startTag(null,"smss");
//循環寫 xml sms body address date
//1、利用內容解析者 獲取我們關心列
//content://sms 是短信的匹配規則
Uri uri = Uri.parse("content://sms");
Cursor cursor = getContentResolver().query(uri, new String[]{"address", "date", "body"}, null, null, null);
if (cursor != null&&cursor.getCount()>0) {
while(cursor.moveToNext()){
String address = cursor.getString(0);
String date = cursor.getString(1);
String body = cursor.getString(2);
String datef = formatDate(date);
//開始寫 xml 的 sms節點
serializer.startTag(null,"sms");
serializer.startTag(null,"address");
//如果不做這個判斷,讀取到是草稿短信,就會報空指針異常。
if (TextUtils.isEmpty(address)){
serializer.text("草稿箱");
}else{
serializer.text(address);
}
serializer.endTag(null,"address");
serializer.startTag(null,"date");
serializer.text(datef);
serializer.endTag(null,"date");
serializer.startTag(null,"body");
serializer.text(body);
serializer.endTag(null,"body");
serializer.endTag(null,"sms");
}
}
serializer.endTag(null,"smss");
serializer.endDocument();
//關閉數據庫查詢
cursor.close();
fos.close();//釋放資源
Toast.makeText(getApplicationContext(),"短信備份完成。",Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),"短信備份失敗。",Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
//不要忘記添加短信權限
}
/**
* 時間格式轉換
* @param date
* @return
*/
private String formatDate(String date){
long l = System.currentTimeMillis();
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String format1 = format.format(new Date(new Long(date)));
return format1;
}
ContentProvider之短信插入案例
public void insertSms(View view){
//通過內容解析者,插入數據到短信數據庫中
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms");
String phoneNumber = mTvPhone.getText().toString().trim();
String context = mTvPhone.getText().toString().trim();
long l = System.currentTimeMillis();
ContentValues values = new ContentValues();
values.put("address",context);
values.put("date",l);
values.put("body",phoneNumber);
//從這裏插入你添加的短信數據
resolver.insert(uri,values);
}
//不要忘記添加短信權限
ContentProvider之讀取聯繫人案例
由於讀取聯繫人是實際開發中比較常用的功能,因此在這裏我把讀取聯繫人抽取成了工具類,方便以後再開發中,直接哪來用。
這個讀取聯繫人的工具類,只是最簡單的實現功能,代碼還有很多需要完善的地方,在此不做修改了,等用到的時候在優化。
public class ReadContactUtils {
public List<ContactsBean> readContacts(Context context){
//自定義一個javabean,用於存儲短信格式,javabean在此就不貼出來了,根據實際需求自己定義。
List<ContactsBean> contactsBeanList = new ArrayList<>();
//(1)去raw_contacts表查詢 contact_id列,contact_id記錄了聯繫人的數目
Uri contactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor contactsCursor = context.getContentResolver().query(contactsUri, new String[]{"contact_id"}, null, null, null);
if (contactsCursor!= null&&contactsCursor.getCount()>0) {
while(contactsCursor.moveToNext()){
String contactsID = contactsCursor.getString(0);
//判斷contactsID不爲null說明聯繫人存在
if (contactsID != null) {
ContactsBean contactsBean = new ContactsBean();
contactsBean.setId(contactsID);
//(2)根據 contact_id 去查 data表 查詢data1列 和 mimetype_id 列
Cursor dataCursor = context.getContentResolver().query(dataUri, new String[]{"data1","mimetype"}, "raw_contact_id=?", new String[]{contactsID}, null);
if (dataCursor != null&&dataCursor.getCount()>0) {
while (dataCursor.moveToNext()){
if (dataCursor!=null){
String data1 = dataCursor.getString(0);//獲取data1列的數據,就是聯繫人的詳情數據
String mimetype = dataCursor.getString(1);//獲取mimetype列數據
//(3)拿mimetype 數據做一下對比,然後取出聯繫人號碼或者其他信息
if("vnd.android.cursor.item/name".equals(mimetype)){
System.out.println("姓名data1:"+data1);
contactsBean.setName(data1);
}else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){
System.out.println("電話號碼data1:"+data1);
contactsBean.setPhone(data1);
}
}
}
}
contactsBeanList.add(contactsBean);
}
}
// System.out.println("一共有"+contactsID+"個聯繫人");
}
return contactsBeanList;
}
ContentProvider之插入聯繫人案例
public void addContact(View view){
String name = mTvName.getText().toString().trim();
String number = mTvNumber.getText().toString().trim();
//添加聯繫人之前先查詢聯繫的contact_id
Uri contactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data");
Cursor cursor = getContentResolver().query(contactsUri, null, null, null, null);
int contact_id = cursor.getCount();
// System.out.println("contact_id"+contact_id);
//2現在開始插入聯繫人id
ContentValues Values = new ContentValues();
//3爲什麼加1,是在原來的基礎上+1
int newContact_id = contact_id+1;
Values.put("contact_id",newContact_id);
getContentResolver().insert(contactsUri,Values);
//4開始插入聯繫人姓名
ContentValues nameValues = new ContentValues();
nameValues.put("raw_contact_id",newContact_id);
nameValues.put("mimetype","vnd.android.cursor.item/name");
nameValues.put("data1",name);
getContentResolver().insert(dataUri,nameValues);
//5插入聯繫人手機號碼
ContentValues numberValues = new ContentValues();
numberValues.put("raw_contact_id", newContact_id);
numberValues.put("mimetype", "vnd.android.cursor.item/phone_v2");
numberValues.put("data1",number);
getContentResolver().insert(dataUri,numberValues);
Toast.makeText(getApplicationContext(),"聯繫人插入成功",Toast.LENGTH_SHORT).show();
}
關於作者
- Email:[email protected]
- 項目地址:https://github.com/swordman20/Hsia04ContentProviderDemo.git