Android开发教程之ContentProvider数据存储

ContentProvider是Android中非常重要的一个系统组件,常用于实现应用程序间的数据共享。同时,也可以在应用内部使用ContentProvider实现数据的存储、查询和修改。本文将从以下几个方面入手讲解ContentProvider的使用及数据存储方法:

  1. ContentProvider的概念及使用方法
  2. 使用ContentProvider进行数据存储、查询和修改的具体操作
  3. 示例说明:使用ContentProvider存储联系人信息
  4. 示例说明:使用ContentProvider存储笔记信息

1. ContentProvider的概念及使用方法

ContentProvider是Android系统中用于共享数据的一种方式,通过ContentProvider可以将自己应用中的数据对外提供,其他应用可以通过ContentResolver访问共享的数据。ContentProvider在应用程序间提供了一种标准化的数据访问方式,对于需要共享数据的应用程序非常有用。

ContentProvider的使用方法如下:

  1. 实现ContentProvider类,继承自android.content.ContentProvider,并重写其中的方法。
  2. 在AndroidManifest.xml文件中注册ContentProvider,指定其访问权限。
  3. 在ContentProvider中实现数据存储、查询和修改等操作方法。

2. 使用ContentProvider进行数据存储、查询和修改的具体操作

ContentProvider中提供了如下几个方法,用于实现对数据的CRUD操作:

  1. insert(Uri uri, ContentValues values):向ContentProvider中添加数据。
  2. query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):从ContentProvider中查询数据。
  3. update(Uri uri, ContentValues values, String selection, String[] selectionArgs):更新ContentProvider中的数据。
  4. delete(Uri uri, String selection, String[] selectionArgs):删除ContentProvider中的数据。

3. 示例说明:使用ContentProvider存储联系人信息

我们可以使用ContentProvider来存储联系人信息,其具体实现如下:

  1. 首先实现MyContentProvider类,继承自android.content.ContentProvider类,并在AndroidManifest.xml文件中注册该类:
public class MyContentProvider extends ContentProvider {
    private ContactDbHelper mDbHelper;
    private static UriMatcher sUriMatcher = buildUriMatcher();
    private static final int CONTACT = 1;
    private static final int CONTACT_ID = 2;

    private static UriMatcher buildUriMatcher(){
        UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(CONTACT_AUTHORITY,"contact",CONTACT);
        uriMatcher.addURI(CONTACT_AUTHORITY,"contact/#",CONTACT_ID);
        return uriMatcher;
    }

    @Override
    public boolean onCreate() {
        mDbHelper = new ContactDbHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = mDbHelper.getReadableDatabase();
        Cursor cursor;
        switch (sUriMatcher.match(uri)){
            case CONTACT:
                cursor = db.query(ContactContract.Contact.TABLE_NAME,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder);
                break;
            case CONTACT_ID:
                String id = uri.getPathSegments().get(1);
                cursor = db.query(ContactContract.Contact.TABLE_NAME,
                        projection,
                        ContactContract.Contact._ID +"=?",
                        new String[]{id},
                        null,
                        null,
                        sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        return cursor;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        long id;
        switch (sUriMatcher.match(uri)){
            case CONTACT:
                id = db.insert(ContactContract.Contact.TABLE_NAME,null,values);
                getContext().getContentResolver().notifyChange(uri,null);
                return ContentUris.withAppendedId(uri,id);
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        int rows;
        switch (sUriMatcher.match(uri)){
            case CONTACT:
                rows = db.update(ContactContract.Contact.TABLE_NAME,
                        values,
                        selection,
                        selectionArgs);
                break;
            case CONTACT_ID:
                String id = uri.getPathSegments().get(1);
                rows = db.update(ContactContract.Contact.TABLE_NAME,
                        values,
                        ContactContract.Contact._ID+"=?",
                        new String[]{id});
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        if(rows > 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        return rows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        int rows;
        switch (sUriMatcher.match(uri)){
            case CONTACT:
                rows = db.delete(ContactContract.Contact.TABLE_NAME,selection,selectionArgs);
                break;
            case CONTACT_ID:
                String id = uri.getPathSegments().get(1);
                rows = db.delete(ContactContract.Contact.TABLE_NAME,
                        ContactContract.Contact._ID +"=?",
                        new String[]{id});
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        if(rows > 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        return rows;
    }
}
  1. 接着实现ContactContract类,定义表结构及字段:
public final class ContactContract {
    private ContactContract(){}
    public static final String CONTACT_AUTHORITY = "com.example.contacts";
    public static final String CONTACT_PATH = "contact";
    public static final String CONTACT_BASE_URI = "content://"+CONTACT_AUTHORITY+"/";
    public static final Uri CONTACT_URI = Uri.parse(CONTACT_BASE_URI+CONTACT_PATH);

    public static final class Contact implements BaseColumns{
        public static final String TABLE_NAME = "contact";
        public static final String NAME = "name";
        public static final String PHONE = "phone";
        public static final String EMAIL = "email";
    }
}
  1. 最后实现ContactDbHelper类,用于创建数据库及表结构:
public class ContactDbHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "contacts.db";
    private static final int DB_VERSION = 1;
    private static final String CREATE_CONTACT_TABLE = "CREATE TABLE IF NOT EXISTS "+ ContactContract.Contact.TABLE_NAME+" ("
            +ContactContract.Contact._ID+" INTEGER PRIMARY KEY,"
            +ContactContract.Contact.NAME+" TEXT NOT NULL,"
            +ContactContract.Contact.PHONE+" TEXT NOT NULL,"
            +ContactContract.Contact.EMAIL+" TEXT NOT NULL);";

    public ContactDbHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_CONTACT_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

有了以上三个类的支持,我们便可以在应用程序中进行联系人信息的存储、查询及修改操作。示例代码如下:

public class MainActivity extends AppCompatActivity {

    private ContentResolver mContentResolver;
    private ListView mListView;
    private ArrayList<Contact> mContactList = new ArrayList<>();
    private ContactAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContentResolver = getContentResolver();

        mListView = findViewById(R.id.list_view);
        mAdapter = new ContactAdapter();
        mListView.setAdapter(mAdapter);

        Button addButton = findViewById(R.id.add_button);
        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addContact();
            }
        });

        Button queryButton = findViewById(R.id.query_button);
        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                queryContacts();
            }
        });
    }

    private void addContact(){
        ContentValues values = new ContentValues();
        values.put(ContactContract.Contact.NAME,"张三");
        values.put(ContactContract.Contact.PHONE,"123456789");
        values.put(ContactContract.Contact.EMAIL,"zhangsan@example.com");
        Uri uri = mContentResolver.insert(ContactContract.CONTACT_URI,values);
        Log.d("MainActivity","inserted uri: "+uri);
    }

    private void queryContacts(){
        Cursor cursor = mContentResolver.query(ContactContract.CONTACT_URI,
                null,
                null,
                null,
                null);
        if(cursor != null){
            mContactList.clear();
            while (cursor.moveToNext()){
                Contact contact = new Contact();
                contact.setId(cursor.getInt(cursor.getColumnIndex(ContactContract.Contact._ID)));
                contact.setName(cursor.getString(cursor.getColumnIndex(ContactContract.Contact.NAME)));
                contact.setPhone(cursor.getString(cursor.getColumnIndex(ContactContract.Contact.PHONE)));
                contact.setEmail(cursor.getString(cursor.getColumnIndex(ContactContract.Contact.EMAIL)));
                mContactList.add(contact);
            }
            mAdapter.notifyDataSetChanged();
            cursor.close();
        }
    }

    private class ContactAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return mContactList.size();
        }

        @Override
        public Object 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) {
            if(convertView == null){
                convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item_contact,null);
            }
            TextView idText = convertView.findViewById(R.id.contact_id_text);
            TextView nameText = convertView.findViewById(R.id.contact_name_text);
            TextView phoneText = convertView.findViewById(R.id.contact_phone_text);
            TextView emailText = convertView.findViewById(R.id.contact_email_text);

            Contact contact = mContactList.get(position);

            idText.setText(String.valueOf(contact.getId()));
            nameText.setText(contact.getName());
            phoneText.setText(contact.getPhone());
            emailText.setText(contact.getEmail());

            return convertView;
        }
    }
}

4. 示例说明:使用ContentProvider存储笔记信息

除了可以存储联系人信息,我们还可以使用ContentProvider来存储笔记信息。其具体实现过程如下:

  1. 首先实现NoteContentProvider类,继承自android.content.ContentProvider类,并在AndroidManifest.xml文件中注册该类:
public class NoteContentProvider extends ContentProvider {
    private NoteDbHelper mDbHelper;
    private static UriMatcher sUriMatcher = buildUriMatcher();
    private static final int NOTE = 1;
    private static final int NOTE_ID = 2;

    private static UriMatcher buildUriMatcher(){
        UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(NoteContract.NOTE_AUTHORITY,"note",NOTE);
        uriMatcher.addURI(NoteContract.NOTE_AUTHORITY,"note/#",NOTE_ID);
        return uriMatcher;
    }

    @Override
    public boolean onCreate() {
        mDbHelper = new NoteDbHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = mDbHelper.getReadableDatabase();
        Cursor cursor;
        switch (sUriMatcher.match(uri)){
            case NOTE:
                cursor = db.query(NoteContract.Note.TABLE_NAME,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder);
                break;
            case NOTE_ID:
                String id = uri.getPathSegments().get(1);
                cursor = db.query(NoteContract.Note.TABLE_NAME,
                        projection,
                        NoteContract.Note._ID +"=?",
                        new String[]{id},
                        null,
                        null,
                        sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        return cursor;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        long id;
        switch (sUriMatcher.match(uri)){
            case NOTE:
                id = db.insert(NoteContract.Note.TABLE_NAME,null,values);
                getContext().getContentResolver().notifyChange(uri,null);
                return ContentUris.withAppendedId(uri,id);
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        int rows;
        switch (sUriMatcher.match(uri)){
            case NOTE:
                rows = db.update(NoteContract.Note.TABLE_NAME,
                        values,
                        selection,
                        selectionArgs);
                break;
            case NOTE_ID:
                String id = uri.getPathSegments().get(1);
                rows = db.update(NoteContract.Note.TABLE_NAME,
                        values,
                        NoteContract.Note._ID+"=?",
                        new String[]{id});
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        if(rows > 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        return rows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        int rows;
        switch (sUriMatcher.match(uri)){
            case NOTE:
                rows = db.delete(NoteContract.Note.TABLE_NAME,selection,selectionArgs);
                break;
            case NOTE_ID:
                String id = uri.getPathSegments().get(1);
                rows = db.delete(NoteContract.Note.TABLE_NAME,
                        NoteContract.Note._ID +"=?",
                        new String[]{id});
                break;
            default:
                throw new IllegalArgumentException("Invalid uri: "+uri);
        }
        if(rows > 0){
            getContext().getContentResolver().notifyChange(uri,null);
        }
        return rows;
    }
}
  1. 接着实现NoteContract类,定义表结构及字段:
public final class NoteContract {
    private NoteContract(){}
    public static final String NOTE_AUTHORITY = "com.example.notes";
    public static final String NOTE_PATH = "note";
    public static final String NOTE_BASE_URI = "content://"+NOTE_AUTHORITY+"/";
    public static final Uri NOTE_URI = Uri.parse(NOTE_BASE_URI+NOTE_PATH);

    public static final class Note implements BaseColumns{
        public static final String TABLE_NAME = "note";
        public static final String TITLE = "title";
        public static final String CONTENT = "content";
        public static final String DATE = "date";
    }
}
  1. 最后实现NoteDbHelper类,用于创建数据库及表结构:
public class NoteDbHelper extends SQLiteOpenHelper {
    private static final String DB_NAME = "notes.db";
    private static final int DB_VERSION = 1;
    private static final String CREATE_NOTE_TABLE = "CREATE TABLE IF NOT EXISTS "+ NoteContract.Note.TABLE_NAME+" ("
            +NoteContract.Note._ID+" INTEGER PRIMARY KEY,"
            +NoteContract.Note.TITLE+" TEXT NOT NULL,"
            +NoteContract.Note.CONTENT+" TEXT NOT NULL,"
            +NoteContract.Note.DATE+" INTEGER NOT NULL);";

    public NoteDbHelper(Context context){
        super(context,DB_NAME,null,DB_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_NOTE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

有了以上三个类的支持,我们便可以在应用程序中进行笔记信息的存储、查询及修改操作。示例代码如下:

```java
public class MainActivity extends AppCompatActivity {

private ContentResolver mContentResolver;
private ListView mListView;
private ArrayList<Note> mNoteList = new ArrayList<>();
private NoteAdapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mContentResolver = getContentResolver();

    mListView = findViewById(R.id.list_view);
    mAdapter = new NoteAdapter();
    mListView.setAdapter(mAdapter);

    Button addButton = findViewById(R.id.add_button);
    addButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            addNote();
        }
    });

    Button queryButton = findViewById(R.id.query_button);
    queryButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            queryNotes();
        }
    });
}

private void addNote(){
    ContentValues values = new ContentValues();
    values.put(NoteContract.Note.TITLE,"这是一条新笔记");
    values.put(NoteContract.Note.CONTENT,"这是第一行内容");
    values.put(NoteContract.Note.DATE,System.currentTimeMillis());
    Uri uri = mContentResolver.insert(NoteContract.NOTE_URI,values);
    Log.d("MainActivity","inserted uri: "+uri);
}

private void queryNotes(){
    Cursor cursor = mContentResolver.query(NoteContract.NOTE_URI,
            null,
            null,
            null,
            null);
    if(cursor != null){
        mNoteList.clear();
        while (cursor.moveToNext()){
            Note note = new Note();
            note.setId(cursor.getInt(cursor.getColumnIndex(NoteContract.Note._ID)));
            note.setTitle(cursor.getString(cursor.getColumnIndex(NoteContract.Note.TITLE)));
            note.setContent(cursor.getString(cursor.getColumnIndex(NoteContract.Note.CONTENT)));
            note.setDate(cursor.getLong(cursor.getColumnIndex(NoteContract.Note.DATE)));
            mNoteList.add(note);
        }
        mAdapter.notifyDataSetChanged();
        cursor.close();
    }
}

private class NoteAdapter extends BaseAdapter{

    @Override
    public int getCount() {
        return mNoteList.size();
    }

    @Override
    public Object getItem(int position) {
        return mNoteList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发教程之ContentProvider数据存储 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • C语言中scanf的用法举例

    让我们开始介绍C语言中scanf的用法。 什么是scanf? scanf函数是C语言中的一个标准库函数,用于从标准输入中读取一定格式的数据。其函数原型为: int scanf(const char *format, …) 我们通常调用scanf函数时,需要向其传递一个格式字符串,以指明我们要读取的数据的格式,此外,我们还需要传递一个或多个指向我们要存储读…

    other 2023年6月27日
    00
  • win系统中XP必联电子阿里智能路由器动态IP上网的详细设置教程

    Win系统中XP必联电子阿里智能路由器动态IP上网的详细设置教程 本教程将详细介绍如何在Windows XP操作系统中使用XP必联电子阿里智能路由器进行动态IP上网设置。以下是完整的攻略: 步骤一:连接路由器 将XP必联电子阿里智能路由器连接到电源,并确保其正常启动。 使用网线将路由器的LAN口与计算机的网卡连接。 步骤二:访问路由器设置页面 打开任意浏览器…

    other 2023年7月31日
    00
  • 在cmd命令行里进入和退出Python程序的方法

    在CMD命令行中,进入和退出Python程序需要使用Python解释器。下面是进入和退出Python程序的完整攻略。 进入Python程序 要进入Python程序,我们首先需要在CMD命令行中打开Python解释器。这可以通过输入python命令来实现。打开Python解释器后,我们就可以在命令行中开始运行Python代码了。 示例代码: C:\> p…

    other 2023年6月26日
    00
  • Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案 在使用ListView显示图片时,经常会出现图片错位、重复、闪烁等问题。这些问题的产生原因是因为ListView的ListViewItem View的复用机制。本文将分析产生这些问题的原因,并提供对应的解决方案。 问题产生的原因 当ListView滑动时,会重复使用已经创建的Li…

    other 2023年6月26日
    00
  • sshipv6

    当然,我很乐意为您提供sshipv6的完整攻略。以下是详细的步骤和示例: 步骤1:了解sship6 sshipv6是一种基于IPv6的安全传输协议,用于在不安全的网络上安全地传输数据。它使用加密和身份验证来保护数据的机密性和完整性。 步骤2:安装sshipv6 以下是在Ubuntu上安装sshipv6的示例: 打开终端; 运行以下命令以更新软件包列表: su…

    other 2023年5月6日
    00
  • Ant Design of Vue的树形控件Tree的使用及说明

    Ant Design 是一款优秀的 React UI 库,它的 Vue 版本 Ant Design of Vue 同样也是备受欢迎的UI框架之一。Ant Design of Vue中提供了一种常用的可展开、可收起的树形控件 Tree,下面我来详细介绍如何使用及说明。 安装 可以通过 npm 或 yarn 安装 Ant Design of Vue。 使用 np…

    other 2023年6月27日
    00
  • Windows10下利用DOSBOX和MASM32搭建汇编语言开发环境

    下面是详细讲解如何在Windows 10下利用DOSBOX和MASM32搭建汇编语言开发环境的完整攻略。 步骤一:下载和安装DOSBOX 首先,我们需要下载并安装DOSBOX软件。DOSBOX是一个模拟MS-DOS环境的免费软件,它可以帮助我们在Windows 10下运行汇编语言开发环境。 可以在官方网站(https://www.dosbox.com/)下载…

    other 2023年6月26日
    00
  • Golang应用程序性能优化技巧分享

    Golang应用程序性能优化技巧分享 本文将详细介绍如何对 Golang 应用程序进行性能优化,以提高应用程序的性能和效率。本攻略将介绍以下步骤: 分析应用程序性能问题 使用性能分析工具优化应用程序 实践优化技巧和实例 分析应用程序性能问题 分析应用程序的性能问题非常重要,我们需要找到导致应用程序性能瓶颈的因素。我们可以使用一些工具和技术来获取应用程序的性能…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部