#内容提供者基础 Content Provider Basics

content provicer 管理着中心数据仓库的访问。一个provider是Android的应用的一部分,它可以提供数据工作的UI。


然而,content provider基本都是被其他的应用访问,使用一个provider客户端对象来访问provider。provider和provider client一同创立了一个持续的标准的数据接口,它可以提供进程内通信以及安全数据访问。


这个主题讲解下面内容的基础部分;
- content provider 是怎样工作的
- 从content provider中获取数据的api
- 从content provider中插入、删除、更新数据的api
- 其他装备了content provider 的功能的api


##一览 Overview

content provider给外部应用的数据以表的形式,类似于关系型数据库。行表示provider汇集的数据类型,行中的列表示一个对象的一块数据。


例如一个Android平台内置的provider——用户字典,它保存着用户的一些非标准的词汇的拼写。表1展示了content provider里面的数据的大致样子。

表1 用户词典

word app id frequency locale _ID
mapreduce user1 100 en_US 1
precompiler user14 200 fr_FR 2
applet user2 225 fr_CA 3
const user1 255 pt_BR 4
int user5 100 en_UK 5
在表1中,每一个行头代表了一个词的实例,他们在标准的词典中找不到。其每一栏都表示这个词的数据,比如说locale就是第一次遇见的场所。每一栏的头是存储在provider中的栏目的名字。想要引用一行的 locale,你要引用“locale”栏。对于这个提供者,_ID作为你的关键字栏目,是由provider自动维护的。

***********提示*************

一个provider的关键字不是必须的,即使存在,其名字也可以不是_ID。但如果你想要从provider中获取数据装入到listView中,那么你必须要有一栏为_ID。这个要求的更多细节请参见 Displaying query results一节。

*****************************


访问一个provider

应用可以通过访问ContentResolver对象来访问content provider。这个对象中的方法和provider对象的中的同名,是ContentProvider的子类的具体实现。ContentResolver方法中包含了维护数据的增删改查操作。

在客户应用进程中的ContentProvider对象和在拥有provider的应用的进程中的ContentProvider对象会自动处理进程内的交流。ContentProvider还会作为在数据仓库和比如说表这样的数据形式的之间的抽象层。

**********提示******************

访问contentprovider你的你需要在manifest中申请特殊的权限。在Content Provider Permissions会有更详细的讨论。

*********************************

举个例子,获取从用户字典中获取词汇和对应的现场,你可以调用ContentResolver.query()方法。这里面的query()方法会调用ContentProvider的query()方法,它要由用户词典提供者定义。下面的代码展示了一个ContentProvider.query()的调用。

// Queries the user dictionary and returns results
mCursor = getContentResolver().query(UserDictionary.Words.CONTENT_URI,   // The content URI of the words tablemProjection,                        // The columns to return for each rowmSelectionClause                    // Selection criteriamSelectionArgs,                     // Selection criteriamSortOrder);                        // The sort order for the returned rows
表2展示了query(Uri,projection,selection,selectionArgs,sortOrder)中的参数是如何对应 SQL SELECT statement(SQL查询语句的)。

Table 2: Query() compared to SQL query.

query() argument SELECT keyword/parameter Notes
Uri FROM table_name Uri 对应的provider中的名为table_name的表。
projection col,col,col,... projection 每一行中需要查询的栏目名字构成的数组。
selection WHERE col =value selection 选择行的选择条件的说明。
selectionArgs (没有准确的 SQL语句中的对应,表示的是在选择从句中的?的占位。)
sortOrder ORDER BYcol,col,... sortOrder
返回的Cursor中的行的排序方式。


内容的URI


content URI是指定了provider中的数据的uri。Content URI中包含了整个provider的符号名字(它的职权),和一个指向一个表的名字。(一个路径)当你调用一个方法来访问provider中的一个表的时候,表的content URI就是其中 的一个参数。

在运行的代码中,常量CONSTANT_URI包含了用户字典word表的内容URI。ContentProvider对象解析出URI的职权,并使用它们通过比较用户职权和系统已知的provider的表,来处理provider。ContentResolver接着就可以传递查询参数给正确的provider了。

ContentProvider通过使用contentURI中的路径部分来选择要访问的表。provider都会给他呈现的表设定一个路径。
在上一段代码中,words表的完全的URI是:
content://user_dictionary/words

其中的user_dictionary 是provider职权,words字符串是表的路径。content://(模式)字符串则一直都会有,它定义为content URI。

很多provider允许你在content URI中的最后一个字段来追加一个ID值,从而可以访问表中的某一行。例如,想要从用户字典里面检索一个行的 _ID 字段为4的行,就尅使用这个content URI。

Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
当你想要删除或者更新很多行中的一个的时候,你需要使用id字段。
************提示*****************
Uri和Uri.Builder类都有使用构建URI格式对象的便捷方法。ContentUris类中有在URI后边追加ID字段的方法。之前的代码段就使用了withAppendedId()方法来向用户字典中的content URI中追加 di。
***********************************

从provider中检索数据

下面介绍怎样从provider中检索数据,使用用户字典(User Dictionary Provider)作为例子。

******************************

为了便于说明,这一节中的代码片中调用的ContentResolver.query()都是在UI线程中调用的。在实际的应用中,你应该异步地在另一个线程中进行查询。一种方法是使用CursorLoader类,在Loader的教程中有更多的说明。并且,这些代码只是一个片段,并没有展现一个整个的应用。

想要从provider中检索数据,要遵循下面的基本步骤:

1.为provider请求读权限。

2.定义向provider发送查询的代码。


获取读访问权限

要从provider中获取数据,你的应用怒要provider的 读访问权限。必不能在运行时获得这样的权限,只可以在manifest文件中声明,使用<uses-permission>元素,以及在provider中定义的名字。当你在manifest中声明这个元素以后,就是在想你的应用请求权限了。当用户安装了你的应用的时候,他就隐式地授予了这些权限。

在User Dictionary Provider 在manifest文件在中定义了android.permission.READ_USER_DICTIONNARY权限,所以想要从这个provider中读取数据的应用就要请求这个权限。


构建一个查询

从provider中检索数据的下一个步骤就是构建一个查询。第一个代码片中定义了一些用来访问User Dictionary Provider的的变量。

// A "projection" defines the columns that will be returned for each row
String[] mProjection =
{UserDictionary.Words._ID,    // Contract class constant for the _ID column nameUserDictionary.Words.WORD,   // Contract class constant for the word column nameUserDictionary.Words.LOCALE  // Contract class constant for the locale column name
};// Defines a string to contain the selection clause
String mSelectionClause = null;// Initializes an array to contain selection arguments
String[] mSelectionArgs = {""};

下面的代码片向你展示怎样使用ContentResolver.query()方法,还是使用User Dictionary Provider作为例子。一个ContentProvider查询和一个SQL查询类似,都包含要获取的栏目,筛选标准以及结果排序的顺序。

查询中要返回的栏目叫做projection(英语中有投影的意思)(mProjection变量)。

说明那些行要查询的表达式,则被分成了selection clause 和 selection arguments两部分。selection clause 是一个逻辑和布尔表达式,栏目的名字,以及值(mSelectionClause)的结合。如果你使用了占位符?而不是数值,那么查询方法会从来选择参数数组中获取值(mSelectArgs 变量)。


下一个代码片中,如果用户没有输入一个单词,selection clause就会被设置成null,从而查询会返回所有的provider中的单词。如果用户输入了一个单词,那么selection clause就会设定为“UserDictionary.Words.WORD+"=?”,同时selection arguments 数组中的第一个元素会被设定为用户输入的这个单词。

/** 这里定义一个只有一个元素的String数组来表示selection argument*/
String[] mSelectionArgs = {""};// 从UI中获取一个输入
mSearchString = mSearchWord.getText().toString();// 记得检查用户的输入是否合法或者是否是恶意代码// 如果获得是一个空的String,就查询所有的内容
if (TextUtils.isEmpty(mSearchString)) {// 把筛选标砖的从句设为null,就会返回所有行mSelectionClause = null;mSelectionArgs[0] = "";} else {// 构建一个和用户输入相对应的查询选择从句mSelectionClause = UserDictionary.Words.WORD + " = ?";//把用户输入放入到选择的参数的数组中mSelectionArgs[0] = mSearchString;}// 对指定的的表进行查询并在Cursor中返回
mCursor = getContentResolver().query(UserDictionary.Words.CONTENT_URI,  // The content URI 表的mProjection,                       // The 每一行指定的栏目mSelectionClause                   // 是空或者是用户用户输入的单词mSelectionArgs,                    // 是空或者是用户输入的字符串mSortOrder);                       // 返回的一组行的排序顺序// 如果发生了一些错误,就会返回一个null的Cursor,或者是抛出异常
if (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.
在这里处理错误,一定要确保不要使用这个cursor,你可以调用Log.e来记录这些错误
     *     */// 如果返回的Cursor中没有元素,说明没有对应的内容} 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这里进行查询结果的处理} 这个查询和SQL的语句是类似的。

SELECT _ID, word, locale FROM words WHERE word = <userinput> ORDER BY word ASC;
在SQL语句中,使用了真实的栏目的名字,而不是协议类中的常量。

防止恶意输入

如果content Provider管理的 是一个SQL数据库,在SQL语句中包含不信任的外部数据可以导致SQL注入。

思考下面的选择从句:

// Constructs a selection clause by concatenating the user's input to the column name
String mSelectionClause =  "var = " + mUserInput;
如果你这样做,就留存了用户进行连接恶意SQL代码到你的SQL语句中的漏洞。例如,用户可以输入“nothing;DROP TALBE *;”给变量mUserInput, 会导致这个选择的从句变成了var=nothing;DROP TABLE *;。以为这个选择的语句会被当做一个SQL语句,所以这可能会导致provider擦出除了对应的SQLitedatabase中的所有的表。(除非这个providerprovider设置了捕获SQL注入的选项)。


想要避免在这样的问题,就使用?占位符,将参数和语句进行分离。如果这样做的话,用户的输入就会被局限在查询当中,而不会被作为一个一般的SQL语句的一部分。因为不会被视为SQL,所以用户输入不可能插入恶意代码。不要使用拼接来引入用户输入,而是要使用选择从句。

// Constructs a selection clause with a replaceable parameter
String mSelectionClause =  "var = ?";

设置选择的参数的数组:

// Defines an array to contain the selection arguments
String[] selectionArgs = {""};
在选择数组中赋值如下:


// Sets the selection argument to the user's input
selectionArgs[0] = mUserInput;

使用?占位符,以及一个选择的参数的数组是一个推荐方法,即使不是在SQL数据库中,也推荐这么做。


表示查询结果

ContentResolver.query()的客户端方法总是返回一个包含查询中mProject中指定的栏目,和筛选条件中指定的行的一个cursor。一个Cursor可以为它包含的栏目和行提供随机访问的功能。通过使用Cursor中的方法,你可以迭代Cursor中行,对每一行中的栏目进行判断,获取这些栏目,以及检查结果中的其他的属性。一些Cursor对象中定义了自动更新的方法,在数据库中对应的数据发生变化的时候会自动的更新的奥cursor中,还有一些包含着触发器,当Cursor中的数据发生变化会自动同步到数据库当中。,或者两者都有。


*********提示*************

provider可能会限制对于一些栏目的访问,基于进行查询的对象的一些特性。例如,Contacts Provider会只允许同步适配器访问以下栏目,这样的话就不会想activity或者service返回这些栏目。

***************************


如果没有行和选择中的标准相互对应,那么就会返回一个Cursor.getCount()方法为0的Cursor对象。(一个空的cursor)


如果内部发生了异常,那么返回的结果取决于具体的provider,通常会返回一个指向null 的cursor或者抛出异常 。

因为Cursor对象的组织就如同一个行的列表,所以用来表达内容的简单的办法就是使用SimpleCursorAdaper来把它和一个ListView进行关联。


下面是一个承接上面代码片的新代码片。其中创建了SimpleCurcorAdaper的对象,其中包含了通过查询获得的Cursor对象,并且设置一个ListView来适配这个对象。


// 定义了Cursor中的,我们想要表示 栏目的名字的数组。
String[] mWordListColumns ={    UserDictionary.Words.WORD,   // 协议来中的包含word栏目名字的常量。    UserDictionary.Words.LOCALE  // 协议类中locale栏目的常量};// 定义一个接受从Cursor中获取的栏目的内容的View的数组int[] mWordListItems = { R.id.dictWord, R.id.locale};// 创建一个SimpleCursorAdaptermCursorAdapter = new SimpleCursorAdapter(    getApplicationContext(),               // 应用的上下文对象    R.layout.wordlistrow,                  // ListView中一行的布局的xml布局    mCursor,                               // 查询的结果    mWordListColumns,                      // cursor需要展示的栏目的名字    mWordListItems,                        // 行布局中接收数据的view的id的int数组    0);                                    // 标志位,通常不需要// 设置ListView的适配器mWordList.setAdapter(mCursorAdapter);


*************提示*******************

想要从Cursor构建一个ListView,cursor中一定要包含一个名为_ID的字段。正式因为这样,所以之前的查询都要包含_ID字段,尽管在ListView中并不需要显示。这个限制也解释了为什么contentProider表大都包含_ID字段。

**************************************

从查询结果中获取数据

预期仅仅是显示查询结果,你可以把它们用作其他任务中。例如你可以在用户字典里面检索拼写,然后在其他的provider里面进行查找。你可以在Cursor的行上面迭代来完成。

// 确定一个叫做“word”的栏目的索引号
int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);/** Only executes if the cursor is valid. The User Dictionary Provider returns null if* a只有在Cursor合法的时候才可以执行。如果获得Cursor过程中发生内部错误,其他的provider可能会抛出异常而不是返回null。
 */if (mCursor != null) {/** Moves to the next row in the cursor. Before the first movement in the cursor, the* "row pointer" is -1, and if you try to retrieve data at that position you will get an*移动到Cursor的的下一行。当你移动cursor之前,它默认的指针的位置是-1。如果你在这个位置读数据的话就会发生异常*/while (mCursor.moveToNext()) {// 从这一栏中中获取数据。newWord = mCursor.getString(index);// 这里插入处理检索出的单词的代码。...// 循环体结束}
} else {//  如果cursor为null或者发生异常,那么在这里插入处理的代码。
}
Cursor的构建里面包含了很多get类型的方法,以从对象中获取不同类型的信息。例如上面的代码片里面就是使用了getString()方法。同样,还有getType()方法来返回所指定的栏目的数据类型。


Content Provider的权限许可

provider可以指定其他应用想要访问这个provider必须要声明的权限。这个许可保证了使用者知道自己将访问哪一个provider。基于这个要求,其他的应用就要通过请求响应的权限来访问provider。终端用户在安装这个应用的时候就可以看见权限请求。


如果一个provider没有指定一个权限许可,那么其他的应用是不可以访问该provider的。但是,无论是否声明权限,provider的同一个应用的其他组件拥有provider的完全读写权限。

如同之前提到的那样,User Dictionary Provider需要请求android.permission.READ_USER_DICTIONARY的权限,来从中获取数据。provider还有另外一个分离的权限android.permission.WRITE_USER_DICTIONARY来进行插入更新和删除数据。

要获取想访问的provider的权限,应用通过在manifest文件当中使用<uses-permission>标签。当Android Package Manager安装应用时,用户必须要允许所有应用请求的权限。如果用户用户允许了所有,安装才可以继续进行,如果不允许,Android Packet Manager就中断安装。

下面的<user-permission>标签请求了访问User Dictionary Provider的权限。

    <uses-permission android:name="android.permission.READ_USER_DICTIONARY">

权限许可对于provider访问的影响将在Security and Permission一节进行更多的讲解。

插入,更新和删除数据

和你从provider中获取数据的方式类似,你在客户端组件和ContentProvider之间使用同样的方式来修改数据。你通过调用ContentProvider的一个方法,同时还有一些参数,这些参数会被传入到ContentProvider的对应方法当中。provider和provider客户端之间就会自动处理安全的跨进程的通信。

插入数据

可以使用ContentResolver.insert()方法来插入数据。这个方法在ContentProvider中插入一行数据,并返回这行数据的uri。下面的代码片展示了向User Dictionary Provider插入一个新单词的例子。

// 定义一个接受插入返回值的uri
Uri mNewUri;...// 定义一个包含要插入值的对象
ContentValues mNewValues = new ContentValues();/** Sets the values of each column and inserts the word. The arguments to the "put"* method are "column name" and "value"为插入的数据设定每一栏的值,put方法的两个参数分别为栏目的名字和插入的值*/
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,   // user dictionary content 的urimNewValues                          // 要插入的值
);

新的要插入的值被放入到ContentValues的对象当中,在形式上和只有一行的Cursor类似。对象中的栏目不必是相同的类型,并且如果你不想给某一栏设定值,你可以使用ContentValues.putNull()来设定为null。

代码片中没有插入_ID一栏,因为这一栏会被自动插入。provider会给每一个插入的数据设定惟一的_ID。provider通常使用这个值作为表格的主键。

返回的指示新插入行的content URI是下面的这种形式

content://user_dictionary/words/<id_value>

<id_value>是新插入行的_ID的内容。大多数的provider都可以自动探测这种类型的URI,并且在对应的行上面完成相应的操作。

想要从返回的Uri中获取_ID的值,可以调用ContentUris.parseId()方法。

更新数据

更新数据的一行,使用的方法和参数类似于你插入数据,并且如同你查找数据那样设定选取行的标准。客户端你使用的方法是ContentResolver.update()。你只需要把你要更新的数据添加到ContentValues对象的当中即可。如果你想清除某一栏的数据,就把对应的栏目设置为null。

下面的代码片就是把local语言为“en”的行都更新为null。返回值是更新了的行的数量。

// 定义包含要更新的值的对象
ContentValues mUpdateValues = new ContentValues();// 定义选择你要更新行的标准
String mSelectionClause = UserDictionary.Words.LOCALE +  "LIKE ?";
String[] mSelectionArgs = {"en_%"};// 定义返回的更新的行目数量
int mRowsUpdated = 0;.../** 设定更新的值,并更新选定的单词*/
mUpdateValues.putNull(UserDictionary.Words.LOCALE);mRowsUpdated = getContentResolver().update(UserDictionary.Words.CONTENT_URI,   // the user dictionary content URIcontent的urimUpdateValues                       // the columns to update更新的栏目mSelectionClause                    // the column to select on选择的行mSelectionArgs                      // the value to compare to对应上一句的值
);
当你调用ContentResolver.update()方法的时候,你需要防范用户的输入。更多关于防范的注意,请阅读Protecting against malicious input。


删除数据

删除数据行和检索很类似:你指定筛选要删除的行的标准,接着返回删除的行的数目。下面的代码片删除了appid为“user”的行。方法返回了删除的行的书目。

// Defines selection criteria for the rows you want to delete
String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
String[] mSelectionArgs = {"user"};// Defines a variable to contain the number of rows deleted
int mRowsDeleted = 0;...// Deletes the words that match the selection criteria
mRowsDeleted = getContentResolver().delete(UserDictionary.Words.CONTENT_URI,   // the user dictionary content URImSelectionClause                    // the column to select onmSelectionArgs                      // the value to compare to
);
在调用ContentResolver.delete()中,同样需要注意防范用户输入。


Provider数据类型

ContentProvider可以提供不同种类的数据类型。User Dictionary Provider里面仅仅提供了text类型,但是provider还可以提供下面的类型。

- integer

- long integer(long)

- floating point

- long floating point (double)

还有一种provider经常使用的数据是Binary Large OBject(BLOB),由一个64kb的byte数据构成。你可以通过查看Cursor类的get方法来看支持的数据类型。

每一栏的数据类型都会在provider的文档中列举。User Dictionary Provider的数据类型,在他的协议类UserDictionary.Words的参考文档中列举。(Contract Classes中有关于它的介绍)。你也可以通过调用Cursor.getType()来确定数据类型。


Provider同样可以维护每一个定义的URI对应的MIME类型信息。你可以使用MIME类型信息来确定你的应用是否支持provider提供的类型,或者是基于MIME类型选择一种处理的类型。当你使用包含复杂的数据结构或者文件的provider的时候,你总是需要使用MIME类型。例如,ContactsProvider中的ContactsContarct.Data表,就使用MIME类型来标明每一行中存储的数据的类型。想要获取MIME类型对应的content URI,可以调用ContentResolver.getType()。

MIME Type Reference描述了标准和用户MIME类型的语意。

Provider的访问形式

在应用开发中有三种访问provider的形式:
- Batch access: 你可以使用ContentProviderOperation类来创建batch access,然后使用ContentResolver.applyBatch()方法来应用这些访问。
- 异步查询 Asynshronous: 在分离的线程中进行查询。使用它的一种方法是使用一个CursorLoader对象。更多说明在Loader的教程中。
- 使用intent进行数据访问:尽管你不能直接用intent访问provider,但是你可以访问provider所在的应用,这个应用应该总是准备好了来修改provider的数据。

下面将介绍Batch access和使用intent进行修改。

Batch access组团访问

Batch访问适合于处理插入大量的行,或者在同一个方法调用中向不同的表中插入行,或者通常作为一个事物(transaction,一种原子操作)来跨进程一系列操作。
使用batch模式访问provider,你要创建一个ContentProviderOperation对象数组,并调用ContentResolver.applyBatch()方法来把它们派发到content provider上。你要把contentProvider的职权传递到这个方法上,而不仅是一个特定的content URI。这使得ContentProviderOperation中的每一个对象都可以在不同的表上工作。对于ContentResolver.applyBatch()的调用返回一个结果数组。

关于ContactsContract.RawContacts的协议类的表述中包含了一个展示batch 插入的例子的代码片。Contact Manager的示例应用中在ContactAdder.java源文件中,有一个batch模式访问的例子。

通过intent访问数据

intent可以间接对于content provider进行访问。尽管你的应用没有访问某provider的权限,你也可以让用户访问content provider中的数据。可以通过接受一个拥有权限的应用返回的intent。或者激活一个拥有权限的应用,来让用户从provider中获取数据。
*****************侧栏提示****************************

使用一个帮助者应用来现实数据
如果你的应用有content provider的访问权限,你可能仍然想使用intent来在另一个应用中来现实数据。例如,日历app接收一个ACTION_VIEW的intent,来现实一个特定的日期或者事件。这可以让你不用自己创建UI就可以显式日历。更多请参考Calender Provider一章。

你发送的intent的目的app不一定与provider关联。例如你可以从Contact Provider中获取一个联系人,然后把传送一个包含联系人图像对应的content URI的ACTION_VIEW intent 给一个图像浏览器。


********************************************************

使用暂时权限来访问

尽管你没有访问某个contentProvider的权限,但是你可以通过向某个有权限的应用发出intent并接受返回的intent,其中包含了URI的权限许可。这是一个访问某个特定的URI的权限许可,一直可以持续到接受它的应用finish就截止。那些有永久访问权的应用可以通过在返回的intent中设定一个标志位来授权。
- Read permission:FLAG_GRANT_READ_URI_PERMISSION
-Write permission:FLAG_GRANT_WRITE_URI_PERMISSON

*****************提示****************************
这些标志位不能赋予包含在content URI中的provider的通常的访问权限。权限仅仅作用于uri本身。
*******************************************************
一个provider在manifest中定义contentURI的访问权限。使用<provider>元素的android:grantUriPermisson属性,以及<grant-uri-permission>的子元素。关于URI权限机制的更多说明在Security and Permission教程中的“URI Permssions”一章。

例如你可以从Contacts Provider中检索联系人,尽管你不用有该provider的READ_CONTACTS访问权限。你可能在一个应用中想通过这种方式,向你的联系人在生日那天发送电子祝福。与其获取联系人provider的READ_CONTACTS权限,来可以访问所有的联系人,不如由用户指定你的应用可以访问那些联系人。这么做要遵循以下几个步骤:
1.使用startActivityForResult方法,来传递一个包含了ACTION_PICK 的action以及一个contact MIME类型CONTENT_ITEM_TYPE.
2.因为这个intent匹配了另一个应用的“选择”activity,这个activity出现到了前台。
3.在选择activity中,用户选择了一个要更新的联系人。当这时,选择activity就会通过调用setResult(resultcode,intent)来建立一个返回给你原来应用的intent。这个intent包含了用户选择的联系人的content URI,和一个Extra flags的数据,FLAG_GRANT_READ_URI_PERMISSON。这些标志位赋予了你的应用读取content URI指定的的联系人数据。选择activity会接着调用finish()方法来将控制权交回到原来的activity。
4.你的应用重新回到了前台,并且系统调用了你的应用中的onActivityResult()方法。这个方法接收从那个app中的选择activity中返回的结果intent。
5.通过使用结果intent中包含的content URI,你可以从Contact Provider中读取联系人的数据,尽管你没有那个provider的永久访问权限。你就可以获取这个联系人的生日信息或者email地址,来发出电子祝福了。

使用另一个应用

另个访问你没有永久权限的provider中的 数据的办法就是激活另一个有访问权限的应用,然后让用户在这个应用上进行操作。

例如,日历应用就可以接受一个 ACTION_INSERT intent,它可以让你激活这这个应用的插入UI。你可以在intnet的Extra中插入数据,这样UI可以使用这些数据进行提前填充。因为重复时间具有复杂的语法,所以更好的向日历provider插入事件的方法就是使用ACTION_INSERT来激活日历应用,然后让用户在那里插入事件。



协议类

协议类中定义了一些可以有助于content provider使用 content URI,栏目名称,intent action,以及其他功能的一些常量。协议类不会自动地包含进content provider,开发content provider的人必须自己定义他们并且可以让其他的开发者能够获取。很多的android平台的provider都有对应的协议类。他们在android.provider包下面。

例如,User Dictionary Provider 有一个叫做UserDictionary的协议类,包含了content URI和栏目名称常量。words表的content URI被定义在了常量UserDictionary.Words.CONTENT_URI当中。UserDictionary.Words类中还包含栏目名称的常量,他们在之前的教程的代码片中使用过。例如,一个查询的投影可以定义为如下的样子:
String[] mProjection =
{UserDictionary.Words._ID,UserDictionary.Words.WORD,UserDictionary.Words.LOCALE
};

另一个Contacts Provider的协议类是ContactsContract。这个类的参考文档包含例子代码片。他的一个子类,ContactsContract.Intents.Insert,是一个包含intent和intent data的常量。

MIME类型的引用

content provider可以返回标准的MIME类型数据,或者自定义MIME类型,或者两者都支持。
MIME类型数据格式如下。

type/subtype
例如有一个熟悉是MIME类型叫做 text/html,它的类型是text,子类型是html。如果一个provider 针对一个 URI返回这种类型,那意味着使用这个URI的查询将会得到包含HTML标签的text。

自定义类型的MIME类型字符串,也叫作“供应商指定”MIME类型,拥有更加复杂的类型和子类型。类型的值经常是:

vnd.android.cursor.dir
来表示多行。
vnd.android.cursor.item
来表示一行。
子类型是provider指定的。Android内置的provider通常都用一个简单的子类型。例如,当联系人应用创建了电话号码的行的时候,就在这一行上设定下面的MIME类型。
vnd.android.cursor.item/phone_v2
注意到这个子类型值就是简单的phone_v2。

其他的provider开发者可以根据provider的职权和表名,创建他们自己的子类型的模式。思考一个存储列车时刻表的provider。provider的职权是com.example.trains,并且其中包含三条线路表Line1,Line2,Line3。对应如下的content URI。

content://com.example.trains/Line1
对应table Line1,provider返会如下是数据类型。

vnd.android.cursor.dir/vnd.example.line1


而对于下面的URI

content://com.example.trains/Line2/5
对应的是Line2表达第五行,provider返回MIME类型如下。

vnd.android.cursor.item/vnd.example.line2

大多数content Provider都会定义他们使用 的MIME类型对应的协议类。例如 联系人provider对应的协议类ContactsContract.RawContacts,就为单个的原始联系人行数据定义了CONTENT_ITEM_TYPE。

单独一行的Content URIs在Content URIs里面有更多的描述。




























 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 《QQ西游》,最接近神的一个

    《QQ西游》,最接近神的一个久不搞魔兽,最近心血来潮,找了几个新网游玩。第一次听说《QQ西游》,是在去年“腾讯嘉年华”上,印象中大幅的宣传海报上赫然写着“娶个妖精做老婆”,走非清纯路线的女主角戴唇钉,第一感觉是这游戏定位为90后为主的年轻玩家群体。最近几天这游戏…...

    2024/4/19 0:23:51
  2. QT项目卡死在Reading Project

    在打开项目时,或做出一些修改后重新编译会出现这些问题; 解决方式: 先强行关掉QT,进入项目目录下,删除后缀为.user和.user.xxxx的文件;然后重新打开即可...

    2024/3/31 7:27:48
  3. 一步步学习Linux多任务编程

    系统调用01、什么是系统调用?02、Linux系统调用之I/O操作(文件操作)03、文件描述符的复制:dup(), dup2()多进程实现多任务04、进程的介绍05、Linux可执行文件结构与进程结构06、多进程实现多任务(一):fork()07、多进程实现多任务(二):vfork()08、进程的控制:结束进程…...

    2024/4/18 23:58:10
  4. 设计模式之UML类图该怎么画

    关于可维护、可复用、可扩展、灵活性好的理解: 生活中:印刷术和活字印刷,当需要对某些内容修改时,印刷术只要有一丁点变化,就需要重头再来;而活字印刷只需要进行部分修改即可。 可维护:只更改要更改的内容; 可复用:之前的内容并非用完就无用,后面仍可使用; 可扩展:…...

    2024/4/17 6:27:10
  5. leetcode - 贪心算法(一)

    先导:为什么要做leetcode?现实收益角度看,无论你是算法、数据、前端、后端工程师等等,目前大厂互联网公司面试肯定要考察的,国外google和facebook等等更盛 。都是从leetcode或者类似的网站上出题,如果不熟练,一面都过不了,与心仪的公司失之交臂。我认为它的价值在哪呢?…...

    2024/3/31 20:43:46
  6. 2018年最新Python的人工智能深度学习框架Tensorflow 入门教程+源码

    Python的人工智能深度学习框架Tensorflow 入门视频教程+源码下载地址:百度网盘...

    2024/4/24 13:47:09
  7. 【翻译】(9-补丁2)电话簿提供者

    【翻译】(9-补丁2)电话簿提供者see http://developer.android.com/guide/topics/providers/contacts-provider.html原文见 http://developer.android.com/guide/topics/providers/contacts-provider.html-------------------------------Contacts Provider电话簿(注:联系人,…...

    2024/5/6 7:15:26
  8. 设计模式之工厂模式(简单工厂,工厂方法,抽象工厂)

    此篇文章介绍工厂模式包含3种:简单工厂,工厂方法,抽象工厂。 下面一一介绍 背景:开一家比萨店,店子位于对象村 简单工厂: 进行初步设计,你可能进行如下设计现在,店子扩张,需要更多的比萨类型。。。修改设计: 通过传递一个“type”,来决定创建这个比萨问题有来了:需要…...

    2024/4/17 6:25:34
  9. 适合少儿学习编程的工具

    打定主意,要教小孩学编程,于是到处找简单易学的编程工具。网上推荐信息太多,陷入选择综合症。一天大学同学小侯推荐Scratch编程工具,说简单易学,上网一查,乖乖,确实极合我意,直观,易用。闲话少说,先看看Scratch是什么东东?http://www.codepku.com/information/351根…...

    2024/4/26 10:41:51
  10. 从一个游戏开始看设计(二)

    从一个游戏开始看设计地下城与勇士 表现层建模 抽象层建模 成长体系建模 战斗体系建模 副本体系建模 随机数体系建模 竞技体系建模 经济体系建模 文化元素建模结语从一个游戏开始看设计——地下城与勇士导语:号称最好的2D横版格斗类游戏,这一次我们会从表现层与抽象层找出这个…...

    2024/4/25 19:30:49
  11. Altium PCB快捷键篇(自己整理)

    Alt+F5:切换全屏模式 Shift+s : 切换单层视图模式(隐藏丝印使界面简洁)(重要) Ctrl + shift + 滚轮 :层切换 滚轮 :上下移动窗口 Shift + 滚轮 :左右移动窗口ctrl + D,在多边形里选择隐藏即可。 隐藏敷铜的方法隐藏敷铜的方法选…...

    2024/5/6 16:03:46
  12. Java设计模式之——工厂方法模式

    工厂方法模式简单介绍工厂方法模式是创建型设计模式之一。工厂方法模式是一种结构简单的模式,其在我们平时开发中应用很广泛。如 Android 中的 Activity 里的各个生命周期方法,以 onCreate 方法为例,它就可以看作是一个工厂方法,我们在其中可以构造我们的 View 并通过 setC…...

    2024/5/6 5:28:19
  13. 非常好用的在线编程网站

    编程几乎已经成为了人类所知每个行业的必要组成部分,如今有越来越多的人开始了他们的编程之旅。如果你正在在学习编程,那么我可以告诉你一个提高技能的好方法,那就是敢于去解决编码过程中遇到的难题。解决不同类型的难题,可以帮助你成为一名优秀的问题解决者。我整理了一些…...

    2024/5/6 12:38:38
  14. 基于python语言,使用爬虫和深度学习来预测双色球(二、模型训练与测试)

    在上一篇博文中(基于python语言,使用爬虫和深度学习来预测双色球(一、数据的准备)),我们完成了数据的准备,通过爬虫的方式将2003年至今的每一期的中奖数据保存到了txt文件中,那么我们现在就开始深度学习模型的训练和预测。首先我们选择使用RNN的变种网络LSTM来实现双色球…...

    2024/4/17 6:27:52
  15. Jenkins自动部署SpringCloud项目

    1.本地准备Tomcat环境 2.jenkins下载地址https://jenkins.io/zh/download/ 选择war包下载image.png下载后把war包放入Tomcat的webapps目录下,之后启动Tomcat3.浏览器输入http://localhost:8080/jenkins/进入jenkins页面(Tomcat端口号为8080),等待...image.png4.打开提示目录下…...

    2024/5/6 12:17:41
  16. 连发冲突

    为什么我用这个连发会和方向发生冲突呢。在DNF游戏中,不按方向按普通攻击有反应,而攻击时和方向同时运作时连发就失效了。角色就不砍了,在空中按方向组合攻击键也是无效,不按方向,就有效果。这是怎么回事啊。...

    2024/4/11 11:30:11
  17. Android 学习笔记 Contacts ContentResolver query、add、update、delete 参数详解

    1.获取联系人姓名一个简单的例子,这个函数获取设备上所有的联系人ID和联系人NAME。public void fetchAllContacts() {ContentResolver contentResolver = this.getContentResolver();Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTE…...

    2024/4/4 22:33:49
  18. 开源大数据查询分析引擎现状

    http://www.venustech.com.cn/NewsInfo/531/25567.Html引言 大数据查询分析是云计算中核心问题之一,自从Google在2006年之前的几篇论文奠定云计算领域基础,尤其是GFS、Map-Reduce、Bigtable被称为云计算底层技术三大基石。GFS、Map-Reduce技术直接支持了Apache Hadoop项目的诞…...

    2024/4/20 11:25:37
  19. 工厂方法模式(Factory Method Pattern)

    前言介绍 简单工厂定义 简单工厂类图概述 定义 涉及的策略 模式结构 类图 需要注意的东西适用场景 设计模式的实现 场景说明 代码实现 运行结果总结前言介绍简单工厂定义​ 又称之为静态工厂方法。在简单工厂中,可以根据传递的参数不同,返回不同类的实例。简单工厂定义了一…...

    2024/4/26 2:54:16
  20. python 深度学习(5)-- 随机失活 & 过采样

    (1)随机失活随机失活 指的是在每轮训练时忽略一定随机数量的神经元,dropout 可能会提高 DNN 性能。随机省略一部分隐藏的神经元的过程称之为 随机失活 。如图阐释一下这种方法:对于每次训练的实例,每个隐藏层的神经元以 p 的概率从网络中随机被忽略。由于神经元是随机选择…...

    2024/4/17 6:27:04

最新文章

  1. CCF-CSP认证考试 202403-1 词频统计 100分题解

    更多 CSP 认证考试题目题解可以前往&#xff1a;CSP-CCF 认证考试真题题解 原题链接&#xff1a; 202403-1 词频统计 时间限制&#xff1a; 1.0 秒 空间限制&#xff1a; 512 MiB 题目描述 在学习了文本处理后&#xff0c;小 P 对英语书中的 n n n 篇文章进行了初步整理。 …...

    2024/5/9 0:13:22
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. HTML——3.链接、头部、图像

    一、链接 HTML 中的链接由 <a> 标签定义&#xff0c;用于创建可点击的文本或图像&#xff0c;以便导航到其他页面或资源。下面是一个简单的 HTML 链接示例&#xff1a; <a href"https://www.example.com">Visit Example</a> 在这个示例中&#…...

    2024/5/8 21:23:10
  4. centos7 安装 postgresql

    进入地址&#xff1a;https://yum.postgresql.org/repopackages.php 鼠标放置红色框内&#xff0c;右击拷贝地址 yum install 拷贝的地址 例如&#xff1a;yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch…...

    2024/5/8 1:28:11
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/8 20:48:49
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/8 20:38:49
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57