在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. 2月9日 《Java 8实战》读后感

    第一部分 基础知识 第3章 Lambda表达式 使用函数式接口 Predicate Consumer Function 第二部分 函数式数据处理 第4章 引入流 第5章 使用流 第6章 用流收集数据 ...

  2. Python3基本数据类型之列表

    1.初识列表 列表(List)是Python3中的"容器型"数据类型. 列表通过中括号把一堆数据括起来的方式形成,列表的长度不限. 列表里面的元素可以是不同的数据类型,但是一般是相 ...

  3. Oracle、MySQL和Sqlserver的事务管理、分页和别名的区别

    1.在mysql中事务默认是自动提交的,只有设置autocommit为0的时候,才用自己commit(commit--rollback回滚) 2.但是在oracle中必须自己commit;不然就只能结 ...

  4. ASP.NET Core on K8S深入学习(4)你必须知道的Service

    本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 前面几篇文章我们都是使用的ClusterIP供集群内部访问,每个Pod都有一个 ...

  5. Winform改变Textbox边框颜色

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. LD_PRELOAD和ld --wrap

    前言 LD_PRELOAD和ld --wrap都能实现不修改原始代码,替换指定函数的实现.通常我们会使用这些方法,替换如malloc)()/free().read()/write()等函数,并在替换函 ...

  7. c# 读取 txt 文件中数据(int)

    今天在学图的算法做测试是,需要读取文本文件中的点坐标,本来很简单的事情,折腾了半天,记录一下找到的一种简单粗暴的解决方法,以便以后查看. 第一种方法 : StringReader string lin ...

  8. 小白学Python(2)——常用Python编程工具,Python IDE

    下载好Python,但是如何开始编程呢? 有几种方法, 1.第一个就是command lind 即为命令行的方式,也就是我们常说的cmd. 输入 win+ cmd 在命令行中再输入 python,即可 ...

  9. 《深入理解Java虚拟机》- JVM如何进行异常处理

    一.Java异常 在程序中,错误可能产生于程序员没有预料到的各种情况,或者超出程序员可控范围的环境,例如用户的坏数据.试图打开一个不存在的文件等.为了能够及时有效地处理程序中的运行错误,Java 专门 ...

  10. Unity进阶:用AssetBundle和Json做了一个玩家登陆界面

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...