Cursor cursor = getContentResolver().query(
Uri.parse("content://media/external/file"),
projection,
MediaStore.Files.FileColumns.DATA + " not like ? and ("
+ MediaStore.Files.FileColumns.DATA + " like ? or "
+ MediaStore.Files.FileColumns.DATA + " like ? or "
+ MediaStore.Files.FileColumns.DATA + " like ? or "
+ MediaStore.Files.FileColumns.DATA + " like ? )",
new String[]{"%" + bookpath + "%",
"%" + Constant.SUFFIX_TXT,
"%" + Constant.SUFFIX_PDF,
"%" + Constant.SUFFIX_EPUB,
"%" + Constant.SUFFIX_CHM}, null);
这是一段搜索media中后缀为txt,pdf,epub,chm格式的文档的源码.这里我们使用了一个内容URI"content://media/external/file/",然而这个URI究竟是在哪里呢?这是一个系统自带的一个内容URI,来自MediaPlayer.我们跟踪MediaPlayer的源码.
499 public static final Uri getContentUri(String volumeName) {
501 return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
502 + "/file/");
503 }
这里我们看到getContentUri方法返回了一个CONTENT_AUTHORITY_SLASH + volumeName + “/file/”,CONTENT_AUTHORITY_SLASH在类中已经定义了,
就是"media",那么volumeName代表的是什么呢,我们看到volumeName是作为参数传入的,因此我们搜索getContentUri方法,看看它都能传递什么参数,我们找到这么一行,
public static final Uri EXTERNAL_CONTENT_URI =
1164 getContentUri("external");
因此我们的内容URI确实是MediaPlayer提供的.并且在MediaPlayer类中组装成了EXTERNAL_CONTENT_URI,它的值就是"content://media/external/file",那么我们得到这个EXTERNAL_CONTENT_URI是做什么的呢?我们继续搜索,得到这么一段代码:
1072 public static final Cursor queryMiniThumbnail(ContentResolver cr, long origId, int kind,
1073 String[] projection) {
1074 return cr.query(EXTERNAL_CONTENT_URI, projection,
1075 IMAGE_ID + " = " + origId + " AND " + KIND + " = " +
1076 kind, null, null);
1077 }
说明MediaStore利用这个EXTERNAL_CONTENT_URI来进行CRUD操作,并且是利用ContentResolver来进行查询的,我们跟踪ContentResolver,定位到query方法:
782 public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
783 @Nullable String[] projection, @Nullable Bundle queryArgs,
784 @Nullable CancellationSignal cancellationSignal) {
785 Preconditions.checkNotNull(uri, "uri");
786 IContentProvider unstableProvider = acquireUnstableProvider(uri);
787 if (unstableProvider == null) {
788 return null;
789 }
790 IContentProvider stableProvider = null;
791 Cursor qCursor = null;
792 try {
793 long startTime = SystemClock.uptimeMillis();
794
795 ICancellationSignal remoteCancellationSignal = null;
796 if (cancellationSignal != null) {
797 cancellationSignal.throwIfCanceled();
798 remoteCancellationSignal = unstableProvider.createCancellationSignal();
799 cancellationSignal.setRemote(remoteCancellationSignal);
800 }
801 try {
802 qCursor = unstableProvider.query(mPackageName, uri, projection,
803 queryArgs, remoteCancellationSignal);
804 } catch (DeadObjectException e) {
805 // The remote process has died... but we only hold an unstable
806 // reference though, so we might recover!!! Let's try!!!!
807 // This is exciting!!1!!1!!!!1
808 unstableProviderDied(unstableProvider);
809 stableProvider = acquireProvider(uri);
810 if (stableProvider == null) {
811 return null;
812 }
813 qCursor = stableProvider.query(
814 mPackageName, uri, projection, queryArgs, remoteCancellationSignal);
815 }
816 if (qCursor == null) {
817 return null;
818 }
819
820 // Force query execution. Might fail and throw a runtime exception here.
821 qCursor.getCount();
822 long durationMillis = SystemClock.uptimeMillis() - startTime;
823 maybeLogQueryToEventLog(durationMillis, uri, projection, queryArgs);
824
825 // Wrap the cursor object into CursorWrapperInner object.
826 final IContentProvider provider = (stableProvider != null) ? stableProvider
827 : acquireProvider(uri);
828 final CursorWrapperInner wrapper = new CursorWrapperInner(qCursor, provider);
829 stableProvider = null;
830 qCursor = null;
831 return wrapper;
832 } catch (RemoteException e) {
833 // Arbitrary and not worth documenting, as Activity
834 // Manager will kill this process shortly anyway.
835 return null;
836 } finally {
837 if (qCursor != null) {
838 qCursor.close();
839 }
840 if (cancellationSignal != null) {
841 cancellationSignal.setRemote(null);
842 }
843 if (unstableProvider != null) {
844 releaseUnstableProvider(unstableProvider);
845 }
846 if (stableProvider != null) {
847 releaseProvider(stableProvider);
848 }
849 }
850 }
大概的意思就是先调用不稳定的提供器,如果获取内容失败,那么启动稳定的提供器,如果得到结果,执行wrap操作.那么我们继续跟踪稳定的提供器stableProvider.这里为Provider提供接口.那么Provider就应该有具体实现,由于这个是系统提供的组件,我们可以在Package包下找到MediaProvider.java.