android基础之五——内容提供者

来源:互联网 发布:php 检验日期格式 编辑:程序博客网 时间:2024/05/21 21:50

内容提供者

01_为什么需要内容提供者

为了能够让其他应用程序访问本地应用程序中数据库,使用内容提供者对外开放几个接口,让其他应用程序调用这些接口。

02_编写内容提供者(重点)

步骤:1、在工程中添加一个内容提供者的类,继承ContentProvider,重写其中的方法;2、在配置文件中配置一个provider,指定主机名唯一标示内容提供者(android4.1.2之后的版本中,需要指定exported=true,否则其他应程序没有权限访问该内容提供者);3、在内容提供者类里面,创建一个uriMather(柜员),然后做岗前培训,添加增删改查的uri;4、在内容提供者的增删改查的方法判断uri是否匹配正确,再调用数据库的增删改查的方法访问数据库;

03_内容提供者工作的原理(重点)

在其他应用程序中,通过内容提供者的解析器,操作内容提供者。通过一个uri唯一的匹配内容提供者,在uri中指定了操作的路径(内容提供者已经匹配过的路径),内容提供者接收到这个uri后就可以做相应的操作;uri urlhttp://www.baidu.com:80/i.htmlcontentftp://uri组成:schemel,主机名、端口、路径http://www.baidu.com/i.htmlcontent://com.itheima.dbapp.accountcontentprovider/delete

04_内容提供者的增删改查的实现

代码:package com.itheima.dbapp;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;public class AccountContentProvider extends ContentProvider {    private AccountDBHelper helper;    private static String INSERT = "insert";    private static String DELETE = "delete";    private static String UPDATE = "update";    private static String QUERY = "query";    //创建一个银行的柜员    private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);    //柜员的岗前培训    static{//      content://com.itheima.dbapp.accountcontentprovider/insert//      content://com.itheima.dbapp.accountcontentprovider/delete        mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", INSERT, 1);        mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", DELETE, 2);**        mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", UPDATE, 3);        mUriMatcher.addURI("com.itheima.dbapp.accountcontentprovider", QUERY, 4);    }    /**     * 初始化实例对象     * 通常是创建一个数据库帮助类的对象     */    @Override    public boolean onCreate(){        helper = new AccountDBHelper(getContext());        return false;    }    @Override    public Uri insert(Uri uri, ContentValues values) {        //匹配用户的相应操作,匹配码与柜员培训的匹配吗一致        if(mUriMatcher.match(uri) == 1){            SQLiteDatabase db = helper.getWritableDatabase();            db.insert("account", null, values);        }        return null;    }    @Override    public Cursor query(Uri uri, String[] projection, String selection,            String[] selectionArgs, String sortOrder) {        if(mUriMatcher.match(uri) == 4){            SQLiteDatabase db = helper.getWritableDatabase();            return db.query("account", projection, selection, selectionArgs, null, null, sortOrder);        }else{            return null;        }    }    @Override    public int update(Uri uri, ContentValues values, String selection,            String[] selectionArgs) {        if(mUriMatcher.match(uri) == 3){            SQLiteDatabase db = helper.getWritableDatabase();             db.update("account", values, selection, selectionArgs);        }        return 0;    }    @Override    public int delete(Uri uri, String selection, String[] selectionArgs) {        if(mUriMatcher.match(uri) == 2){            SQLiteDatabase db = helper.getWritableDatabase();             db.delete("account", selection, selectionArgs);        }        return 0;    }    @Override    public String getType(Uri uri) {        return null;    }}

05_内容提供者的使用场景

场景:

写内容提供者的场景:让其他应用程序访问自己应用程序数据库中的数据;写内容提供者的解析器场景:访问别的应用程序中的内容提供者时;

06_插入短信(重点)

在自己的工程里访问手机上短信应用程序里面短信列表。1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/;   3、分析数据库表:sms;address,date,type,body;

代码:

package com.itheima.insertsms;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.net.Uri;import android.os.Bundle;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void insert(View view){    //得到内容提供者的解析器    ContentResolver resolver = getContentResolver();    Uri uri = Uri.parse("content://sms/");    ContentValues values = new ContentValues();    values.put("address", "18910903535");    values.put("date",System.currentTimeMillis());    values.put("type", 1);//type为表示接收到短信    values.put("body", "上次从我这里借的500万还没还我呢");    resolver.insert(uri, values);    Toast.makeText(this, "插入完成", 0).show();}}

07_内容提供者uri的写法

content://sms/;1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/;   3、分析数据库表:sms;address,date,type,body;

08_短信的备份(重点)

第一步:通过内容提供者查询短信列表:

1、需要访问短信应用提供的内容提供者;2、需要知道uri:content://sms/;   3、分析数据库表:sms;address,date,type,body;

第二步:把短信列表序列化到xml的文件上:

4、把备份的文件写到SD卡上;5、使用xml格式的文件存数短信;

代码:

package com.itheima.copysms;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import org.xmlpull.v1.XmlSerializer;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.util.Xml;import android.view.View;import android.widget.Toast;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void backup(View view){    try {        //1、访问短信应用的内容提供者        ContentResolver resolver = getContentResolver();        Uri uri = Uri.parse("content://sms/");        Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, "date desc");        //得到xml序列化器        XmlSerializer s = Xml.newSerializer();        FileOutputStream os = new FileOutputStream(new File(Environment.getExternalStorageDirectory()+"/backup.xml"));        //初始化序列器        s.setOutput(os, "UTF-8");        s.startDocument("UTF-8", true);        s.startTag(null, "info");        while(cursor.moveToNext()){            String address = cursor.getString(0);            long date = cursor.getLong(1);            int type = cursor.getInt(2);            String body = cursor.getString(3);            s.startTag(null, "sms");            s.startTag(null, "address");            s.text(address);            s.endTag(null, "address");            s.startTag(null, "date");            s.text(date+"");            s.endTag(null, "date");            s.startTag(null, "type");            s.text(type+"");            s.endTag(null, "type");            s.startTag(null, "body");            s.text(body);            s.endTag(null, "body");            s.endTag(null, "sms");        }        s.endTag(null, "info");        s.endDocument();        cursor.close();        os.close();        Toast.makeText(this, "备份成功", 0).show();    } catch (Exception e) {        e.printStackTrace();    }}}

09_短信的还原操作(重点)

把已经备份的xml短信数据插入到短信应用的数据库表中。1、解析xml的短信数据:2、通过短信应用程序的内容提供者把数据插入到数据库表中:

代码:

package com.itheima.restoresms;import java.io.File;import java.io.FileInputStream;import org.xmlpull.v1.XmlPullParser;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.content.ContentResolver;import android.content.ContentValues;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.util.Xml;import android.view.View;import android.widget.Toast;import com.itheima.restoresms.domain.SmsInfo;public class MainActivity extends Activity {    private SmsInfo sms;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public void restore(View view) {        // 创建一个对话框的构造器        AlertDialog.Builder builder = new Builder(this);        builder.setTitle("提醒");        builder.setMessage("是否删除所有短信并重新还原?");        builder.setPositiveButton("是", new OnClickListener() {            /**             * 单击按钮时调用这个方法             */            @Override            public void onClick(DialogInterface dialog, int which) {                //删除短信                deleteSms();                //还原短信                insertSms();            }        });        builder.setNegativeButton("否", new OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {            }        });        // 使用构造器创建出一个对话框对象        AlertDialog ad = builder.create();        ad.show();    }    public void insertSms() {        try {            ContentResolver resolver = getContentResolver();            Uri uri = Uri.parse("content://sms/");            resolver.delete(uri, null, null);            // 解析xml文件            XmlPullParser parser = Xml.newPullParser();            FileInputStream fis = new FileInputStream(new File(                    Environment.getExternalStorageDirectory() + "/backup.xml"));            parser.setInput(fis, "UTF-8");            // 得到解析的事件类型            int type = parser.getEventType();            while (type != XmlPullParser.END_DOCUMENT) {                switch (type) {                case XmlPullParser.START_TAG:// 开始标签的事件类型                    if ("sms".equals(parser.getName())) {                        sms = new SmsInfo();                    } else if ("address".equals(parser.getName())) {                        String address = parser.nextText();                        sms.setAddress(address);                    } else if ("date".equals(parser.getName())) {                        String date = parser.nextText();                        sms.setDate(date);                    } else if ("type".equals(parser.getName())) {                        String smsType = parser.nextText();                        sms.setType(smsType);                    } else if ("body".equals(parser.getName())) {                        String body = parser.nextText();                        sms.setBody(body);                    }                    break;                case XmlPullParser.END_TAG:// 结束标签的事件类型                    if ("sms".equals(parser.getName())) {                        // 把短信还原到数据库                        // address,date,type,body;                        ContentValues values = new ContentValues();                        values.put("address", sms.getAddress());                        values.put("date", sms.getDate());                        values.put("type", sms.getType());                        values.put("body", sms.getBody());                        resolver.insert(uri, values);                        sms = null;                    }                    break;                }                // 解析到下一个标签                parser.next();                type = parser.getEventType();            }            fis.close();        } catch (Exception e) {            e.printStackTrace();        }    }    public void deleteSms(){        ContentResolver resolver = getContentResolver();        Uri uri = Uri.parse("content://sms/");        resolver.delete(uri, null, null);    }}

10_联系人数据库的表结构

联系人相关的表:1、raw_contacts:存储了联系人的contact_id;2、data:存储了联系人信息字段的值;3、mimetypes:存储了联系人信息字段的类型;读取联系的信息的逻辑:1、查询raw_contacts:得到contact_id;2、根据contact_id查询data表;content://com.android.contacts/raw_contactscontent://com.android.contacts/data代码:package com.itheima.readcontacts;import android.app.Activity;import android.content.ContentResolver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void readContacts(View view){    System.out.println("=======");    ContentResolver resolver = getContentResolver();    Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");    Cursor cursor = resolver.query(uri, new String[]{"contact_id"}, null, null, null);    while(cursor.moveToNext()){        long contact_id = cursor.getLong(0);        System.out.println("contact_id===="+contact_id);        Uri dataUri = Uri.parse("content://com.android.contacts/data");        Cursor dataCursor = resolver.query(dataUri, new String[]{"mimetype","raw_contact_id","data1"}, "raw_contact_id=?",                 new String[]{contact_id+""}, null);        while(dataCursor.moveToNext()){            String mimetype = dataCursor.getString(0);            long raw_contact_id = dataCursor.getLong(1);            String data1 = dataCursor.getString(2);            System.out.println("mimetype===="+mimetype);            System.out.println("data1===="+data1);        }        dataCursor.close();        System.out.println("=========================================");    }    cursor.close();}}

11_联系人的还原(重点)

联系人相关的表:1、raw_contacts:存储了联系人的contact_id :记录数加1;2、data:存储了联系人信息字段的值;3、mimetypes:存储了联系人信息字段的类型;content://com.android.contacts/raw_contactscontent://com.android.contacts/data

代码:

package com.itheima.readcontacts;import android.app.Activity;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);}public void restoreContacts(View view) {    ContentResolver resolver = getContentResolver();    Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");    Cursor cursor = resolver.query(uri, null, null, null, null);    int rownum = cursor.getCount();    cursor.close();    int contact_id = rownum + 1;    // 在raw_contacts表中加入一点条数据    ContentValues values = new ContentValues();    values.put("contact_id", contact_id);    resolver.insert(uri, values);    Uri dataUri = Uri.parse("content://com.android.contacts/data");    // 姓名    ContentValues nameValues = new ContentValues();    nameValues.put("mimetype", "vnd.android.cursor.item/name");    nameValues.put("raw_contact_id", contact_id);    nameValues.put("data1", "wangwu");    resolver.insert(dataUri, nameValues);    // 手机号码    ContentValues phoneValues = new ContentValues();    phoneValues.put("mimetype", "vnd.android.cursor.item/phone_v2");    phoneValues.put("raw_contact_id", contact_id);    phoneValues.put("data1", "18910903535");    resolver.insert(dataUri, phoneValues);    // email    ContentValues emailValues = new ContentValues();    emailValues.put("mimetype", "vnd.android.cursor.item/email_v2");    emailValues.put("raw_contact_id", contact_id);    emailValues.put("data1", "wangwu@itcat.cn");    resolver.insert(dataUri, emailValues);}}

12_内容观察者

内容观察者(ContentObserver):可以监听到内容提供者中数据变化的情况;

13_短信窃听器(重点)

代码:

package com.itheima.smslistener;import android.app.Activity;import android.content.ContentResolver;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Handler;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    ContentResolver resolver = getContentResolver();    Uri uri = Uri.parse("content://sms/");    //注册一个内容观察者    resolver.registerContentObserver(uri, true, new MyObserver(new Handler()));}private class MyObserver extends ContentObserver{    public MyObserver(Handler handler) {        super(handler);    }    /**     * 内容提供者中数据发生变化时调用这个方法     */    @Override    public void onChange(boolean selfChange) {        super.onChange(selfChange);        //查询短信应用        ContentResolver resolver = getContentResolver();        Uri uri = Uri.parse("content://sms/");        Cursor cursor = resolver.query(uri, new String[]{"address", "date" , "type", "body"}, null, null, "date desc");        cursor.moveToNext();        String address = cursor.getString(0);        long date = cursor.getLong(1);        long type = cursor.getLong(2);        String body = cursor.getString(3);        System.out.println("address==="+address);        System.out.println("date==="+date);        System.out.println("type==="+type);        System.out.println("body==="+body);    }}}

0 0
原创粉丝点击