Android内容提供程序
来源:互联网 发布:115 mac版 编辑:程序博客网 时间:2024/05/23 11:48
内容提供程序管理对结构化数据集的访问,它们封装数据,并供用于定义数据安全性的机制。内容提供程序是连接一个进程中的数据与另一个进程中运行的代码的标准界面。
将应用的Context中的ContentResolver对象用作客户端来提供程序通信,可以访问内容提供程序中的数据。ContentResolver对象会实现ContentProvider的类实例通信,提供程序对象从客户端接收数据请求,执行请求的操作并返回结果。
内容提供程序以一个或多个表的形式将数据呈现给外部应用,行表示提供程序收集的某种数据类型的实例,行中的每个列表示为实例收集的。
访问提供程序
应用从具有ContentResolver客户端对象的内容提供程序访问数据,此对象具有调用提供程序对象中同名方法的方法,ContentResolver方法可提供程序存储的基本CRUD(创建,检索,更新,删除)功能。客户端应用进程中ContentResolver对象和拥有提供程序的应用中的ContentProvider对象可自动处理跨进程通信,ContentProvider还可充当其数据存储区和表格外部显示之间的抽象层。
内容URI
是用于在提供程序中表示数据的URI,包括整个提供程序的符号名称,和一个指向表的名称(路径)。ContentResolver对象会分析出URI的授权,并通过将该授权与已知提供程序的系统进行比较来解析提供程序,然后,ContentResolver可以将查血的参数分派给正确的提供程序。
ContentProvider使用内容URI的路径部分来选择要访问的表,提供程序通常会为其公开每个表显示一条路径。
例如:content://user_dictionary/words
其中user_dictionary字符串是提供程序的授权,words字符串是表的路径,字符串content://(架构)始终显示,并将此标识为内容URI
许多提供程序都允许通过将ID值追加到URI末尾来访问表中的单个行。在检索到一组行后想要更新或删除其中某一行时通常用到ID值。
Uri和Uri.Builder 类包含根据字符串构建格式规范的URI对象的便利方法,ContentUris包含一些可以将ID值追加到URI后的方法。例如:
Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI, 4);
提供程序检索数据
为了说明,本例在UI线程上调用ContentResolver.query(),但在实际代码中应该在单独线程上异步执行查询,使用CursorLoader类,按照以下两个基本操作执行
1.请求对提供程序的读取访问权限
2.定义将查询发送至提供程序的代码
在清单文件<uses-permission>中添加读取访问权限
构建查询
// A "projection" defines the columns that will be returned for each rowString[] mProjection ={ UserDictionary.Words._ID, // Contract class constant for the _ID column name UserDictionary.Words.WORD, // Contract class constant for the word column name UserDictionary.Words.LOCALE // Contract class constant for the locale column name};// Defines a string to contain the selection clauseString mSelectionClause = null;// Initializes an array to contain selection argumentsString[] mSelectionArgs = {""};查询应该返回的列集被称为投影(即变量mProjection)
String[] mSelectionArgs = {""};// Gets a word from the UImSearchString = mSearchWord.getText().toString();// Remember to insert code here to check for invalid or malicious input.// If the word is the empty string, gets everythingif (TextUtils.isEmpty(mSearchString)) { // Setting the selection clause to null will return all words mSelectionClause = null; mSelectionArgs[0] = "";} else { // Constructs a selection clause that matches the word that the user entered. mSelectionClause = UserDictionary.Words.WORD + " = ?"; // Moves the user's input string to the selection arguments. mSelectionArgs[0] = mSearchString;}// Does a query against the table and returns a Cursor objectmCursor = getContentResolver().query( UserDictionary.Words.CONTENT_URI, // The content URI of the words table mProjection, // The columns to return for each row mSelectionClause // Either null, or the word the user entered mSelectionArgs, // Either empty, or the string the user entered mSortOrder); // The sort order for the returned rows// Some providers return null if an error occurs, others throw an exceptionif (null == mCursor) { /* * Insert code here to handle the error. Be sure not to use the cursor! You may want to * call android.util.Log.e() to log this error. * */// If the Cursor is empty, the provider found no matches} else if (mCursor.getCount() < 1) { /* * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily * an error. You may want to offer the user the option to insert a new row, or re-type the * search term. */} else { // Insert code here to do something with the results}如果用户未输入字词,则选择子句将设置为
null
,而且查询会返回提供程序中的所有字词。 如果用户输入了字词,选择子句将设置为 UserDictionary.Words.WORD + " = ?"
且选择参数数组的第一个元素将设置为用户输入的字词。防止恶意输入
如果内容提供程序管理的数据位于 SQL 数据库中,将不受信任的外部数据包括在原始 SQL 语句中可能会导致 SQL 注入。
String mSelectionClause = "var = " + mUserInput;如果执行此操作,则会允许用户将恶意SQL串连接到SQL语句上,由于选择子句是作为SQL语句处理,故可能会导致提供程序擦除基础SQLite数据库中的所有表。
要避免此问题,可使用一个用于将 ? 作为可替换参数的选择子句以及一个单独的选择参数数组。 执行此操作时,用户输入直接受查询约束,而不解释为 SQL 语句的一部分。 由于用户输入未作为 SQL 处理,因此无法注入恶意 SQL。
String mSelectionClause = "var = ?";String[] selectionArgs = {""};selectionArgs[0] = mUserInput;
一个用于将 ? 用作可替换参数的选择子句和一个选择参数数组是指定选择的首选方式,即使提供程序并未基于 SQL 数据库。
如果没有与选择条件匹配的行,则提供程序会返回Cursor.geeCount() 为 0(空游标)的Cursor 对象。
如果出现内部错误,查询结果将取决于具体的提供程序。它可能会选择返回 null,或引发Exception
由于Cursor是行“列表”,因此显示Cursor 内容的良好方式是通过SimpleCursorAdapter将其与ListView 关联。
内容提供程序权限提供程序的应用可以指定其他应用访问提供程序的数据所必需的权限。 这些权限可确保用户了解应用将尝试访问的数据。 根据提供程序的要求,其他应用会请求它们访问提供程序所需的权限。 最终用户会在安装应用时看到所请求的权限。
如果提供程序的应用未指定任何权限,则其他应用将无权访问提供程序的数据。 但是,无论指定权限为何,提供程序的应用中的组件始终具有完整的读取和写入访问权限。
要获取访问提供程序所需的权限,应用将通过其清单文件中的<uses-permission>元素来请求这些权限。Android 软件包管理器安装应用时,用户必须批准该应用请求的所有权限。 如果用户批准所有权限,软件包管理器将继续安装;如果用户未批准这些权限,软件包管理器将中止安装。插入、更新、删除数据
与从提供程序检索数据的方式相同,也可以通过提供程序客户端和提供程序ContentProvider之间的交互来修改数据。 您通过传递到ContentProvider的对应方法的参数来调用 ContentResolver方法。 提供程序和提供程序客户端会自动处理安全性和跨进程通信。
// Defines a new Uri object that receives the result of the insertionUri mNewUri;...// Defines an object to contain the new values to insertContentValues mNewValues = new ContentValues();/* * Sets the values of each column and inserts the word. The arguments to the "put" * method are "column name" and "value" */mNewValues.put(UserDictionary.Words.APP_ID, "example.user");mNewValues.put(UserDictionary.Words.LOCALE, "en_US");mNewValues.put(UserDictionary.Words.WORD, "insert");mNewValues.put(UserDictionary.Words.FREQUENCY, "100");mNewUri = getContentResolver().insert( UserDictionary.Word.CONTENT_URI, // the user dictionary content URI mNewValues // the values to insert);更新:
// Defines an object to contain the updated valuesContentValues mUpdateValues = new ContentValues();// Defines selection criteria for the rows you want to updateString mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?";String[] mSelectionArgs = {"en_%"};// Defines a variable to contain the number of updated rowsint mRowsUpdated = 0;.../* * Sets the updated value and updates the selected words. */mUpdateValues.putNull(UserDictionary.Words.LOCALE);mRowsUpdated = getContentResolver().update( UserDictionary.Words.CONTENT_URI, // the user dictionary content URI mUpdateValues // the columns to update mSelectionClause // the column to select on mSelectionArgs // the value to compare to);删除:
// Defines selection criteria for the rows you want to deleteString mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";String[] mSelectionArgs = {"user"};// Defines a variable to contain the number of rows deletedint mRowsDeleted = 0;...// Deletes the words that match the selection criteriamRowsDeleted = getContentResolver().delete( UserDictionary.Words.CONTENT_URI, // the user dictionary content URI mSelectionClause // the column to select on mSelectionArgs // the value to compare to);提供程序访问的替代形式
- Android内容提供程序
- android 内容提供程序的构建
- Android 之内容提供程序基础
- Android 之创建内容提供程序
- 内容提供程序基础知识
- 创建内容提供程序
- Android 之内容提供程序(Content Provider)
- Android跨程序共享数据,探究内容提供器
- android内容提供器
- Android内容提供器
- Android 内容提供器---简介
- Android 内容提供器---简介 .
- android 内容提供器api
- Android之内容提供器
- Android 内容提供器 ContentProvider
- Android 内容提供器小结
- android 内容提供组件机制
- Android创建内容提供器
- 代码混淆与打包 Android
- c++ vector, set, map的用法总结
- 紫书动规 例题9-9 UVA
- Sevlet的生命周期
- Linux 驱动的写法
- Android内容提供程序
- 《程序猿的第n+3天》bootstrap做收缩导航
- 用户账号不可同时两处登入系统的控制
- 虚函数和纯虚函数的区别
- 整数高精度算法
- itchat 群用户搜索的踩坑记录
- codeforces round#404(div.2) C. Anton and Fairy Tale
- 使用jquery-datatable和bootsrap创建表格
- unity 屏幕旋转 相关 笔记