版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、android 內(nèi)容提供者 contentprovider 總結(jié)一.contentprovider 基礎(chǔ)知識(shí)contentprovider作為android四大組件之一,相對(duì)其他 組件來(lái)說(shuō),應(yīng)用的場(chǎng)合是最少的了,但是它是有自己獨(dú)特的 作用的,比如為其他程序提供數(shù)據(jù)。contentprovider和其 他四個(gè)組件一樣,使用自己編寫(xiě)的類時(shí),要在 androidmanifest 里面注冊(cè)。contentprovider內(nèi)部如何保存數(shù)據(jù)由其設(shè)計(jì)者決定.但 所有的contentprovider都實(shí)現(xiàn)了一組通的方法來(lái)提供數(shù)據(jù) 的增刪改查功能.客戶端通常不會(huì)直接使用這些方法,大多數(shù)據(jù)是通過(guò) contentr
2、esolver 對(duì)象實(shí)現(xiàn)對(duì) contentprovider 的操作開(kāi)發(fā) 人員可以通過(guò)調(diào)用activity或者其它應(yīng)用程序組伯的實(shí)現(xiàn) 類中的 getcontentresolver ()方法 來(lái)獲得 content provider 對(duì)象,如i: contentresolver cr=getcontentresolver();使用contentresolver提供的方法可以獲得content provider中任何感興趣的數(shù)據(jù).不同進(jìn)程之間通信由 contentprovider 類和contentresolver 類處理.(一)數(shù)據(jù)模型contentprovider使用基本數(shù)據(jù)庫(kù)模型的簡(jiǎn)單表格來(lái)提
3、供 其中的數(shù)據(jù),這里每行代表一條記錄,每列代表特定類型和 含義的數(shù)據(jù)例如,聯(lián)系人的信息可以如下idnamenumberemail001張三123*123*163 com002李四132*132*google. com003王五414*414*qq. com每條記錄包含一個(gè)數(shù)值型的_id字段,它用于在表格中唯一標(biāo)記該記錄id每條記錄包含一個(gè)數(shù)值型的_id字段,它用于在表格中唯 一標(biāo)記該記錄id能用于匹配相關(guān)表格中的記錄,例如在一 個(gè)表格中查詢聯(lián)系人電話,在另一個(gè)表格中查詢照片 查詢 返回一個(gè)cursor對(duì)象,它能遍歷各行各列來(lái)讀取各個(gè)字段的 值對(duì)于各個(gè)類型的數(shù)據(jù),cursor對(duì)象都提供專用的方法
4、.因此,為了讀取字段的數(shù)據(jù),開(kāi)發(fā)人員必須知道當(dāng)前字段 包含的數(shù)據(jù)類型。其實(shí)這個(gè)增刪改查的操作實(shí)現(xiàn)和android數(shù)據(jù)庫(kù)的操作 是底層實(shí)現(xiàn)是一樣的,只是我們客戶端操作調(diào)用的是寫(xiě)好的 方法來(lái)實(shí)現(xiàn),基本的數(shù)據(jù)的關(guān)鍵字還是要我們自己來(lái)填寫(xiě)的。(二)uri的用法對(duì)于contentprovider來(lái)說(shuō)uri是非常需要理解的知識(shí)。在電腦術(shù)語(yǔ)中,統(tǒng)一資源標(biāo)識(shí)符(uniform resource identifier,或uri)是一個(gè)用于標(biāo)識(shí)某一互聯(lián)網(wǎng)資源名稱 的字符串。該種標(biāo)識(shí)允許用戶對(duì)任何(包括本地和互聯(lián)網(wǎng)) 的資源通過(guò)特定的協(xié)議進(jìn)行交互操作。uri由包括確定語(yǔ)法 和相關(guān)協(xié)議的方案所定義。每個(gè)content
5、provider提供公共的uri來(lái)唯一標(biāo)識(shí)其數(shù)據(jù) 集,管理多個(gè)數(shù)據(jù)集(多個(gè)表格)的contentprovider為每個(gè) 都提供了單獨(dú)的uri.也就是說(shuō)每一個(gè)uri對(duì)于一個(gè)表格,我們可以通過(guò)某個(gè) uri來(lái)實(shí)現(xiàn)對(duì)某個(gè)表格進(jìn)行相應(yīng)的操作,比如找到電話號(hào)碼 表格的uri才能讀取里面的通話數(shù)據(jù)。所提供的uri都以content:/作為前綴” content:/” 模式表示數(shù)據(jù)由content provider來(lái)管理 如果自定義 content provider,則應(yīng)該也是其uri定義一個(gè)常量,以簡(jiǎn)化 客戶端代碼并讓日后更 新更加簡(jiǎn)潔.android為當(dāng)前平臺(tái)提供的content provider定義了
6、content_uri常量.匹配電話號(hào)碼到聯(lián)系人表格的uri和匹 配保存聯(lián)系人照片表格的uri分別如下. android, provider. contacts. phones. content. uri; android, provider. contacts. photos. content. uri;uri常量用于所有與content provider的交互中.每個(gè) contentresolver方法使用uri作為其第一個(gè)參數(shù).它標(biāo)識(shí) contentresolver應(yīng)該使用哪個(gè)provider以及其中的哪個(gè)表 格.下面是content uri重要部分的總結(jié)比女口 uri: content
7、:/com. hua. employeeprovider/dba/001上面的uri分四部分第一部分:標(biāo)準(zhǔn)的前綴(content:/),用于標(biāo)識(shí)該數(shù)據(jù)由 content provider管理,它永遠(yuǎn)不用修改。第二部分:uri的authority部分,它標(biāo)識(shí)該content provider.對(duì)于第三方應(yīng)用,該部分一般是完整的包名(小寫(xiě)) 來(lái)保證唯一性。女口果是自定義的 contentprovider 要在 androidmanifest 中的 provider 聲明 authority.第三部分:content provider的路徑部分,用于決定哪類 數(shù)據(jù)被請(qǐng)求,如果contentprovi
8、der僅提供一種數(shù)據(jù)類型,這 部分可以沒(méi)有如果提供幾種類型,包括子類型,這部分可以 由幾部分組成.比如對(duì)數(shù)據(jù)庫(kù)不同表格或?qū)Ρ砀竦牟煌僮?都可以使用路徑來(lái)區(qū)分。第四部分:被請(qǐng)求的特定的記錄的id值.這是被請(qǐng)求記錄 的_id值.如果請(qǐng)求不僅限于單條記錄該部分及前面的斜線 應(yīng)該刪除。二.系統(tǒng)中預(yù)定義的contentproviderandroid系統(tǒng)為常用數(shù)據(jù)類型提供了很多預(yù)定義的contentprovider(聲音,視頻,圖片,聯(lián)系人),它他大部分位于android, provider包中,開(kāi)發(fā)人員可以查詢這些 provider經(jīng)獲得其中包含的信息.android系統(tǒng)提供的常見(jiàn)content pr
9、ovider 說(shuō)明如下1. browser:讀取或修改書(shū)簽,瀏覽歷史或網(wǎng)絡(luò)搜索.2. calllog:查看或更新通話歷史.3. contacts:獲取、修改或保存聯(lián)系人4. livefolders:由 content provider 提供 內(nèi)容的特定文 件夾5. mediastrore:訪問(wèn)聲音,視頻和圖片6. setting:查看和獲取藍(lán)牙設(shè)置,鈴聲和其它設(shè)備偏好.7. earchrecentsuggestions:該類能為應(yīng)用程序創(chuàng)建簡(jiǎn)單 的查詢建議提供者,它基于近期查詢提供建議.8. syncstatecontract:用于使用數(shù)據(jù)數(shù)組帳號(hào)關(guān)聯(lián)數(shù)據(jù) 的content provider約
10、束,希望使用標(biāo)準(zhǔn)方式保存數(shù)據(jù)的 provider可以使用它.9. userdictionary:在可以預(yù)測(cè)文本輸入時(shí),提供用戶定義的單詞給輸入法使用應(yīng)用程 序和輸入法能增加到該字 典,單詞能關(guān)聯(lián)頻率信息和本地化信息.其中上面大部分的contentprovider并不常用,??绰?lián)系 人信息是比較常用的。二查詢數(shù)據(jù)在 contentprovider中查詢數(shù)據(jù),開(kāi)發(fā)人員需要知道以下1=1信息:(一) 標(biāo)識(shí)該 content provider 的 uri(二) 需要查詢的數(shù)據(jù)字段名稱和字段中數(shù)據(jù)的類型如果需要查詢特定記錄,那么還需要知道該記錄的id值.一般使用contentresolver對(duì)象的que
11、ry ()方法完成查詢 功能,都返回cursor對(duì)象.query ()方法的聲明如下public final cursor query(uri uri, string projection, stringselection,string selectionargs, string sortorder)參數(shù)一:uri:用于查詢的 content providerr uri 值參數(shù)二:projection:由需要查詢的列名組成的數(shù)組,如果為null則不勝枚舉查詢?nèi)苛袇?shù)三:selection:類似sql中的where子句,用于增加條件來(lái)完成數(shù)據(jù)過(guò)慮參數(shù)四:selectionargs:用于替換se
12、lection中可以使用? 表示的變量值參數(shù)五:sortorder:類似sql中的order by子句,用于 實(shí)現(xiàn)排序功能返回值:cursor對(duì)象,它位于第一條記錄之前,或者為 null為了限制僅返回一條記錄,可以在url結(jié)尾加該記錄的 _id值,即將匹配id值的字符串作為uri路徑部分的結(jié)尾片 段.四. 自定義 contentprovider如果開(kāi)發(fā)人員希望共享自己的數(shù)據(jù),可以自定義content provider步驟如下建立數(shù)據(jù)存儲(chǔ)系統(tǒng),大多數(shù)contentprovider使用 android文件存儲(chǔ)方法或者sqlite數(shù)據(jù)庫(kù)保存數(shù)據(jù),但是開(kāi) 發(fā)人員可以使用任何方式存儲(chǔ).(一)使用自定義的
13、contentprovider必須要做的:1. 繼承contentprovider類來(lái)提供數(shù)據(jù)訪問(wèn)方式。實(shí)現(xiàn)contentprovider里面的六個(gè)方法,(1) 重寫(xiě)oncreate方法里面創(chuàng)建數(shù)據(jù)庫(kù)(2) 重寫(xiě)增刪改查操作的方法,也可以不用全部重寫(xiě), 比如你只想讓其他程序訪問(wèn)本程序的數(shù)據(jù),而不能進(jìn)行其他 的操作,只需要重寫(xiě)query方法就可以了,其他方法可以不 重寫(xiě)。2. 在應(yīng)用程序的androidmanifest文件中聲明contentprovidero代碼如下:<providerandroid:name= mycontentprovider"android: author
14、 it ies=zzcom lwz provider"android:exported二true" />如果想要外部能訪問(wèn)自己程序的資源上面三個(gè)屬性是必 須要設(shè)置的。自定義的uri用到的知識(shí)相對(duì)就比較多一點(diǎn),如果是多表, 又有增刪改查各種操作,必須對(duì)uri進(jìn)行比較全面的定義和 規(guī)范使用。(二)urimatcherurimatcher類主要用于規(guī)范匹配urio比如給uri添加路徑和id號(hào)。系統(tǒng)判斷到相應(yīng)的類別就做相應(yīng)的操作。使用方法如下。1 初始化:urimatchermatcher=newurimatcher(urimatcher. n0_match);2.注冊(cè)需要的
15、uri:matcher adduri(com whunf, "people", people);或 matcher adduri ("com whunf''person/people_id);一個(gè)表的不同操作可以注冊(cè)多個(gè)uri。3與已經(jīng)注冊(cè)的uri進(jìn)行匹配:(1) uri uri 二 uri. parse ("content:/+"com. whunf" + "/people");這個(gè)uri是訪問(wèn)者填寫(xiě)的。(2 ) int match = matcher .match (uri);這里的match是
16、在contentprovider里面定義的,做判斷 和匹配也是在contentprovider里面進(jìn)行的。switch (match)case people:return vnd. android. cursor dir/people/z;case people_id:return vnd android cursor item/people;default:return null:match方法匹配后會(huì)返回一個(gè)匹配碼code,即在使用注冊(cè) 方法adduri時(shí)傳入的第三個(gè)參數(shù)。上述方法會(huì)返回 z/vnd. android. cursor dir/person總結(jié):常量urimatcher. n
17、o match表示不匹配任何路徑的返回#號(hào)為通配符*號(hào)為任意字符官方sdk說(shuō)明中關(guān)于uri的注冊(cè)是這樣寫(xiě)的:private static finalurimatchersurtmatcher = newurimatcher (urimatcher. no_matcii);static sur i matcher. adduri (z/contactsz,,"/people",people);surimatcher. adduri("contacts", "/people/#", people id);surtmatcher. addu
18、ri (,zcontacts/z, /people/#/phones", people piione s); surimatcher. adduri (''contacts'', "/people/#/phones/#,people_pi1o nes_id); slrimatcher adduri ("contacts", /people/#/contact methods'7, peo ple_contactmethods);surimatcher. adduri("contacts", eo
19、ple contactmethods td);surtmatcher. addurt("contacts", surimatcher. adduri("contacts", surimatcher. adduri("contacts", surimatcher adduri("contacts", surtmatcher. adduri("contacts", surimatcher. adduri("contacts", surimatcher. adduri (/zcal
20、l_logz,, surimatcher. adduri(call_log,"/people/#/contiict methods/p/deleted_peopl"/phones","/phones/fi1 ter/*", "/phones/con tactmethods77,/contact_methods/“/calls”,"/calis/fiiter/*",deleted_peopl e); phones);phones_filter);phones id);contactmethods);contactme
21、t iiods_id);calls);calls_f1lter) ;vcalls/#', calls id);surimatcher. adduri ("call log",其實(shí)上面只是提供一種書(shū)寫(xiě)的規(guī)范,提供我們參考。也可 以按照自己的思路來(lái)注冊(cè)u(píng)rio(三) content uriscontenturis類用于獲取uri路徑后面的id部分 為路徑加上 id 的方法:withappendedld(uri, id) 比如有這樣一個(gè)uriuri uri = uri. parse(z/content :/com. whunf/people)通過(guò)withappendedl
22、d方法,為該uri加上id1. uri resuituri 二 contenturiswithappendedld(uri, 10);最后 resulturi 的字符串為: content:/com whunf/people/10從路徑中獲取id: parseld(uri)1. uriuri=uri. parse ("content:/com. whunf/people/10z,)2. long personid = contenturisparseld(uri);最后 personid 為:10五.下面是一個(gè)訪問(wèn)手機(jī)聯(lián)系人的信息的使用示例 程序分析:手機(jī)聯(lián)系人的信息是在androi
23、d中某個(gè)固定的位置的,它的uri也是系統(tǒng)規(guī)定好的,需要我們?nèi)ゲ?。手機(jī)聯(lián)系人里面不止一個(gè)表,字段也很多,這個(gè)也是需要 我們了解后,才能取得它對(duì)應(yīng)的信息。里面很多信息我們可以把手機(jī)電話信息的數(shù)據(jù)導(dǎo)出后再, 研究里面的元素,這里打開(kāi)手機(jī)數(shù)據(jù)庫(kù)文件的工具一般使用 的是:sqlite expert professional 視圖根據(jù)。下面是查詢所有用戶的姓名和號(hào)碼的java代碼package com. lwz. provider;import android content. contentresolver;import android content. contentvalues;import and
24、roid, database cursor;import androidnet> uri;import androidos. bundle;import android provider. contactscontract;import android support. v7 app appcompatactivity;import android, util.log;import java, uti la rraylist;import javauti1. list;public class mainactivity extends appcompatactivity ©ov
25、errideprotected void oncreate (bundle saved!nstancestato) super. oncreate(savedlnstancestale); setcontentview(r. layout, activity main);操作電話本數(shù)據(jù) selectphoneo ;private void selectphoneo /獲得 contentresol ver 對(duì)彖contentresolver resolver = getcontentresolver();/獲得系統(tǒng)定義的電話某一個(gè)表格的uri (這里対應(yīng)的是數(shù)據(jù)庫(kù)的contacts表,這個(gè)表主
26、要數(shù)存放用戶的id)uri uri = contactscontract. contacts. content_uri;/這是系統(tǒng)類定義好的 字符串的uriuri/獲取該uri下的信息cursor cursor = resolverquery(uri, null, null, null, null);/創(chuàng)建一個(gè)list集合存放用戶對(duì)彖的數(shù)據(jù)list<user> list = new arraylisto();遍歷取出數(shù)據(jù),這里涉及到多表查詢,因?yàn)閿?shù)據(jù)存儲(chǔ)是分類在多個(gè)表屮 whi 1 e (cursor. movetonext () /獲得用戶的id,參數(shù)數(shù)字段名稱的字符串longi
27、dcursor. getlong(cursor. getcolumnlndex(''nameaw contact_id");/log. e("tag", "id二"+ id);/創(chuàng)建一個(gè)user來(lái)存儲(chǔ)信息user user = new user();user, id = id;/根據(jù)獲取的到的用戶的id,來(lái)分別獲取它的數(shù)據(jù),這些數(shù)據(jù)又是在另 一個(gè)表中/獲得系統(tǒng)定義的電話某一個(gè)表格的uri (這里對(duì)應(yīng)的是數(shù)據(jù)庫(kù)的data 表,這個(gè)表里面有最全面的信息)/正是因?yàn)橛捎谘儽砝锩娴臄?shù)據(jù)最多,所以顯示或排列的順序不一定 正常,需要我們提
28、供一個(gè)td來(lái)查找對(duì)應(yīng)的數(shù)據(jù)uri uri2 = contactscontract. data. content_uri;/等同uriuri2=ur i. parse (z/c onten t: /com. an droid, con tacts/datazz );根據(jù)剛才獲得的用戶的id值來(lái)分別獲取對(duì)應(yīng)的數(shù)據(jù)/獲取該u"2下的信息/ string d二contactscontract. contacts. data. raw_contact_id;這里的 字符串d等同于z,raw contact id"cursor cursor2 = resolver.query(uri2
29、, null, "raw_contact_id二?", new stringid +null);獲取每一個(gè)用戶id里面某些信息while (cursor2. movetonext() 獲取用戶的姓名/contactscontract. contacts. display_name->"di splay_name,zuser, namecursor2. getstring(cursor2. getcolumnlndex("display name");/ contactscontract. data. data1>"data
30、luser, phone, add(cursor2. getstring(cursor2. getcolumnlndex ("clatal");1 ist. add (user);/打卬輸出內(nèi)容for (int i = 0; i < list. size(); i+) log. e("tag", list, get (i). tostring();/創(chuàng)建一個(gè)用戶信息類 class user long id;/用戶的 tdstring name;/用戶的姓名list<string> phone = new arraylisto() ;/用
31、戶的多個(gè)號(hào)碼顯示用戶的數(shù)據(jù)©overridepublic string tostringo return "user" +id= + id +,name= + name +"、phone二"+ phone +在手機(jī)聯(lián)系人中,每添加一個(gè)用戶信息都會(huì)對(duì)應(yīng)一個(gè)id, 但是這條信息可以包含多個(gè)用戶的名稱或多個(gè)號(hào)碼,我們只 需要取其中的一部分就可以了。為了更好的去熟悉相關(guān)數(shù)據(jù)的操作,最好是把數(shù)據(jù)庫(kù)的文 件,導(dǎo)出來(lái),看看數(shù)據(jù)的結(jié)構(gòu)。android程序安裝的文件都放在/data/date路徑下,系統(tǒng)的提供的所有contentprovider也在這個(gè)包下:52
32、016-10-19072016-10-19072016-10-19072016-10-1907> d tips> 0 viders.calendar> viders.contactsv viders.downloads耳 viders.downloads.ui> e viders.mediad viders.settings> d com.android.p
33、roviders.telephony> 3 viders.userdictionary“ ufll.ailmf viu.ncipccu:” 3 com.android.packageinstaller> 3 com.android.pacprocessor> 厶 com.android.phone> d com.android.printspooler凸 xyhandler> & com.android.quicksearchbox2016-10-19 07 2016-10-19072016-10
34、-19072016-10-19072016-10-19 07 2016-10-19072016-10-19072016-10-19072016-11-07022016-10-19 072016-10-19072016-10-19 07> b com.android.sdksetup上面的幾個(gè)包名,都有providers ,這是系統(tǒng)的contentprovider程序包,里面包含相關(guān)的數(shù)據(jù)庫(kù)文件。比如:聯(lián)系人的信息在 com. android, provider, contacts 包內(nèi)。 其他的包有的是下載過(guò)得文件數(shù)據(jù),有的是手機(jī)撥號(hào)記錄數(shù)據(jù),有的是瀏覽器歷史記錄數(shù)據(jù)等等。導(dǎo)出手機(jī)聯(lián)系人的數(shù)據(jù)庫(kù)方法:芟 threads heap i® allocation .歹 network s iff1 file explor.二 q emulatorf system in仁 sw <8 1 -1 pnameme permissions a> g com.android.printspooler& viders.calendar厶 3 viders.contacts ache 3 databasescontacts2.dblj contacts2.d
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年電子商務(wù)平臺(tái)軟件開(kāi)發(fā)與運(yùn)營(yíng)服務(wù)合同范本2篇
- 2025年度祠堂古建筑安全監(jiān)測(cè)與維護(hù)承包合同3篇
- 2024年金屬屋面施工合同
- 2024櫥柜購(gòu)銷合同書(shū)范文
- 精神科護(hù)理部人員緊急狀態(tài)下的調(diào)配預(yù)案
- 2024挖掘機(jī)操作員實(shí)習(xí)實(shí)訓(xùn)基地合作協(xié)議3篇
- 中醫(yī)針灸治療過(guò)敏性鼻炎經(jīng)驗(yàn)總結(jié)報(bào)告
- 2024年門面租借轉(zhuǎn)租合同
- 全球禮儀教育解析
- 歷史解密:研究視角
- MOOC 無(wú)機(jī)及分析化學(xué)(下)-華中農(nóng)業(yè)大學(xué) 中國(guó)大學(xué)慕課答案
- 人教版六年級(jí)下冊(cè)數(shù)學(xué)期末測(cè)試卷附答案【達(dá)標(biāo)題】
- 食品安全管理員理論考試題庫(kù)(濃縮300題)
- 員工工作狀態(tài)分析
- 河道水質(zhì)養(yǎng)護(hù)項(xiàng)目應(yīng)急預(yù)案
- 小學(xué)一年級(jí)數(shù)學(xué)口算題大全(1000多道)每天50道題
- 燙傷護(hù)理pdca案例
- “人工智能訓(xùn)練項(xiàng)目”-中華人民共和國(guó)第二屆職業(yè)技能大賽甘肅省選拔賽-技術(shù)工作文件
- 分布式發(fā)電技術(shù)的現(xiàn)狀與面臨的挑戰(zhàn)
- 《中小學(xué)實(shí)施教育懲戒規(guī)則試行》考核試題及答案
- 2023-2024學(xué)年浙江省寧波市慈溪市七年級(jí)(上)期末數(shù)學(xué)試卷
評(píng)論
0/150
提交評(píng)論