我是靠谱客的博主 热情枕头,最近开发中收集的这篇文章主要介绍java setcontenprovider,7.6.2 ContentProvider的 openTypedAssetFile函数分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

**ContentProvider.java::openTypedAssetFile**

~~~

public AssetFileDescriptor openTypedAssetFile(Uriuri, String mimeTypeFilter,

Bundle opts) throws FileNotFoundException {

//本例满足下面的if条件

if("*/*".equals(mimeTypeFilter))

return openAssetFile(uri, "r");//此函数的代码见下文

StringbaseType = getType(uri);

if(baseType != null &&

ClipDescription.compareMimeTypes(baseType, mimeTypeFilter)) {

return openAssetFile(uri, "r");

}

throw newFileNotFoundException("Can't open " +

uri + " as type " + mimeTypeFilter);

}

~~~

**ContentProvider.java::openAssetFile**

~~~

public AssetFileDescriptor openAssetFile(Uri uri,String mode)

throws FileNotFoundException {

//openFile由子类实现。这里还以MediaProvider为例

ParcelFileDescriptor fd = openFile(uri, mode);

//根据openFile返回的fd得到一个AssetFileDescriptor对象

returnfd != null ? new AssetFileDescriptor(fd, 0, -1) : null;

}

~~~

下面分析MediaProvider实现的openFile函数。

1. MediaProvideropenFile分析

**MediaProvider.java::openFile**

~~~

public ParcelFileDescriptor openFile(Uri uri,String mode)

throws FileNotFoundException {

ParcelFileDescriptor pfd = null;

//假设URI符合下面的if条件,即客户端想读取的是某音乐文件所属专辑(Album)的信息

if(URI_MATCHER.match(uri) == AUDIO_ALBUMART_FILE_ID) {

DatabaseHelper database = getDatabaseForUri(uri);

......

SQLiteDatabase db = database.getReadableDatabase();

......

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

//得到客户端指定的代表该音乐文件的_id值

intsongid = Integer.parseInt(uri.getPathSegments().get(3));

qb.setTables("audio_meta");

qb.appendWhere("_id=" + songid);

Cursor c = qb.query(db,

new String [] {

MediaStore.Audio.Media.DATA,

MediaStore.Audio.Media.ALBUM_ID },

null, null, null, null, null);

if(c.moveToFirst()) {

String audiopath = c.getString(0);

//获取该音乐所属的album_id值

int albumid = c.getInt(1);

//注意,下面函数中调用的ALBUMART_URI将指向album_art表

Uri newUri = ContentUris.withAppendedId(ALBUMART_URI, albumid);

try {

//调用ContentProvider实现的openFileHelper函数。注意,pfd的

//类型是ParcelFileDescriptor

pfd = openFileHelper(newUri, mode);

} ......

}

c.close();

return pfd;

}

......

}

~~~

在以上代码中,MediaProvider将首先通过客户端指定的音乐文件的_id去查询它的专辑信息。此处给读者一个示例,如图7-8所示。

:-: ![](https://img-blog.csdn.net/20150803131007500?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

图7-8 audio_meta内容展示

图7-8中设置的SQL语句是select _id,album_id,_data from audio_meta,得到的结果集包含:第一列音乐文件的_id值,第二列返回音乐文件所属专辑的album_id值,第三列返回对应歌曲的文件存储路径。

以上代码在调用openFileHelper函数前构造了一个新的URI变量,根据代码中的注释可知,它将查询album_art表,不妨再看一个示例,如图7-9所示。

:-: ![](https://img-blog.csdn.net/20150803131023705?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

图7-9 album_art内容展示

在图7-9中,结果集的第一列为专辑艺术家的缩略图文件存储路径,第二列为专辑艺术家album_id值。所以,要打开的文件就是对应album_id的缩略图。再来看openFileHelper的代码。

2. ContentProvideropenFileHelper函数分析

**ContentProvider.java::openFileHelper**

~~~

protected final ParcelFileDescriptoropenFileHelper(Uri uri,

String mode) throws FileNotFoundException {

//获取缩略图的文件路径

Cursor c =query(uri, new String[]{"_data"}, null, null, null);

int count= (c != null) ? c.getCount() : 0;

if (count!= 1) {

......//一个album_id只能对应一个缩略图文件

}

c.moveToFirst();

int i =c.getColumnIndex("_data");

Stringpath = (i >= 0 ? c.getString(i) : null);

c.close();

if (path == null)

throw new FileNotFoundException("Column _data not found.");

intmodeBits = ContentResolver.modeToMode(uri, mode);

//创建ParcelFileDescriptor对象,内部会首先打开一个文件以得到

//一个FileDescriptor对象,然后再创建一个ParcelFileDescriptor对象,其实

//就是设置ParcelFileDescriptor中成员变量mFileDescriptor的值

returnParcelFileDescriptor.open(new File(path), modeBits);

}

~~~

至此,服务端已经打开指定文件了。那么,这个服务端的文件描述符是如何传递到客户端的呢?我们单起一节来回答这个问题。

最后

以上就是热情枕头为你收集整理的java setcontenprovider,7.6.2 ContentProvider的 openTypedAssetFile函数分析的全部内容,希望文章能够帮你解决java setcontenprovider,7.6.2 ContentProvider的 openTypedAssetFile函数分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部