摘要:获取短信内容的方法短信内容数据也是系统提供的,获取方法如下获取方法如下微信公众号程序员插入数据测试数据中。。。。。
极力推荐文章:欢迎收藏
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 三者关系
三者关系图如下
至此,本篇已结束,如有不对的地方,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/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...
阅读 1571·2021-11-25 09:43
阅读 2476·2019-08-30 15:54
阅读 2938·2019-08-30 15:53
阅读 1086·2019-08-30 15:53
阅读 747·2019-08-30 15:52
阅读 2538·2019-08-26 13:36
阅读 806·2019-08-26 12:16
阅读 1210·2019-08-26 12:13