摘要:獲取短信內容的方法短信內容數據也是系統提供的,獲取方法如下獲取方法如下微信公眾號程序員插入數據測試數據中。。。。。
極力推薦文章:歡迎收藏
Android 干貨分享
本篇文章主要介紹 Android 開發中的部分知識點,通過閱讀本篇文章,您將收獲以下內容:
ContentProvider
獲取聯系人信息的方法
獲取短信內容的方法
ContentResolver 內容解析者
ContentObserver 內容觀察者
ContentProvider ContentResolver ContentObserver 三者關系
ContentProvider 是Android 四大組件之一,其本質上是一個標準化的數據管道,它屏蔽了底層的數據管理和服務等細節,以標準化的方式在Android 應用間共享數據。用戶可以靈活實現ContentProvider 所封裝的數據存儲以及增刪改查等,所有的ContentProvider 必須實現一個對外統一的接口(URI)。
1. ContentProvider 實現 ContentProvider 繼承關系java.lang.Object ???? android.content.ContentProvider四大組件之一,必須在Androidmainfest.xml 中注冊
注意 :
URI 中的元素 android:authorities="ProgramAndroid"繼承 ContentProvider 實現增刪改查等方法
package com.programandroid.ContentProvider; import android.content.ContentProvider; import android.content.ContentUris; 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.Nullable; /* * ContentProviderMethod.java * * Created on: 2017-9-13 * Author: wangjie * * Welcome attention to weixin public number get more info * * WeiXin Public Number : ProgramAndroid * 微信公眾號 :程序員Android * */ public class CustomContentProviderMethod extends ContentProvider { private SQLiteDatabase db; private static final String MAUTHORITIESNAME = "ProgramAndroid"; private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int PERSON = 1; private static final int PERSON_NUMBER = 2; private static final int PERSON_TEXT = 3; private static final String TABLE_NAME = "table_person"; // 構建URI static { // content://programandroid/person matcher.addURI(MAUTHORITIESNAME, "person", PERSON); // # 代表任意數字content://programandroid/person/4 matcher.addURI(MAUTHORITIESNAME, "person/#", PERSON_NUMBER); // * 代表任意文本 content://programandroid/person/filter/ssstring matcher.addURI(MAUTHORITIESNAME, "person/filter/*", PERSON_TEXT); } @Override public boolean onCreate() { DBHelper helper = new DBHelper(getContext()); // 創建數據庫 db = helper.getWritableDatabase(); return true; } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 過濾URI int match = matcher.match(uri); switch (match) { case PERSON: // content://autoname/person return db.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder); case PERSON_NUMBER: break; case PERSON_TEXT: break; default: break; } return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { // 過濾URI int match = matcher.match(uri); switch (match) { case PERSON: // content://autoname/person long id = db.insert(TABLE_NAME, null, values); // 將原有的uri跟id進行拼接從而獲取新的uri return ContentUris.withAppendedId(uri, id); case PERSON_NUMBER: break; case PERSON_TEXT: break; default: break; } 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) { return 0; } @Nullable @Override public String getType(Uri uri) { return null; } }提供對外提供操作的數據庫方法
package com.programandroid.ContentProvider; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; /* * DBHelper.java * * Created on: 2017-9-13 * Author: wangjie * * Welcome attention to weixin public number get more info * * WeiXin Public Number : ProgramAndroid * 微信公眾號 :程序員Android * */ public class DBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "persons.db"; private static final int DB_VERSION = 1; private static final String TABLE_NAME = "table_person"; private static final String ID = "_id"; private static final String NAME = "name"; public DBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL" + "," + NAME + " CHAR(10) )"; db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }其他APK 訪問此ContentProvider 數據庫的方法
public class MainActivity extends Activity { private String uri = "content://ProgramAndroid/person"; private EditText mEditText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mEditText = (EditText) findViewById(R.id.ed_name); } public void QureyData(View view) { String name = null; Cursor cursor = getContentResolver().query(Uri.parse(uri), null, null, null, null); while (cursor.moveToNext()) { name = cursor.getString(cursor.getColumnIndex("name")); } mEditText.setText(name); } public void InsertData(View view) { String editName = mEditText.getText().toString(); ContentValues values = new ContentValues(); values.put("name, editName); Uri result = getContentResolver().insert(Uri.parse(uri), values); // 注意 : 此條添加上才ContentObserver可以監聽數據庫改變 getContentResolver().notifyChange(Uri.parse(uri),null); long parseid = ContentUris.parseId(result); if (parseid > 0) { Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_LONG).show(); mEditText.setText(""); } } }
注意 :
// 此條添加上才ContentObserver可以監聽數據庫改變 getContentResolver().notifyChange(Uri.parse(uri),null);
至此,自定義ContentProvider的使用方法已經實現。
2. 獲取聯系人信息的方法 Android 系統自帶一下ContentProvider ,比如 聯系人
例如: 源碼 packagesproviders 下的內容
public class ContactListActivity extends Activity { private static final String tag = "ContactListActivity"; private ListView lv_contact_list; private ListListView 顯示布局如下> mContactList = new ArrayList >(); private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { // 給數據適配器設置數據 MyAdapter myAdapter = new MyAdapter(); TextView emptyView = new TextView(getApplicationContext()); emptyView.setLayoutParams(new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); emptyView.setText(getResources().getString( R.string.please_add_contanct)); emptyView.setVisibility(View.GONE); emptyView.setTextColor(Color.BLACK); emptyView.setTextSize(20); emptyView.setGravity(Gravity.CENTER); ((ViewGroup) lv_contact_list.getParent()).addView(emptyView); lv_contact_list.setEmptyView(emptyView); lv_contact_list.setAdapter(myAdapter); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_contact_list); initUI(); initData(); } /** * 從系統數據庫中獲取聯系人數據,權限,讀取聯系人 */ private void initData() { new Thread() { public void run() { // 1,獲取內容解析器(訪問地址(后門)) ContentResolver contentResolver = getContentResolver(); // 2,對數據庫指定表進行查詢操作 Cursor cursor = contentResolver.query(Uri .parse("content://com.android.contacts/raw_contacts"), new String[] { "contact_id" }, null, null, null); // 3,判斷游標中是否有數據,有數據一直度 while (cursor.moveToNext()) { String id = cursor.getString(0); Log.i(tag, "id = " + id);// 1,2,3 // 4,通過此id去關聯data表和mimetype表生成視圖,data1(數據),mimetype(數據類型) Cursor indexCursor = contentResolver.query( Uri.parse("content://com.android.contacts/data"), new String[] { "data1", "mimetype" }, "raw_contact_id = ?", new String[] { id }, null); HashMap hashMap = new HashMap (); // 5,游標向下移動獲取數據過程 while (indexCursor.moveToNext()) { String data = indexCursor.getString(0); String type = indexCursor.getString(1); // Log.i(tag, "data = "+data); // Log.i(tag, "type = "+type); if (type.equals("vnd.android.cursor.item/phone_v2")) { // data就為電話號碼 hashMap.put("phone", data); } else if (type.equals("vnd.android.cursor.item/name")) { // data 為聯系人名字 hashMap.put("name", data); } } indexCursor.close(); mContactList.add(hashMap); } cursor.close(); // 告知主線程集合中的數據以及準備完畢,可以讓主線程去使用此集合,填充數據適配器 mHandler.sendEmptyMessage(0); }; }.start(); } private void initUI() { lv_contact_list = (ListView) findViewById(R.id.lv_contact_list); lv_contact_list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { // 1,position點中條目的索引值,集合的索引值 String phone = mContactList.get(position).get("phone"); // 2,將此電話號碼傳遞給前一個界面 Intent intent = new Intent(); intent.putExtra("phone", phone); setResult(0, intent); // 3,關閉此界面 finish(); } }); } class MyAdapter extends BaseAdapter { @Override public int getCount() { return mContactList.size(); } @Override public HashMap getItem(int position) { return mContactList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Holder holder; if (convertView == null) { holder = new Holder(); // 1,生成當前listview一個條目相應的view對象 convertView = View.inflate(getApplicationContext(), R.layout.list_item_contact, null); // 2,找到view中的控件 holder.tv_name = (TextView) convertView .findViewById(R.id.tv_name); holder.tv_phone = (TextView) convertView .findViewById(R.id.tv_phone); convertView.setTag(holder); } else { holder = (Holder) convertView.getTag(); } // 3,給控件賦值 holder.tv_name.setText(getItem(position).get("name")); holder.tv_phone.setText(getItem(position).get("phone")); return convertView; } } class Holder { public TextView tv_name; public TextView tv_phone; } }
item 布局如下:
注意:
獲取聯系人需要申請權限
至此,已經可以獲取并顯示聯系人信息。
3.獲取短信內容的方法短信內容數據也是Android 系統提供的,獲取方法如下:
獲取方法如下
package com.programandroid.ContentProvider; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.widget.CursorAdapter; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; import android.widget.TextView; import com.programandroid.MainActivity; import com.programandroid.R; /* * MmsListActivity.java * * Created on: 2017-9-13 * Author: wangjie * * Welcome attention to weixin public number get more info * * WeiXin Public Number : ProgramAndroid * 微信公眾號 :程序員Android * */ public class MmsListActivity extends Activity { private ContentResolver resolver; private ListView listView; private static final String SMS_URI = "content://sms"; private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mms_list); listView = (ListView) findViewById(R.id.lv_mms); resolver = getContentResolver(); } public void GetMMSBtn(View view) { // 插入數據 ContentValues values = new ContentValues(); values.put("address", "136259"); values.put("body", "測試數據中。。。。。"); resolver.insert(Uri.parse(SMS_URI), values); // 查詢數據方法 cursor = resolver.query(Uri.parse(SMS_URI), null, null, null, null); // 將數據顯示到ListView中 listView.setAdapter(new MyAdapter(MmsListActivity.this, cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER)); } @Override protected void onDestroy() { super.onDestroy(); if (cursor != null) { // 關閉cursor // cursor.close(); } } class MyAdapter extends CursorAdapter { public MyAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } // 創建一個視圖,引入listview要展示的子視圖 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return getLayoutInflater().inflate(R.layout.list_item_mms, null); } // 綁定數據的方法 @Override public void bindView(View view, Context context, Cursor cursor) { TextView tvNumber = (TextView) view.findViewById(R.id.tv_number); TextView tvContent = (TextView) view.findViewById(R.id.tv_content); TextView tvState = (TextView) view.findViewById(R.id.tv_state); TextView tvDate = (TextView) view.findViewById(R.id.tv_date); TextView tvId = (TextView) view.findViewById(R.id.tv_id); TextView tvRead = (TextView) view.findViewById(R.id.tv_read); String number = cursor.getString(cursor.getColumnIndex("address")); String body = cursor.getString(cursor.getColumnIndex("body")); String date = cursor.getString(cursor.getColumnIndex("date")); int read = cursor.getInt(cursor.getColumnIndex("read")); int id = cursor.getInt(cursor.getColumnIndex("_id")); int type = cursor.getInt(cursor.getColumnIndex("type")); if (read == 0) { tvRead.setText("短信狀態:未讀"); } else { tvRead.setText("短信狀態:已讀"); } tvNumber.setText("手機號:" + number); tvContent.setText("短信內容:" + body); tvDate.setText("接收短信時間:" + date); tvId.setText("短信Id:" + id); if (type == 1) { tvState.setText("短信狀態:已接收"); } else { tvState.setText("短信狀態:已發送"); } } } }ListView 布局如下
item 布局如下:
# 4. ContentResolver 內容解析者
ContentResolver 主要是通過URI調用getContentResolver()獲取ContentProvider 提供的數據接口,進而進行增刪改查等操作。
// 查詢 Cursor cursor = getContentResolver().query(Uri.parse(uri), null, null, null, null); // 插入數據到指定 URI 中 getContentResolver().insert(Uri.parse(uri), ContentValues);5.ContentObserver 內容觀察者
ContentObserver 內容觀察者通過指定URI 監聽ContentProvider數據是否改變。
自定義 ContentObserver 內容觀察者/** * 監聽ContentProvider數據庫變化 */ private void ContentObserverDatabase() { // [1]注冊內容觀察者 Uri uri = Uri.parse("content://ProgramAndroid/person"); // false 觀察的uri 必須是一個確切的uri 如果是true getContentResolver().registerContentObserver(uri, true, new CustomContentObserver(new Handler())); }
package com.programandroid.ContentProvider; import android.database.ContentObserver; import android.os.Handler; /* * CustomContentObserver.java * * Created on: 2017-9-13 * Author: wangjie * * Welcome attention to weixin public number get more info * * WeiXin Public Number : ProgramAndroid * 微信公眾號 :程序員Android * */ public class CustomContentObserver extends ContentObserver { /** * @param handler */ public CustomContentObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } // 當我們觀察的uri發生改變的時候調用 @Override public void onChange(boolean selfChange) { System.out.println(" 數據庫被操作了 "); super.onChange(selfChange); } }
至此自定義內容觀察者已經實現完成
調用ContentObserver 監聽短信數據改變public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //[1]注冊一個內容觀察者 Uri uri = Uri.parse("content://sms/"); getContentResolver().registerContentObserver(uri, true, new MyContentObserver(new Handler())); } private class MyContentObserver extends ContentObserver{ public MyContentObserver(Handler handler) { super(handler); } //當觀察的內容發生改變的時候調用 @Override public void onChange(boolean selfChange) { System.out.println(" 短信的數據庫發生了改變"); super.onChange(selfChange); } }6. ContentProvider ContentResolver ContentObserver 三者關系
三者關系圖如下
至此,本篇已結束,如有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75835.html
摘要:如何自學知識儲備本知識點不做重點講解對于有基礎的同學推薦看編程思想,鞏固基礎,查漏補全,了解并熟悉更多細節知識點。基礎學習基礎學習對于這些基礎的使用谷歌官網給出了很好的實例。是谷歌根據自帶的改進的。是基于谷歌內核的一個可以作為瀏覽器的視圖。 如何自學Android 1. Java知識儲備 本知識點不做重點講解: 對于有基礎的同學推薦看《Java編程思想》,鞏固基礎,查漏補全,了解...
摘要:前言屬于的四大組件之一本文全面解析了,包括原理使用方法實例講解,希望你們會喜歡。 前言 ContentProvider屬于 Android的四大組件之一 本文全面解析了 ContentProvider ,包括ContentProvider 原理、使用方法 & 實例講解,希望你們會喜歡。 目錄 showImg(https://segmentfault.com/img/remote/...
摘要:使用詳解使用詳解源碼解剖源碼解剖地址技術人,一位不羈的碼農。在中,它默認為我們初始化,作為一個成員變量。在方法中,它會判斷我們是否已經添加,沒有的話,添加進去。說在前面 本次推出 Android Architecture Components 系列文章,目前寫好了四篇,主要是關于 lifecycle,livedata 的使用和源碼分析,其余的 Navigation, Paging libr...
閱讀 1578·2021-11-25 09:43
閱讀 2482·2019-08-30 15:54
閱讀 2946·2019-08-30 15:53
閱讀 1096·2019-08-30 15:53
閱讀 755·2019-08-30 15:52
閱讀 2545·2019-08-26 13:36
閱讀 814·2019-08-26 12:16
閱讀 1216·2019-08-26 12:13