ContentProvider数据库共享之读写权限与数据监听
前言:随着工作的时间越来越长,越来越觉得自己学知识的速度太慢,原定的两年,现在已经过了快九个月了,仍然对很多知识懵懵懂懂,对JAVA理解的还是不够彻底,现在终于有点时间能放纵地看一些自己感兴趣的东西了,不知道这样的时间能持续多久,但抓住每一分
前言:随着工作的时间越来越长,越来越觉得自己学知识的速度太慢,原定的两年,现在已经过了快九个月了,仍然对很多知识懵懵懂懂,对JAVA理解的还是不够彻底,现在终于有点时间能放纵地看一些自己感兴趣的东西了,不知道这样的时间能持续多久,但抓住每一分能利用的时间把自己变得强大,终有一天,你会成为你想成为的人。记住,你永远是最棒的!
1、《ContentProvider数据库共享之——概述》
2、《ContentProvider数据库共享之——实例讲解》
3、《ContentProvider数据库共享之——MIME类型与getType()》
4、《ContentProvider数据库共享之——读写权限与数据监听》
经过前面三篇文章,我想大家对ContentProvider已经有了大部分的了解,但在第二篇中,我们提到过一个函数:
getContentResolver().notifyChange(uri, null);
在这之前,还有个ContentProvider共享数据库读写权限的知识 给大家补上;
一、数据库读写权限
1、概述
先看下面这段代码:
<provider android:name=".PeopleContentProvider" android:authorities="com.harvic.provider.PeopleContentProvider" android:exported="true" android:permission="com.harvic.contentProviderBlog" android:readpermission="com.harvic.contentProviderBlog.read" android:writepermission="com.harvic.cotentProviderBlog.write"></provider>
- exported:这个属性用于指示该服务是否能被其他程序应用组件调用或跟他交互; 取值为(true | false),如果设置成true,则能够被调用或交互,否则不能;设置为false时,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。具体参见:《Permission Denial: opening provider 隐藏的android:exported属性的含义》
-
readPermission:使用Content Provider的查询功能所必需的权限,即使用ContentProvider里的query()函数的权限;
-
writePermission:使用ContentProvider的修改功能所必须的权限,即使用ContentProvider的insert()、update()、delete()函数的权限;
-
permission:客户端读、写 Content Provider 中的数据所必需的权限名称。 本属性为一次性设置读和写权限提供了快捷途径。 不过,readPermission和writePermission属性优先于本设置。 如果同时设置了readPermission属性,则其将控制对 Content Provider 的读取。 如果设置了writePermission属性,则其也将控制对 Content Provider 数据的修改。也就是说如果只设置permission权限,那么拥有这个权限的应用就可以实现对这里的ContentProvider进行读写;如果同时设置了permission和readPermission那么具有readPermission权限的应用才可以读,拥有permission权限的才能写!也就是说只拥有permission权限是不能读的,因为readPermission的优先级要高于permission;如果同时设置了readPermission、writePermission、permission那么permission就无效了。
2、实例
(1)有关自定义权限
<provider android:name=".PeopleContentProvider" android:authorities="com.harvic.provider.PeopleContentProvider" android:exported="true" android:readpermission="com.harvic.contentProviderBlog.read"></provider>
<permission android:name="com.harvic.contentProviderBlog.read" android:label="provider pomission" android:protectionlevel="normal"></permission>
<uses-permission android:name="com.harvic.contentProviderBlog.read"></uses-permission>
(2)、带有权限的ContentProvder实例
首先在ContentProviderBlog中首先向系统申请两个权限:
分别对应读数据库权限和写数据库权限
<permission android:name="com.harvic.contentProviderBlog.read" android:label="provider read pomission" android:protectionlevel="normal"></permission> <permission android:name="com.harvic.contentProviderBlog.write" android:label="provider write pomission" android:protectionlevel="normal"></permission>
然后在provider中,我们这里同时使用读、写权限:
<provider android:name=".PeopleContentProvider" android:authorities="com.harvic.provider.PeopleContentProvider" android:exported="true" android:readpermission="com.harvic.contentProviderBlog.read" android:writepermission="com.harvic.cotentProviderBlog.write"></provider>
<uses-permission android:name="com.harvic.contentProviderBlog.read"></uses-permission>
如果我们在provider中,仅添加读共享数据库的权限,那第三方应该怎么申请权限才能读写数据库呢?
<provider android:name=".PeopleContentProvider" android:authorities="com.harvic.provider.PeopleContentProvider" android:exported="true" android:readpermission="com.harvic.contentProviderBlog.read"></provider>
<uses-permission android:name="com.harvic.contentProviderBlog.read"></uses-permission>
(3)、效果:
在实例代码中,在provider中添加了读写权限,但在第三方APP:UseProvider中,仅添加了读权限,所以在利用URI来读共享数据库的时候结果是正常的,但在写数据库时,就会抛出permission-denied错误,如果不用try...catch...捕捉,就会造成crash;结果截图如下:
- query()操作
- insert()、delete() 或 update()操作时,就会抛出异常
源码在文章底部给出。
二、数据监听
1、监听步骤
要监听指定URI上的数据库变化,在监听方需要两步:
(1)、生成一个类派生自ContentObserver
public class DataBaseObserver extends ContentObserver { public DataBaseObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.d("harvic","received first database changed"); } }
(2)、注册和反注册监听
- 注册
在使用URI来操作第三方数据之前,先进行ContentObserver注册,这里我们在MainActivity的OnCreate()函数里注册:
private DataBaseObserver observer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); observer = new DataBaseObserver(new Handler()); //注册指定URI 变动监听 getContentResolver().registerContentObserver(CONTENT_URI_FIRST,true,observer); }
- 在OnDestory()时,反注册:
@Override protected void onDestroy() { super.onDestroy(); //取消监听 getContentResolver().unregisterContentObserver(observer); }
在ContentProvider中指定URI上有数据库数据变动时,及时利用下面的函数来通知
getContext().getContentResolver().notifyChange(uri, null);
好了,到这数据库变动通知和监听的过程就讲完了,下面看看registerContentObserver()注册监听函数的用法:
public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
参数:
- uri : 需要观察的Uri
- notifyForDescendents: 为false 表示精确匹配,即只匹配该Uri; 为true 表示可以同时匹配其派生的Uri
举例如下:假设UriMatcher 里注册的Uri共有一下类型:
1、content://com.qin.cb/student (学生)
2、content://com.qin.cb/student/#
3、content://com.qin.cb/student/schoolchild(小学生,派生的Uri)
假设我们当前需要观察的Uri为content://com.qin.cb/student,如果发生数据变化的 Uri 为 content://com.qin.cb/student/schoolchild;那么当notifyForDescendents为 false,那么该ContentObserver会监听不到, 但是当notifyForDescendents 为ture,能捕捉该Uri的数据库变化。
- observer: ContentObserver的派生类实例
2、结果
在数据库改变时,收到消息如图所示:
好了,这到就结束了,有关ContentProvider的用法也都讲完了;
源码在文章最底部
三、补充:SetProjectionMap——投影映射
在上面的实例中,我们对外提供的数据库列名和内部使用的是一样的,但这样很容易被对方知道我们的数据库结构,那要想自己本地使用一套列名,给外部提供另一套对应的列名,这样别人不就猜不出我们的列名了么,针对这个问题,在SQLiteQueryBuilder类中,为我们提供了内外部列名映射函数,以允许我们在外部和内部列名不同时的提供映射功能。
主要使用的函数是setProjectionMap(HashMap map)
使用方法如下:
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); Map projectionMap = new HashMap<string>(); projectionMap.put("out_column_name_1","inside_column_name_1"); projectionMap.put("out_column_name_2","inside_column_name_2"); projectionMap.put("out_column_name_3","inside_column_name_3"); queryBuilder.setTables(DatabaseHelper.TABLE_FIRST_NAME); queryBuilder.setProjectionMap(projectionMap);</string>
由于是事后补充的知识,在这里就再给大家提供例子参考了,大家可以自己尝试下。
感谢下面这些精彩的文章给了我参考的资料和灵感:
1、《android ContentProvider使用详解》(很棒)
2、《android之ContentProvider和Uri详解》
3、《Android突破笔记五:ContentProvider和Uri详解》
4、《自定义ContentProvider的一些细节探究》
5、《android ContentResolver详解》
6、《对android中MIME类型以及contentprovidergetType()方法的理解》
7、《ContentProvider中getType(Uri uri)用法及理解》
8、《是否需要覆盖ContentProvider的getType方法?》
9、《对ContentProvider中getType(Uri uri)和android.intent.category.DEFAULT的理解》 (很棒)
10、《ContentProvider中gettype() 和MIME类型的理解》
11、《监测database的改变--notifyChange》
12、《Android 监听ContentProvider中数据的变化》
13、《Android监听数据库的值改变与否》
14、《Permission Denial: opening provider 隐藏的android:exported属性的含义》
15、《Content Provider的权限 》
源码来了,源码内容:
1、第一部分:数据库读写权限
2、第二部分:数据监听(把读写权限代码删除,只有监听相关的代码)
如果本文有帮到你,记得关注哦;
源码下载地址:http://download.csdn.net/detail/harvic880925/8535963
http://blog.csdn.net/harvic880925/article/details/44651967 谢谢!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

蘋果公司最新發布的iOS18、iPadOS18以及macOSSequoia系統為Photos應用程式增添了一項重要功能,旨在幫助用戶輕鬆恢復因各種原因遺失或損壞的照片和影片。這項新功能在Photos應用的"工具"部分引入了一個名為"已恢復"的相冊,當用戶設備中存在未納入其照片庫的圖片或影片時,該相冊將自動顯示。 "已恢復"相簿的出現為因資料庫損壞、相機應用未正確保存至照片庫或第三方應用管理照片庫時照片和視頻丟失提供了解決方案。使用者只需簡單幾步

PHP處理資料庫連線報錯,可以使用下列步驟:使用mysqli_connect_errno()取得錯誤代碼。使用mysqli_connect_error()取得錯誤訊息。透過擷取並記錄這些錯誤訊息,可以輕鬆識別並解決資料庫連接問題,確保應用程式的順暢運作。

可以透過使用gjson函式庫或json.Unmarshal函數將JSON資料儲存到MySQL資料庫中。 gjson函式庫提供了方便的方法來解析JSON字段,而json.Unmarshal函數需要一個目標類型指標來解組JSON資料。這兩種方法都需要準備SQL語句和執行插入操作來將資料持久化到資料庫中。

MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

若要避免PHP資料庫連線錯誤,請遵循最佳實務:檢查連線錯誤,變數名稱與憑證相符。使用安全儲存或環境變量,避免硬編碼憑證。使用完後關閉連接,防止SQL注入,使用準備好的語句或綁定參數。

2025年全球數字虛擬幣交易平台競爭激烈,本文根據交易量、安全性、用戶體驗等指標,權威發布2025年全球十大數字虛擬幣交易平台排行榜。 OKX憑藉強大的技術實力和全球化運營策略居首,Binance以高流動性和低費用緊隨其後。 Gate.io、Coinbase、Kraken等平台憑藉各自優勢穩居前列。榜單涵蓋Huobi、KuCoin、Bitfinex、Crypto.com和Gemini等交易平台,各有特色,但投資需謹慎。選擇平台需考慮安全性、流動性、費用、用戶體驗、幣種選擇及監管合規性等因素,理性投資

MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

虛擬貨幣十大交易平台排行榜(2025年最新): 幣安:全球龍頭,高流動性,監管受關注。 OKX:龐大用戶基數,支持多種幣種,提供槓桿交易。 Gate.io:資深交易所,多種法幣支付方式,提供多種交易對和投資產品。 Bitget:衍生品交易所,高流動性,低費用。 火幣:老牌交易所,支持多種幣種和交易對。 Coinbase:美國知名交易所,受監管嚴格。 Phemex等等。
