当前位置:   article > 正文

009 Android之ContentProvider_contentprovider assets

contentprovider assets

Android文件权限简述

关于Android中关于文件权限的具体解释

drwxrwx-x
  • 1

第一位:-表示文件,d表示文件夹,l表示连接

二三四:所有者权限,即程序本身访问文件或目录的权限

五六七:所在群组的权限

八九十:其他用户权限

r表示读权限,w表示写权限,x表示可执行权限,-表示没有权限,用数字表示法:r=4,w=2,x=1,-=0

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LAkutBXO-1623813168455)(009 Android之ContentProvider.assets/1623330084594.png)]

ContentProvider 内容提供者

ContentProvider 内容提供者是安卓中的四大组件之一,为什么需要ContentProvider?

  • Android中的应用程序运行在不同的进程空间中,因此不同应用程序中的数据是不能够直接访问的
  • 为了增强程序之前的数据共享能力,Android系统虽然提供了像SharedPrefences这类简单的跨程序边界的访问方法,但这些方法都存在一定的局限性

在这里插入图片描述

ContentProvider提供了应用之间共享数据的方法,应用程序通过ContentProvider访问数据而不需要关心数据具体的存储及访问过程,这样既提高了数据的访问效率,同时也保护了数据

Android系统中附带的ContentProvider包括:

  • Browser:存储如浏览器的信息
  • CallLog:存储通话记录等信息
  • Contacts:存储联系人等信息
  • MediaStore:存储媒体文件的信息
  • Settings:存储设备的设置和首选项信息

关于ContentProvider数据集

ContentProvider数据集类似于数据库的数据表,每行是一条记录,每列具有相同的数据类型,如下所示

在这里插入图片描述


ContentResolver

应用程序使用ContentResolver对象,利用URI,才能访问ContentProvider提供的数据集

在这里插入图片描述

URI

什么是URI

URI:通用资源标志符(Uniform Resource Identifer),用来定位远程或本地的可用资源;URI的基本格式如下

content://<authority>/<data_path>/<id>
  • 1
  • content 固定前缀
  • authority 授权者名称,用来确定具体由哪一个ContentProvider提供资源
  • data_path 数据路径,用来确定请求的是哪个数据集
  • id 数据编号,用来匹配数据集中_ID字段的值,如果请求的数据不止一条则可以省略

URI示例

content://contacts/people/ 表示全部联系人信息的URI
content://contacts/people/1 表示ID=1的联系人信息的URI
  • 1
  • 2

原生写法

content://com.android.contacts/contacts/
  • 1

常量写法

ContactsContract.Contacts.CONTENT_URI
  • 1

由于URI比较长,而且容易写错,所以在Android中定义了一些辅助类和常量来代替这些字符串

URI和URL

在Android中广泛应用URI,而不是URL。URL是标识资源的物理位置,相当于文件的路径,例如:

http://www.163.com/logo.png
  • 1

URI则是标识资源的逻辑位置,并不提供资源的具体位置。

比如说电话本中的数据,如果用URL来标识的话,可能会是一个很复杂的文件结构,而一旦文件的存储路径改变,URL也必须改动。

但如果是URI,则可以用诸如content://contacts/people/这样容易记录的逻辑地址来标识,而且并不需要关心文件的具体位置,即使文件位置改动也不需要做变化

ContentProvider实例

ContentProvider实例1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UYxXHIJS-1623813168464)(009 Android之ContentProvider.assets/1623412259686.png)]

首先创建一个ContentProvider

在这里插入图片描述

指定URI的路径

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        // TODO: Implement this to handle query requests from clients.
        Log.d("GuiShou","ContentProvider::query");
        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后在query方法中输出一条日志

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn1"
        android:text="访问ContentProvider"
        android:onClick="btnOnclick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

然后编写页面文件,新增一个按钮,用于访问ContentProvider

public void btnOnclick(View view) {
        //获取内容解析者
        ContentResolver resolver=getContentResolver();

        //创建URI对象
        Uri uri= Uri.parse("content://myContentProvider");

        //查询
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            Cursor cursor= resolver.query(uri,null,null,null,null,null);
            Log.d("GuiShou","Cursor::"+cursor);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

编写onClick方法,利用ContentResolver调用ContentProvider的resolver方法

在这里插入图片描述

按钮点击之后,ContentResolver会检测URI所指向的ContentProvider是否存在;如果存在,则调用该ContentProvider的query方法。所以URI的路径至关重要,如果不存在,则后面的代码无法执行成功

ContentProvider实例2

基于上个实例的代码,在自己的ContentProvider中访问数据库。首先需要准备数据

在这里插入图片描述

首先新建一个类名为DBHelper,继承自SQLiteOpenHelper

public class DBHelper extends SQLiteOpenHelper {
    public DBHelper(@Nullable Context context) {
        super(context, "mydata.db", null, 1);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建表
        db.execSQL("create table person(_id integer primary key autoincrement,name varchar(20))");

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

重写三个函数,在onCreate函数中创建一个数据库文件

private DBHelper mDBHelper;
private SQLiteDatabase mDatabase;

   @Override
    public boolean onCreate() {
        mDBHelper=new DBHelper(getContext());
        return true;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在MyContentProvider类内创建DBHelper对象,并在onCreate方法中进行初始化

   public static UriMatcher sUriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
    private static final String authority = "myContentProvider";
    private static final int PERSONS =0x111 ;
    private static final int PERSONS_ID = 0x222;

    static {
        //content://myContentProvider/person
        sUriMatcher.addURI(authority,"person",PERSONS);
         //content://myContentProvider/person/id
        sUriMatcher.addURI(authority,"person/#",PERSONS_ID);
    }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

接着创建一个UriMatcher,并新增两个URI路径

 @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO: Implement this to handle requests to insert a new row.
        //获取数据库对象
        mDatabase=mDBHelper.getReadableDatabase();
        //插入values数据
        long id= mDatabase.insert("person",null,values);
        //返回组合好的URI对象://content://myContentProvider/person/
        return ContentUris.withAppendedId(uri,id);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

完成MyContentProvider的insert方法

   @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        // TODO: Implement this to handle query requests from clients.
        Log.d("GuiShou","ContentProvider::query");

        //获取数据库对象
        mDatabase=mDBHelper.getReadableDatabase();
        //match方法返回的是addURI的第三个参数code
        int code=sUriMatcher.match(uri);
        if (code==PERSONS) {
            return mDatabase.query("person",new String[]{"_id","name"},null,null,null,null,null);
        }else if (code==PERSONS_ID) {
            long id= ContentUris.parseId(uri);
            return mDatabase.query("person",new String[]{"_id","name"},"_id=?",new String[]{""+id},null,null,null);
        }

        return null;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

完成MyContentProvider的query方法。现在在MyContentProvider中还没有数据,我们需要在里面新增数据,查询的时候才能显示出来

    <Button
        android:id="@+id/btn2"
        android:text="插入数据"
        android:onClick="btnOnclick2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

xml中新增一个按钮,用于插入数据

 //插入数据按钮
    public void btnOnclick2(View view) {
        //获取内容解析者
        ContentResolver resolver=getContentResolver();

        //创建URI对象
        Uri uri= Uri.parse("content://myContentProvider");

        //创建数据
        for (int i = 0; i <100 ; i++) {
            ContentValues values=new ContentValues();
            values.put("_id",""+i);
            values.put("name","王大锤"+i);
            resolver.insert(uri,values);
        }
		Log.d("GuiShou","插入数据完成");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

实现插入数据的onClick代码

  public void btnOnclick(View view) {
        //获取内容解析者
        ContentResolver resolver=getContentResolver();

        //查询
        Uri uri1= Uri.parse("content://myContentProvider/person");
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            Cursor cursor= resolver.query(uri1,null,null,null,null,null);
            Log.d("GuiShou","Cursor::"+cursor);

            while (cursor.moveToNext()){
                int id= cursor.getInt(0);
                String name=cursor.getString(1);
                Log.d("GuiShou","id:"+id+"name:"+name);
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

接着完成查询数据的按钮,到此所有代码编写完成。点击插入数据按钮,效果如图:

在这里插入图片描述

执行流程首先会通过ContentResolver找到对应的uri,并执行ContentProvider里的insert方法,insert则调用DBHelper的onCreate创建数据库

点击查询按钮,可以看到刚刚被插入的数据

在这里插入图片描述

同样是通过ContentResolver找到对应的uri,调用了ContentProvider的query方法查询了所有person数据

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/941065
推荐阅读
相关标签
  

闽ICP备14008679号