目錄
一、数据库读写权限
1、概述
2、实例
(1)有关自定义权限
(2)、带有权限的ContentProvder实例
(3)、效果:
二、数据监听
1、监听步骤
2、结果
三、补充:SetProjectionMap——投影映射
首頁 資料庫 mysql教程 ContentProvider数据库共享之读写权限与数据监听

ContentProvider数据库共享之读写权限与数据监听

Jun 07, 2016 pm 03:17 PM
共享 數位 資料庫 權限 讀寫

前言:随着工作的时间越来越长,越来越觉得自己学知识的速度太慢,原定的两年,现在已经过了快九个月了,仍然对很多知识懵懵懂懂,对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>
登入後複製
登入後複製
比如,在这里我们定义一个readPermission字符串,单纯写一个字符串是毫无意义的,因为根本系统的任何权限都是要申请的,没有申请过的一串String代表的字符串系统根本无法识别,也就是说谁进来都会被挡在外面!

<permission android:name="com.harvic.contentProviderBlog.read" android:label="provider pomission" android:protectionlevel="normal"></permission>
登入後複製
这样,我们的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>
登入後複製
登入後複製
从上面可以看到,我们只添加了readPermission,那第三方应用在不申请任何权限的情况下是可以写数据库,但当读数据库时就需要权限了;即如果要读数据库需要添加如下使用权限声明:
<uses-permission android:name="com.harvic.contentProviderBlog.read"></uses-permission>
登入後複製
登入後複製

(3)、效果:

在实例代码中,在provider中添加了读写权限,但在第三方APP:UseProvider中,仅添加了读权限,所以在利用URI来读共享数据库的时候结果是正常的,但在写数据库时,就会抛出permission-denied错误,如果不用try...catch...捕捉,就会造成crash;结果截图如下:

  • query()操作

ContentProvider数据库共享之读写权限与数据监听

  • insert()、delete() 或 update()操作时,就会抛出异常

ContentProvider数据库共享之读写权限与数据监听


源码在文章底部给出。

二、数据监听

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");
    }
}
登入後複製
注意这里会自动生成一个onChange()方法,当有改变到来时就会跑到onChange()里,所以我们在这里面打一个LOG,注意LOG内容:“received first database changed”,很明显这里我只用DataBaseObserver来监听"content://com.harvic.provider.PeopleContentProvider/frist "所对应的数据库进行监听,至于如何指定URI往下看
(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);
}
登入後複製
这里先完整说完流程,等下再讲registerContentObserver()的参数
  • 在OnDestory()时,反注册:
@Override
protected void onDestroy() {
    super.onDestroy();
    //取消监听
    getContentResolver().unregisterContentObserver(observer);
}
登入後複製
(3)、在ContentProvider中数据库变动通知
在ContentProvider中指定URI上有数据库数据变动时,及时利用下面的函数来通知
getContext().getContentResolver().notifyChange(uri, null);
登入後複製
这个函数就是在第二篇中,我们提到的通知函数;
好了,到这数据库变动通知和监听的过程就讲完了,下面看看registerContentObserver()注册监听函数的用法:
public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
登入後複製
功能:为指定的Uri注册一个ContentObserver派生类实例,当**给定**的Uri发生改变时,回调该实例对象去处理。
参数:
  • 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数据库共享之读写权限与数据监听

好了,这到就结束了,有关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  谢谢!


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1668
14
CakePHP 教程
1426
52
Laravel 教程
1328
25
PHP教程
1273
29
C# 教程
1255
24
iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 iOS 18 新增「已復原」相簿功能 可找回遺失或損壞的照片 Jul 18, 2024 am 05:48 AM

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

如何在PHP中處理資料庫連線錯誤 如何在PHP中處理資料庫連線錯誤 Jun 05, 2024 pm 02:16 PM

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

如何在 Golang 中將 JSON 資料保存到資料庫中? 如何在 Golang 中將 JSON 資料保存到資料庫中? Jun 06, 2024 am 11:24 AM

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

mysql:簡單的概念,用於輕鬆學習 mysql:簡單的概念,用於輕鬆學習 Apr 10, 2025 am 09:29 AM

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

PHP 資料庫連線陷阱:避免常見的錯誤和誤區 PHP 資料庫連線陷阱:避免常見的錯誤和誤區 Jun 05, 2024 pm 10:21 PM

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

全球數字虛擬幣交易平台排行榜前十(2025權威排名) 全球數字虛擬幣交易平台排行榜前十(2025權威排名) Mar 06, 2025 pm 04:36 PM

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

MySQL:世界上最受歡迎的數據庫的簡介 MySQL:世界上最受歡迎的數據庫的簡介 Apr 12, 2025 am 12:18 AM

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

幣圈十大交易所2025年最新 數字貨幣app排行榜前十 幣圈十大交易所2025年最新 數字貨幣app排行榜前十 Feb 27, 2025 pm 06:33 PM

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

See all articles