Android cursor query && 访问MediaStore
MediaStore这个类是Android系统提供的一个多媒体数据库,android中多媒体信息都可以从这里提取。这个MediaStore包括了多媒体数据库的所有信息,包括音频,视频和图像,android把所有的多媒体数据库接口进行了封装,所有的数据库不用自己进行创建,直接使用ContentResolver去调用那些封装好的接口就可以进行数据库的操作了。
//获取ContentResolver实例
ContentResolver mResolver = ctx.getContentResolver();
//ContentResolver实例获得后,就可以进行各种增删改查的方法
查看android提供的多媒体表:内部数据库和外部数据库
/data/data/com.google.android.providers.media.module/databases/external.db
/data/data/com.google.android.providers.media.module/databases/internal.db
adb sqlite3命令
然后输入命令sqlite3加上这个数据库的名字就可以查询android的多媒体数据库了。.table命令可以列出所有多媒体数据库的表,.schema加上表名可以查询表中的所有列名。这里可以利用SQL语句来查看你想要的数据,记得最后一定要记住每条语句后面都加上分号。
源码MediaStore.java
/**
* Implement this to handle query requests from clients.
*
* @param uri The URI to query. This will be the full URI sent by the client;
* if the client is requesting a specific record, the URI will end in a record number
* that the implementation should parse and add to a WHERE or HAVING clause, specifying
* that _id value.
* @param projection The list of columns to put into the cursor. If
* {@code null} all columns are included.
* @param selection A selection criteria to apply when filtering rows.
* If {@code null} then all rows are included.
* @param selectionArgs You may include ?s in selection, which will be replaced by
* the values from selectionArgs, in order that they appear in the selection.
* The values will be bound as Strings.
* @param sortOrder How the rows in the cursor should be sorted.
* If {@code null} then the provider is free to define the sort order.
* @return a Cursor or {@code null}.
*/
public abstract @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
@Nullable String selection, @Nullable String[] selectionArgs,
@Nullable String sortOrder);
/**
* Implement this to handle requests to insert a new row.
*
* @param uri The content:// URI of the insertion request.
* @param values A set of column_name/value pairs to add to the database.
* @return The URI for the newly inserted item.
*/
public abstract @Nullable Uri insert(@NonNull Uri uri, @Nullable ContentValues values);
/**
* Implement this to handle requests to delete one or more rows.
*
* @param uri The full URI to query, including a row ID (if a specific
* record is requested).
* @param selection An optional restriction to apply to rows when deleting.
* @return The number of rows affected.
* @throws SQLException
*/
public abstract int delete(@NonNull Uri uri, @Nullable String selection,
@Nullable String[] selectionArgs);
/**
* Implement this to handle requests to update one or more rows.
*
* @param uri The URI to query. This can potentially have a record ID if
* this is an update request for a specific record.
* @param values A set of column_name/value pairs to update in the database.
* @param selection An optional filter to match rows to update.
* @return the number of rows affected.
*/
public abstract int update(@NonNull Uri uri, @Nullable ContentValues values,
@Nullable String selection, @Nullable String[] selectionArgs);
public final Cursor query (Uri uri, String[] projection,String selection,String[] selectionArgs, String sortOrder)
Uri:这个Uri代表要查询的数据库名称加上表的名称。这个Uri一般都直接从MediaStore里取得,
上面我们提到了Android提供内容的叫Provider,那么在Android中怎么区分各个Provider?有提供联系人的,有提供图片的等等。所以就需要有一个唯一的标识来标识这个Provider,Uri就是这个标识,android.provider.ContactsContract.Contacts.CONTENT_URI就是提供联系人的内容提供者
projection:代表要从表中选择的列,用一个String数组来表示。告诉Provider要返回的内容(列Column)
selection:相当于SQL语句中的where子句,就是代表你的查询条件。null表示不进行筛选
selectArgs:如果你的selection里有?这个符号时,这里可以以实际值代替这个问号。如果Selections这个没有?的话,那么这个String数组可以为null。
sortOrder:说明查询结果按什么来排序。相当于SQL语句中的Order by,升序 asc /降序 desc,null为默认排序
MediaStore常用的uri
MediaStore.Video.Media
MediaStore.Audio.Media
MediaStore.Images.Media
//MediaStore.Images.Media.EXTERNAL_CONTENT_URI
//MediaStore.Images.Media.INTERNAL_CONTENT_URI
MediaStore.Downloads.INTERNAL_CONTENT_URI
MediaStore.Downloads.EXTERNAL_CONTENT_URI
可移动存储: MediaStore.Downloads.getContentUri(String volumeName)
不过总有些文件比较特殊,用上面的方法查询不出来,或者说,某些媒体文件扫描不到,就没有添加进上述三个数据源中,导致查询不出来;这种情况下,可以尝试用MediaStore.Files。MediaStore.Files存储了所有应用中共享的文件,包括图片、文件、视频、音乐等多媒体文件,包括非多媒体文件。
//MediaStore.Files没有EXTERNAL_CONTENT_URI,所以只能用getContentUri()自行获取,得出的URI其实是Uri.parse("content://media/external/files")
MediaStore.Files.getContentUri(String volumeName)
MediaStore.Files.getContentUri("external")
//查找
例如我想要查询目录为“pic”的所有图片的ID和名称,就这样写:
Cursor cursor = this.getContentResolver().query(
//数据源,EXTERNAL_CONTENT_URI是外部存储数据源,相应的INTERNAL_CONTENT_URI是内部存储源
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
//查询ID和名称
new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.TITLE},
//条件为目录名
MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " = ?",
//目录名为pic
new String[]{"pic"},
//按ID倒序排列
MediaStore.Images.Media._ID+" DESC");
换作SQL语句大概是这样的:
SELECT _id,title FROM images WHERE bucket_display_name = "pic" ORDER BY _id DESC
//查找获取cursor,怎么获取该数据
Cursor cursor = this.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null,
null,
null,
null);
//图片路径所在列的索引
int indexPhotoPath = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
while (cursor.moveToNext()) {
//打印图片的路径
Log.i("uri:", cursor.getString(indexPhotoPath));
}
cursor.close();
ContentResolver resolver = ctx.getContentResolver();
//增加
ContentValues values = new ContentValues();
values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER,0);
resolver.insert(_uri, values);
//删除
resolver.delete(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,where, selectionArgs);
//查找
//更新
ContentValues values = new ContentValues();
values.put(MediaStore.Audio.Media.DATE_MODIFIED, sid);
resolver.update(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,values, where, selectionArgs);
相关参考:
https://blog.csdn.net/ruiqingzheng/article/details/50651495
https://www.jianshu.com/p/be92dde9598f
https://blog.csdn.net/ifmylove2011/article/details/51425921