在android中,除了存放在外部存储的共享目录下的数据,各个应用的数据库文件,资源等都是私有的,其他应用没有访问权限。所以有了ContentProvider,不包含功能逻辑,用于不同应用进程间共享数据,是数据访问的接口。

一、工作流程

为了快速熟悉ContentProvider的工作流程。先创建一个没有具体实现的ContentProvider。

1、创建ContentProvider

只要继承android提供的ContentProvider并实现抽象方法即可。

import android.content.ContentProvider;

import android.content.ContentValues;

import android.database.Cursor;

import android.net.Uri;

import android.os.Process;

import android.util.Log;

public class MyContentProvider extends ContentProvider {

    private final static String Tag="ContentProvider";

    public MyContentProvider() {

    }

    @Override

    public int delete(Uri uri, String selection, String[] selectionArgs) {

        Log.d(Tag,"................delete");

        return 0;

    }

    @Override

    public String getType(Uri uri) {

        return null;

    }

    @Override

    public Uri insert(Uri uri, ContentValues values) {

        Log.d(Tag,".................insert");

        return null;

    }

    @Override

    public boolean onCreate() {

        Log.d(Tag,"..................onCreate,PID="+ Process.myPid());

        return false;

    }

    @Override

    public Cursor query(Uri uri, String[] projection, String selection,

                        String[] selectionArgs, String sortOrder) {

        Log.d(Tag,".................query");

        return null;

    }

    @Override

    public int update(Uri uri, ContentValues values, String selection,

                      String[] selectionArgs) {

      Log.d(Tag,"...................update");

        return 0;

    }

}

  

2、注册

应用的组件都要在清单文件里面注册。

为了说明ContentProvider工作在不同的进程间,使用process属性。

3、访问

使用URI定位一个ContentProvide,URI值为注册时的authorities属性。

import android.content.ContentResolver;

import android.net.Uri;

import android.os.Process;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private final static String Tag="MainActivity";

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Log.d(Tag,"..............onCreate PID="+ Process.myPid());

        Uri uri=Uri.parse("content://org.su.example.contentper");

        ContentResolver contentResolver=getContentResolver();

        contentResolver.query(uri,null,null,null,null);

        contentResolver.query(uri,null,null,null,null);

        contentResolver.delete(uri,null,null);

        contentResolver.delete(uri,null,null);

    }

}

  

ContentResolver是android提供访问ContentProvide的类。

日志输出

二、数据形式

ContentProvide的接口看起来就像数据库的操作,增删改查。ContentProvide的数据形式也多是组织成表格的形式。每个表有多列。表的一行代表一个记录。这就意味着我们要使用一个ContentProvide还要知道它有哪些表,表结构是什么样的。一般android提供的ContentProvide都有一个说明类。例如访问android的图片的表结构可以通过MediaStore.Images获得,联系人信息通过ContactsContract.Contacts获得。

三、自定义完整的ContentProvider

很多文章的表结构用的是book(id,name,author);

使用SQLiteOpenHelper

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

public class DbOpenHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "book.db";

    public static final String TABLE_NAME = "book";

    private static final int DB_VERSION = 1;

    // book表

    private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS "

            + TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT,"+" author TEXT)";

    public DbOpenHelper(Context context) {

        super(context,DB_NAME,null,DB_VERSION);

    }

    @Override

    public void onCreate(SQLiteDatabase db) {

        db.execSQL(CREATE_BOOK_TABLE);

    }

    @Override

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

        // TODO ignored

    }

}

  

BookProvider代码

import android.content.ContentProvider;

import android.content.ContentValues;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.net.Uri;

import android.util.Log;

public class BookProvider extends ContentProvider {

    private static final String TAG = "BookProvider";

    public static final String AUTHORITY = "org.su.book.provider";

    public static final Uri URI = Uri.parse("content://"

            + AUTHORITY + "/book");

    private Context mContext;

    private SQLiteDatabase mDb;

    @Override

    public boolean onCreate() {

        Log.d(TAG,"onCreate,current thread:"+ Thread.currentThread().getName());

        mContext = getContext();

        //初始化数据

        initProviderData();

        return true;

    }

    private void initProviderData() {

        mDb = new DbOpenHelper(mContext).getWritableDatabase();

        mDb.execSQL("delete from " + DbOpenHelper.TABLE_NAME);

        mDb.execSQL("insert into book values(3,'Android','Android');");

        mDb.execSQL("insert into book values(4,'Ios','Ios');");

        mDb.execSQL("insert into book values(5,'Html5','web');");

    }

    @Override

    public Cursor query(Uri uri,String[] projection,String selection,

                        String[] selectionArgs,String sortOrder) {

        String table = getTableName(uri);

        if (table == null) {

            throw new IllegalArgumentException("Unsupported URI: " + uri);

        }

        return mDb.query(table,projection,selection,selectionArgs,null,

                null,sortOrder,null);

    }

    @Override

    public String getType(Uri uri) {

        Log.d(TAG,"getType");

        return null;

    }

    @Override

    public Uri insert(Uri uri,ContentValues values) {

        Log.d(TAG,"insert");

        String table = getTableName(uri);

        if (table == null) {

            throw new IllegalArgumentException("Unsupported URI: " + uri);

        }mDb.insert(table,null,values);

        mContext.getContentResolver().notifyChange(uri,null);

        return uri;

    }

    @Override

    public int delete(Uri uri,String selection,String[] selectionArgs) {

        Log.d(TAG,"delete");

        String table = getTableName(uri);

        if (table == null) {

            throw new IllegalArgumentException("Unsupported URI: " + uri);

        }

        int count = mDb.delete(table,selection,selectionArgs);

        if (count > 0) {

            getContext().getContentResolver().notifyChange(uri,null);

        }

        return count;

    }

    @Override

    public int update(Uri uri,ContentValues values,String selection,

                      String[] selectionArgs) {Log.d(TAG,"update");

        String table = getTableName(uri);

        if (table == null) {

            throw new IllegalArgumentException("Unsupported URI: " + uri);

        }

        int row = mDb.update(table,values,selection,selectionArgs);

        if (row > 0) {

            getContext().getContentResolver().notifyChange(uri,null);

        }

        return row;

    }

    private String getTableName(Uri uri) {

        String tableName = null;

        if(uri.equals(URI))

            tableName=DbOpenHelper.TABLE_NAME;

        return tableName;

    }

}

  

在MainActivity中访问

Uri uri=Uri.parse("content://org.su.book.provider/book");

        ContentResolver contentResolver=getContentResolver();

        ContentValues values = new ContentValues();

        values.put("_id",6);

        values.put("name","程序设计");

        values.put("author","c");

        contentResolver.insert(uri,values);

        Cursor bookCursor =contentResolver.query(uri,new String[]

                {"_id","name","author"},null,null,null);

        while (bookCursor.moveToNext()) {

            int id= bookCursor.getInt(0);

            String name = bookCursor.getString(1);

            String author =bookCursor.getString(2);

            Log.d(Tag,"query book:" +"id ="+id+",name ="+name+",author ="+author);

        }

        bookCursor.close();

  

日志输出:

四大组件初始之ContentProvider的更多相关文章

  1. Android四大组件之一:ContentProvider(内容提供者)

    Android中还提供了名为ContentProvider(内容提供者),可以向其他应用提供数据,但不常用,除非是同一公司开发的App,可以向不同应用提供数据.虽然为Android的四大组件之一,但用 ...

  2. 四大组件初始之Broadcast

    在进行应用设计时,需要获取很多环境参数,像电量,音量,亮度,网络等.相比较每次去询问android这些信息改变了吗.让Android告诉我们,这些信息改变了更加合理.只要这些信息改变,Android通 ...

  3. Android 四大组件学习之ContentProvider五

    上几节学习了ContentProvider的实际用途,读取短信.插入短信,读取联系人.插入联系人等. 本节课在学习ContentProvider的观察者. 在生活中有第三方的软件.比方什么短信软件.此 ...

  4. Android 四大组件学习之ContentProvider二

    上节学习了什么是ContentProvider.以及ContentProvider的作用.以及什么是URL.本节就对上节学习的知识做一个实践,也就是定义自己的ContentProvider 好.实践是 ...

  5. Android 四大组件学习之ContentProvider三

    上节课学习怎样自己创建一个ContentProvider.以及用ContentResolver去操作ContentProvider. 今天我们用系统提供的ContentProvider. 先来个简单的 ...

  6. Android 四大组件学习之ContentProvider四

    上节我们学习了怎样去读取系统短信以及插入一条短信到系统中. 本节我们学习怎样获取系统的联系人,以及插入一条联系人 好.废话不多说了,直接操作. 首先和读取短信一样,先找到联系人在数据库中的位置. wa ...

  7. Android四大组件与进程启动的关系(转)

    一. 概述 Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可 ...

  8. 四大组件之ContentProvider

    前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...

  9. 初学android:四大组件之contentprovider

    一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...

随机推荐

  1. 轻量级移动端类库,大小20多k,支持多指触摸。

    /* * 移动端 公共类库 * 作者:hqs */ (function(global, factory) { // cmd commonjs if (typeof module === "o ...

  2. python 之 前端开发(基本选择器、组合选择器、 交集与并集选择器、序列选择器、属性选择器、伪类选择器、伪元素选择器)

    11.3 css 11.31 基本选择器 11.311 id选择器 根据指定的id名称,在当前界面中找到对应的唯一一个的标签,然后设置属性 <!DOCTYPE html> <html ...

  3. mpvue微信小程序项目踩坑记录

    1.mpvue入门教程, http://mpvue.com/mpvue/quickstart.html # . 先检查下 Node.js 是否安装成功 $ node -v v8.9.0 $ npm - ...

  4. VMware安装Centos7虚拟机

    首先安装虚拟机很简单,所以呢,具体的安装过程就引用别人的博客,这篇文字很详细,引用之后会在后面加上一些遇到的问题: 原文:https://blog.csdn.net/babyxue/article/d ...

  5. Day4 chart基本属性分析

    属性设置是基于chart实例的,所以我们必须先获取一个chart画板实例,获取方式: G2.Chart.创建 Chart 的方式如下: new G2.Chart({ container: {strin ...

  6. (18)ASP.NET Core 基于现有数据库创建EF模型(反向工程)

    1.简介 Entity Framework Core可通过数据库提供给应用程序的插件访问许多不同的数据库.我们可以通过使用Entity Framework Core构建执行基本数据访问的ASP.NET ...

  7. C#使用NLOG System.TypeInitializationException,类型初始值设定项引发异常

    C#如何使用NLOG,网上有很多介绍,本次使用时遇到一个问题,使用NLOG写日志时,出现初始化异常,基本异常信息如下: System.AggregateException: 发生一个或多个错误. -- ...

  8. 「每日五分钟,玩转JVM」:线程独占区

    前言 如果我们对计算机组成有所了解,那么我们一定会知道在计算机中有一块儿特殊的区域,称之为寄存器,寄存器包括了指令寄存器和程序计数器,这两样位于CPU中,作为程序运行的大脑来控制程序的运行和流转. 而 ...

  9. C笔记_常用快捷键

    1.第一部分 Ctrl + up/down 以光标所在行为中心上下移动文本: Ctrl + left/right 左右跳过一个单词或符号: Ctrl + end 跳至文本末尾: Ctrl + dele ...

  10. Spring框架之JdbcTemplate

    Spring框架之JdbcTemplate 一.JdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到Jd ...