文章目录

  • Android文件权限简述
  • ContentProvider 内容提供者
  • ContentResolver
  • URI
    • 什么是URI
    • URI示例
    • URI和URL
  • ContentProvider实例
    • ContentProvider实例1
    • ContentProvider实例2

Android文件权限简述

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

drwxrwx-x

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

URI示例

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

原生写法

content://com.android.contacts/contacts/

常量写法

ContactsContract.Contacts.CONTENT_URI

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

URI和URL

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

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

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

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

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

ContentProvider实例

ContentProvider实例1

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

首先创建一个ContentProvider

指定URI的路径

    @Overridepublic 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;}

然后在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"><Buttonandroid:id="@+id/btn1"android:text="访问ContentProvider"android:onClick="btnOnclick"android:layout_width="match_parent"android:layout_height="wrap_content" />
</LinearLayout>

然后编写页面文件,新增一个按钮,用于访问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);}}

编写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);}@Overridepublic void onCreate(SQLiteDatabase db) {//创建表db.execSQL("create table person(_id integer primary key autoincrement,name varchar(20))");}@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
}

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

private DBHelper mDBHelper;
private SQLiteDatabase mDatabase;@Overridepublic boolean onCreate() {mDBHelper=new DBHelper(getContext());return true;}

在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/personsUriMatcher.addURI(authority,"person",PERSONS);//content://myContentProvider/person/idsUriMatcher.addURI(authority,"person/#",PERSONS_ID);}

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

 @Overridepublic 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);}

完成MyContentProvider的insert方法

   @Overridepublic 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的第三个参数codeint 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;}

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

    <Buttonandroid:id="@+id/btn2"android:text="插入数据"android:onClick="btnOnclick2"android:layout_width="match_parent"android:layout_height="wrap_content" />

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","插入数据完成");}

实现插入数据的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);}}}

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

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

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

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

009 Android之ContentProvider相关推荐

  1. provider android简书,Android 使用ContentProvider在应用间共享数据

    Android 使用ContentProvider在应用间共享数据 题图 www.gratisography.com 在开发的过程中,有时会有需求要实现应用程序之间实现数据共享,在Android系统中 ...

  2. Android之ContentProvider数据存储

    一.ContentProvider保存数据介绍 一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数 ...

  3. Android About ContentProvider

    Contents: ContentProvider Structural Analysis What is URI? Query Attribute,SQL UNION   ContentProvid ...

  4. Android之ContentProvider

    文章目录 简介 ContentResolver.ContentProvider和URI Uri简介 Uri处理 自定义ContentProvider 1. 新建类继承ContentProvider 2 ...

  5. android使用ContentProvider初始化sdk,初始化时机

    文章目录 系列目录 前言 什么是ContentProvider sdk初始化 常规初始化方案 使用ContentProvider初始化sdk 为什么ContentProvider可以作为sdk初始化 ...

  6. Android【ContentProvider案例】

    ContentProvider实现跨程序数据共享,实例如下: 数据库基于数据存储中的使用的数据库,点击Here 1]ContentProvider类 public class ContentProvi ...

  7. android中contentProvider及ContentResolver

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程 这个技术是解决应用之间的一个调用,如常见的应用间数据库查询,内容提供者暴露接口,内容解析器Conten ...

  8. android 53 ContentProvider内容提供者

    ContentProvider内容提供者:像是一个中间件一样,一个媒介一样,可以以标准的增删改差操作对手机的文件.数据库进行增删改差.通过ContentProvider查找sd卡的音频文件,可以提供标 ...

  9. Android 中ContentProvider和Uri详解

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给 ...

最新文章

  1. MySQL 5.6 解决InnoDB: Error: Table “mysql“.“innodb_table_stats“ not found.问题
  2. ubuntu13.04下安装jdk7
  3. .Net Framwork概述
  4. Lindley equation
  5. C注释   转换为   C++注释
  6. 说一下安卓的touch事件分发机制
  7. COJ1183(计算表达式的值)
  8. 虚拟化时代 智能数据管理架构才是王道
  9. [COCI2011-2012#7] KAMPANJA
  10. JAVA代码查错试题集
  11. 使用J-link+J-Flash给STM32芯片烧写序列号
  12. java基础--枚举的运用
  13. 毕业论文参考文献中出版社和出版地的查询
  14. 漫画:鉴权与安全访问控制的技术血脉
  15. 那些超好听却不红的歌
  16. 【Android】开屏页面
  17. cote dlvoire_科特迪瓦-COTE D‘ IVOIRE-阿比让-ABIDJAN-港口介绍,港口介绍-环球运费网...
  18. (干货)电源方案合集
  19. 【kafka】Error while fetching metadata xxx: {TEST=LEADER_NOT_AVAILABLE}
  20. 耳机是如何是发出声音的?

热门文章

  1. 成功解决AttributeError: module tensorflow has no attribute placeholder
  2. DayDayUp:那些属于程序猿江湖的鄙视链(看完别笑^~^,哈哈,haha)
  3. 成功解决Module Not Found Error : No module named mglearn
  4. Dataset之Fashion-MNIST:Fashion-MNIST数据集简介、下载、使用方法之详细攻略
  5. 成功解决cv2.error: C:\projects\opencv-python\opencv\modules\imgproc\src\resize.cpp:4044: error: (-215) s
  6. 成功解决AttributeError: module 'string' has no attribute 'find'
  7. 让Socket穿透Windows防火墙
  8. Python小游戏之 - 飞机大战 !
  9. Ubuntu 16.04安装unrar解压RAR文件
  10. GPS 气压计高度测量