版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ScopedStorageScopedStorageAndroidQScopedStorageScopedStorageAndroidQAndroid版本中,APPScopedStorageApp-specificAPPspecific中,APP无需任何权限即可读写,而在公共目录中,APPMediaStoreSAF也就是说,AndroidQAPPApp-specific而在外部存储的其他空间上,APP读写是被更加严格地限制的,具体来说,APP需要申请app做限制)。ScopedStorage1.2.3.SAF4.MediaProviderAPPAndroidManifest.xmlandroid:requestLegacyExternalStorage=”truefalse”来设定APP外部存储视图模式。新属性在PackageParser.java里被解析并添加到PermissionPolicyServicePermissionPolicyServiceApplicationInfoAPPAppPermissionPolicyService.onStartUser开始,包括/APPAPP申请了AppOpsManager.OP_LEGACY_STORAGEAPPappopAPPlegacyviewAPKappopmountAPKAPPAPPgroupidmountmodegids包括从packagemanager获取的应用的permGids,和一些补充gids,其中参数mountExtStorageFull默认是false,所以mountmode由StorageManagerServiceENABLE_ISOLATED_STORAGEisolatedstorageENABLE_ISOLATED_STORAGEisolatedstoragescopedstorage特性开关是否打开了,有两个:PRO_ISOLATED_STORAGE_SNAPTSHOT(高优先级)AndroidQBeta4mountmodegetMountMode->1.Isolatedprocess(uid:99000-999991.Isolatedprocess(uid:99000-9999990000-98999),MOUNT_EXTERNAL_NONE3.APPREAD_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE分别对应于WRITE_MEDIA_STORAGE权限对应hasFull,从字面意义上就表示了全部权限。User-launchable的应用不允许申请该权限。 对应hasLegacy。它正是之前分析的当 时: 对应MOUNT_EXTERNAL_WRITE, 对MOUNT_EXTERNAL_READlegacyview模式时,MOUNT_EXTERNAL_DEFAULT。MountmodeNONE:APPmountspecificFULL:READ:gidsmountmode之后,processListzygotefork(->(->->->通过程Beta3mountdisable了,Beta4mounttargetBeta3mountdisable了,Beta4mounttargetAndroidPAPPsandbox(specificdirs)->->->->1.isolatedstorage模式,userstartAPPuser2.APPuserAPPappIdsandboxId3.volumevolumevisibleVolLabels->1.volumevolumeRoot=(->1.volumevolumeRoot=(primaryvolumeuserId:volumeRoot(primaryvolume然后新建文件夹:sandboxRoot2.sandbox2.1mntTargetRoot2.2volume新建primaryvolume2.3mntTargetRoot2.3mntTargetRoot3.rootName=mntFullSb=mntWriteSb=obbMountDir=循环/procpackagepidName=调用 获取mountMode。对于 /mnt/runtime/write/<volumeLabel>[/userId]/Android/sandbox/<sandboxId>bind /mnt/runtime/write/<volumeLabel>[/userId]/Android/obbbindmount/storage/<volumeLabel>[/userId]/Android/obb(对于mountmodeapksandbox(specificdirs)packagesapkapksdVolumeManagersandbox(specificdirs)2.VolumeManagersandbox(specificdirs)2.filepathFileFileOutputStream/InputStreamFileOutputStream.FileOutputStream(Filefile,booleanappend)(构造函数IoBridge.open(Stringpath,intflags)(fd,flagO_WRONLY|O_CREAT|O_APPENDflag来确定需要检查的权限BlockGuardOs.open(Stringpath,intflags,intmode)(mode仅在创建文件时使用Linux.open(Stringpath,intflags,intmode)(native方法->open(path.c_str(),flags,APPspecifcdirs/mnt/runtime/write/<volumeLabel>/[/userId]/Android/(data/media/obb)/packagebindAPPspecificdirs(T卡)APP进程的过程中,可以看到将/mnt/runtime/<mountmode>bindmount到/storagemountmodeAPPmountmodewrite,那么APP可以直接使用路径对文件进行读写,例如legacy视图模式且申请了WRITE_EXTERNAL_STORAGEmountmodefullAPP对所有外部存储APPmountmode3SAFSAFSystemAccessFramework。APPSAF选择文件、选择目录、创建文件,SAFUriAPP。APPUriUriAPP。APPUriSAF1.DocumentsProviderContentProviderMtpDocumentsProvider、MediaDocumentsProvider、ExternalStorageProvider2.文档选取器是客户端程序与文档提供程序之间的桥梁。因为文档需要受到保护,DocumentsProviderread/writepermissionMANAGE_DOCUMETS,而这个权限的等级是signatureDocumentsProviderUriDocumentUI的picker部分。APPintentDocumentUIPickActivity,DocumentUI向用户展示有层DocumentUIAPPuripermissionAndroid4.3ACTION_PICKACTION_GET_CONTENTUIAndroid4.4及更高版本,使用ACTION_OPEN_DOCUMENT可以调起系统提供的选择器注意:CTSMANAGE_DOCUMENTSpackagevendorAPP是想读取/ACTION_GET_CONTENT,使用此方法时,APP会导入数据的副APPAPPDocumentsProvider3.1DocumentsProviderAPPDocumentsProvider3.1DocumentsProvider1.一个DocumentsProvider可以提供多棵文件树,每棵树都定义了一个rootCOLUMN_ROOT_ID标记。rootCOLUMN_DOCUMENT_ID标记。root表征COLUMN_DOCUMENT_IDURI2.COLUMN_FLAGS下文档的元数据,其中的COLUMN_FLAGS就展示了这个Uri支持的操作,例如有3.COLUMN_DOCUMENT_ID4.permission必须是MANAGE_DOCUMENT,否则系统文档选择器无法使用定义的enableAPIenableAPItrue/falseAndroid4.3falseAPPACTION_GET_CONTENTpickeractivity,那么需要在运行设备Android4.4ACTION_GET_CONTENT这个过滤器。否则系统文档选择器打开时,APP会有两个入口。Intent-filterDOCUMENT_PROVIDERactioncontentproviderSAFdocumentprovider,系统的文档选择器选择文档数据源时,就是用这个action来匹配documentproviderDocumentsProvider1)queryRoots(String[]rootrootdocument才会出现在系统文档选择器的第三方栏目中。root的metadata被定义在合约类documentidprojection表示调用方想要返回的字段集合。rootnotifyChangerooturirootnotifyChangerooturirootUrirootUri2)queryChildDocuments(StringparentDocumentId,String[]projection,String返回指定目录下的子目录和文档,不递归。parentDocumentId是指定目录documentprojection是想要返回的字段集合,sortOrderTargetSDK26(O)APPqueryChildDocuments(String,String[],Bundle)APP如果想要监听某个目录下所有子目录/UriDocumentsProvidernotifyChangeUri3)DocumentsProvidernotifyChangeUri3)queryDocument(StringdocumentId,String[]返回指定文件的metadata。 DocumentsContract.Document 4)openDocument(StringdocumentId,Stringmode,CancellationSignalParcelFileDescriptor。mode是打开文件的模式,”r”4DocumentsProvider4DocumentsProvider如queryRecentDocuments(如果DocumentsProvider返回的root定义了件搜索,如果支持就需要实现这个方法,queryArgs决定)3.2DocumentUIAPP中。DocumentUIpackage主要有两个:filespicker。files对应了文件管理器,提供了文件管理的UI,用户可以查看、操作所有pickActivityrootroot下具体的文件/1.性复制大量文件的情况;DocumentClipperAPP内复制剪切操作的类。其中最重要ProvidersCacheDocumentsProvider。2.-mProviders:-mThumbnailCache:-mClipStore:-mClipper:-mDragAndDropManager:-mFileTypeLookup:Lookup<String,DocumentsApplicationonCreateDocumentsApplicationonCreateProvidersCacheUpdateTaskDocumentsProvider并缓存从它们中查询到的rootStoppedpackage里的DocumentsProviderDocumentUIAPPUIProvidersCache3.PickActivityPickActivityUIInjector<Textends-mObserver:(监听所有的DocumentsProvider的roots变化-mRecentRoots:-mRoots:Multimap<String,(保存所有authority和root的对应关系-mStoppedAuthorities:-mObservedAuthoritiesDetails:Map<String,PackageDetails>loadRootsForAuthority:检查exported、grantUriPermissions、添加PackageDetails到构建rootsUri(content://<authority>/root),并注册如果不是强制刷新,尝试从systemCache中获取authority对应的provider的所有RootInfo根据rootsUri,从provider中查询数据,并根据各个字段构建(authority/rootId/flags/icon/tilte/summary/availableBytes/mimeTypes/qeuryArgs/derivedType/把查询构建的结果保存到systemCache中class-mForceRefreshAll:-mForceRefreshPackage:-mTaskRoots:Multimap<String,-mTaskStoppedAuthorities:HashSet<String>根据nt.cio.OCUET_POVDE这个ntnt查询到合适的ContntPovider(即ocumntPovdr)。对每个ContntPovider,如果它的ppliaionnf里显示它所在的应用是toppd,就加入makSoppedAuhoriis;否则,查询DocumntPovdr中的所有roos,加入到makoot中。在同步代码块中,为ProvidersCache的mRoots和发送com.android.documentsui.action.ROOT_CHANGED的本地广播。internalstorageroot是否要展示;fileTypeLookupmimeTypelabel的匹配表;appsRowManagerRootFragmentitemview的构建与显一些选择过程中的数据,例如mRepeatedPickTimes,这个数据会被保存到getRootDocument组件中最重要的是Model类:它存储了当前加载的目录的数据模型。在updateDirectoryLoader去加载当前目录的子文件/DirectoryLoader 信息找到对应的 authority,然后利用最终会调用到对应的DocumentsProvider的queryChildDocuments或者querySearchDocumentsitemview中。Injector<TextendsActionHandler>-features:-config:-prefs:-messages:-fileTypeLookup:Lookup<String,-shortcutsUpdater:-menuManager:-dialogs:-searchManager:-appsRowManager:-pickResult:-actionModeController:-actions:-focusManager:-selectionMgr:-mModel:-getModel:-getFocusManager:-getActionModeController:-getActionHandler:-updateSharedSelectionTracker:当前加载的目录的数据模型-info:当前加载的目录的数据模型-info:-error:-doc:-mFeatures:-mPositions:Map<String,-mFileNames:-mUpdateListener:List<EventListener<Update>>-mCursor:-mCursorCount:-mIds:-addUpdateListener:-removeUpdateListener:-notifyUpdateListener:-reset:-update(DirectoryResultresult):-updateModelData():mIds与cursor中的数据顺序相同,id=mFileNames添加cursor中的_display_namemPositions添加id与cursorposition-getDocuments(Selection<String>selection):-getDocument(StringmodelId):-getItemUri(StringmodelId):4.mRoot表示当前处于的文档树;mList,维护了从文档树rootdocument5.4.mRoot表示当前处于的文档树;mList,维护了从文档树rootdocument5.-getRootDocument(RootInforoot):-getDocument(Uriuri):-getArchiveDocument(Uriuri):-isDocumentUri(Uri-findDocumentPath(Uriuri):-getDocuments(Stringauthority,List<String>docIds):-createDocument(DocumentInfoparentDoc,StringmimeType,StringdisplayName):UrisubclassRuntimeDocumentAccess-mList:-mRoot:当前root下的documentinfo-mObserver:监视被查询的Uri-mRoot:被查询的dir所在的-mUri:查询用的-mModel:封装查询到的cursor-mFileTypeLookup:Lookup<String,String>type匹配缓存-mSearchMode:判断是否在搜索模式下-mQueryArgs:仅在搜索模式下使用-mPhotoPicking:过滤查询到的-mDoc:查询uri对应的dir的doc-mResult:持有cursor的结果查询uri的由来:工具类,主要是再次封装了DocumentsContract中的一些合约方法,实现从Uri工具类,主要是再次封装了DocumentsContract中的一些合约方法,实现从Uri6.LastAccessedProvider中存储了上次选择文档完成时的DocumentStackdocumentstackprovidercallbackonPickFinishedonPickFinishedUriIntentpickresult(UI。-getLastAccessed:-setLastAccessed:(finishpicking或者createpickeddocument的时候更新设置-setLastAccessedToExternalApp:voidsubclassRuntimeLastAccessedStorage读写lastaccess到3.3SAFSAF3.3SAFSAFAPPAndroidAPPSAF,APPACTION...DocumentsProvidercreateDocument方法urur)SUPPORTS_DELETEDocumentsProviderdeleteDocument方法takeFlag)URIURI可能会失效,例如其他应用已经修改或删除了文件,URIgetContentResolver().takePersistableUriPermission()以检3.SAFDocumentsContractdocumentUritreedocumentdocumenturi可以直接打开输入/FDtreeUri持有对应目录的子目录/文档的权限。查询到子目录/documentDocumentsContract.findDocumentPathuriPathdocumentiddocumenturidocumentidtreeuricontent://Uricontent://Uri(UriGrantsManagerServiceUriSparseArray<ArrayMap<GrantUri,UriPermission>>Uiduri授(UriGrantsManagerServiceuriactivity、sendactivityresult(UriGrantsManagerServiceuriactivity、sendactivityresult接口加入数据缓存4MediaProviderScopedStorage新特性引入后,APPMediaStore1.无需权限,APPMediaStore2.READ_EXTERNAL_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论