AndroidJNI媒体文件全盘扫描方案Word文档下载推荐.docx
《AndroidJNI媒体文件全盘扫描方案Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《AndroidJNI媒体文件全盘扫描方案Word文档下载推荐.docx(14页珍藏版)》请在冰点文库上搜索。
1.1文档目的4
2开发环境说明4
2.1扫描入口流程4
2.2ProviderHelp4
2.3JSBD_JL_FileManager4
2.4Launcher图片5
3问题总结5
3.1FileServer框架调整说明5
3.1.1优化Intent事件的监听5
媒体文件扫描方案
1前言
该文档为开发人员阅读。
1.1文档目的
文档编写目的:
为项目参与者阅读。
2开发环境说明
说明如下:
1)Android系统:
AndroidKK以上版本。
2)开发环境:
JDK1.6以上版本,NDK开发环境。
3)开发工具:
Eclipse,AndroidDeveloptools
2.1扫描入口流程
大致流程如下:
●AndroidStorageMounted的Intent事件的监听者onReceive:
接收Storage挂载的事件。
●启动FileService:
该服务用来做文件扫描操作,和intent消息外发工作。
●FileServer会开启ScanRootPathThread线程去做文件的扫描。
●在文件扫描的线程中,会去调用ScanJniJNI类中的方法scanRootPath来对某个磁盘进行扫描。
●JNI回调函数ScanJNI#insertToDb:
用来回调扫描到的媒体数据,并添加到数据库中。
本文档主要介绍的是上面步骤中的第4部。
也是媒体文件扫描的核心部分。
2.2核心类的说明
只介绍该文档中提到的核心类:
●ScanJni.java类:
提供扫描的入口和Java回调的接口
●scan_jni.c文件:
实现全盘的递归扫描工作
●com_file_server_scan_ScanJni.h头文件:
编译所需的头文件,用来申明JNI的函数。
●Android.mk文件:
NDK的编译文件。
2.3核心思路和设计特点
核心的思路和设计特点如下:
1)针对文件的后缀名进行扫描,例如**.mp3文件
2)定义了5中文件类型
●普通文件:
TYPE_FILE
●音乐文件:
TYPE_AUDIO
●视频文件:
TYPE_VIDEO
●图片文件:
TYPE_IMAGE
●中间临时文件:
TYPE_SWAP
3)针对各个类型的文件进行分别处理。
4)JNIC采用递归操作,通过判断文件名的后缀来判断文件类型。
5)递归过程中,提供指定文件夹不扫描的功能。
6)针对特殊文件系统的特殊文件类型的兼容性做过大量的测试工作。
保证支持99%的存储介质的全盘扫描。
7)通过Java反射回到机制,将扫描到的媒体文件交给Java上层来处理。
3核心代码
3.1Android.mk文件
说明:
hz2py.c文件为汉子转拼音的文件,此部分的设计不在这个文档单中。
涉及到另外一项技术,请阅读其他文档。
3.2com_file_server_scan_ScanJni.h文件
这个部分的代码,不多做解释,只是用来做函数声明。
stringFromJni:
测试函数。
未使用。
scanRootPath:
扫描的入口
getPY:
中文转拼音的入口。
3.3ScanJni.java文件
3.4scan_jni.c文件
3.4.1头文件引用
#include<
string.h>
jni.h>
com_file_server_scan_ScanJni.h>
dirent.h>
stdio.h>
stdlib.h>
unistd.h>
android/log.h>
sys/stat.h>
time.h>
#include"
py.h"
3.4.2声明和定义
#define_LOG_TAG"
NDK_ScanJNI"
intTYPE_FILE=2;
intTYPE_AUDIO=3;
intTYPE_VIDEO=4;
intTYPE_IMAGE=5;
intTYPE_SWAP=6;
#defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,_LOG_TAG,__VA_ARGS__)
#defineLOGE(...)__android_log_print(ANDROID_LOG_ERROR,_LOG_TAG,__VA_ARGS__)
jclassmediaBeanClass;
jmethodIDmediaBeanID;
jclassscanJniClass;
jmethodIDinsertToDbID;
3.4.3判断媒体函数
intjudgeMediaType(char*fileName){
char*endStr=fileName;
char*tmp;
tmp=strrchr(endStr,'
.'
);
if(tmp!
=NULL){
endStr=tmp+1;
}
if(strcasecmp(endStr,"
mp4"
)==0||strcasecmp(endStr,"
3gp"
3gpp"
)==0||
strcasecmp(endStr,"
3g2"
3gpp2"
mpeg"
mkv"
rmvb"
rm"
mov"
flv"
f4v"
avi"
vob"
ts"
/*strcasecmp(endStr,"
asf"
wmv"
)==0||*/strcasecmp(endStr,"
m4v"
m2v"
mpe"
mpg"
ogm"
ram"
divx"
asx"
wm"
)==0){
returnTYPE_VIDEO;
}elseif(strcasecmp(endStr,"
mp3"
wma"
ape"
flac"
m4r"
wav"
mp1"
mp2"
aac"
ac3"
amr"
m4a"
mid"
midi"
oga"
ra"
mka"
dts"
aiff"
mmf"
returnTYPE_AUDIO;
png"
jpg"
bmp"
jpeg"
gif"
ico"
tag"
returnTYPE_IMAGE;
swap"
returnTYPE_SWAP;
returnTYPE_FILE;
}
3.4.4处理扫描的结果的函数
voidaddToDb(JNIEnv*env,jobjectthiz,char*filePath,char*fileName,longfileSize){
intfileType=judgeMediaType(fileName);
charfileNamePY[1024];
memset(fileNamePY,'
\0'
sizeof(fileNamePY));
hztpy(fileName,fileNamePY,1);
charfileNamePYSecond[1024];
memset(fileNamePYSecond,'
sizeof(fileNamePYSecond));
hztpy(fileName,fileNamePYSecond,0);
strcat(fileNamePY,"
;
"
strcat(fileNamePY,fileNamePYSecond);
LOGI("
fileName:
%s&
&
fileNamePY:
%s\n"
fileName,fileNamePY);
if(fileType==TYPE_SWAP){
if(remove(filePath)==0){
RemovefilePath:
filePath);
}else{
LOGE("
FailedtoremovefilePath:
}elseif(fileType!
=TYPE_FILE){
jstringfilePathString=(*env)->
NewStringUTF(env,filePath);
jstringfileNameString=(*env)->
NewStringUTF(env,fileName);
jstringfileNamePYString=(*env)->
NewStringUTF(env,fileNamePY);
jintjfileType=(int)fileType;
jlongjfileSize=(long)fileSize;
jobjectjniMediaBean=(*env)->
NewObject(env,mediaBeanClass,mediaBeanID,
filePathString,fileNameString,fileNamePYString,jfileSize,jfileType);
(*env)->
CallVoidMethod(env,thiz,insertToDbID,jniMediaBean);
DeleteLocalRef(env,filePathString);
DeleteLocalRef(env,fileNameString);
DeleteLocalRef(env,fileNamePYString);
DeleteLocalRef(env,jniMediaBean);
3.4.5递归扫描的函数
intreadFileList(JNIEnv*env,jobjectthiz,constchar*basePath)
{
DIR*dir;
structdirent*ptr;
if(strcmp(basePath,"
/mnt/sdcard/MediaCollect"
strcmp(basePath,"
/mnt/sdcard/autonavi"
/mnt/sdcard/amapauto"
/mnt/sdcard/iflytek"
/mnt/sdcard/sogou"
return0;
if((dir=opendir(basePath))==NULL){
Opendirerror:
basePath);
return-1;
while((ptr=readdir(dir))!
if(strcmp(ptr->
d_name,"
."
)==0||strcmp(ptr->
.."
)==0||
(strchr(ptr->
d_name,'
)!
=NULL&
strcmp(ptr->
d_name,strchr(ptr->
))==0)){///currentdirORparrentdir
continue;
}elseif(ptr->
d_type==8){//file
//filePath
charfilePath[1000];
memset(filePath,'
sizeof(filePath));
strcpy(filePath,basePath);
strcat(filePath,"
/"
strcat(filePath,ptr->
d_name);
addToDb(env,thiz,filePath,ptr->
d_name,0);
d_type==10){//linkfile
linkName:
%s/%s\n"
basePath,ptr->
d_type==4){//dir
chardirFilePath[1000];
memset(dirFilePath,'
sizeof(dirFilePath));
strcpy(dirFilePath,basePath);
strcat(dirFilePath,"
strcat(dirFilePath,ptr->
readFileList(env,thiz,dirFilePath);
d_type==0){//unknown
charfileWhole[1000];
memset(fileWhole,'
sizeof(fileWhole));
strcpy(fileWhole,basePath);
strcat(fileWhole,"
strcat(fileWhole,ptr->
structstatstatbuf;
if(stat(fileWhole,&
statbuf)==-1){//unknowerror
LOGI("
unknowFile:
continue;
}
if(S_ISREG(statbuf.st_mode)){//file
addToDb(env,thiz,fileWhole,ptr->
}elseif(S_ISDIR(statbuf.st_mode)){//dir
readFileList(env,thiz,fileWhole);
Otherd_type:
%d-->
linkName:
ptr->
d_type,basePath,ptr->
closedir(dir);
return1;
3.4.6stringFromJni函数
jstringJava_com_file_server_ScanJni_stringFromJni
(JNIEnv*env,jobjectthiz)
return(*env)->
NewStringUTF(env,"
Hellofromscanjni.so!
3.4.7扫描入口函数scanRootPath
voidJava_com_file_server_scan_ScanJni_scanRootPath
(JNIEnv*env,jobjectthiz,jstringrootPath)
mediaBeanClass=(*env)->
FindClass(env,"
com/jsbd/file/provider/bean/MediaBean"
mediaBeanID=(*env)->
GetMethodID(env,mediaBeanClass,"
<
init>
"
(Ljava/lang/String;
Ljava/lang/String;
JI)V"
scanJniClass=(*env)->
com/file/server/scan/ScanJni"
insertToDbID=(*env)->
GetMethodID(env,scanJniClass,"
insertToDb"
(Lcom/jsbd/file/provider/bean/MediaBean;
)V"
constchar*basePath=(*env)->
GetStringUTFChars(env,rootPath,0);
readFileList(env,thiz,basePath);
(*env)->
ReleaseStringUTFChars(env,rootPath,basePath);
3.4.8获取汉子拼音的函数getPY
jstringJava_com_file_server_scan_ScanJni_getPY
(JNIEnv*env,jobjectthiz,jstringjfileName)
constchar*filename=(*env)->
GetStringUTFChars(env,jfileName,0);
hztpy(filename,fileNamePY,1);
hztpy(filename,fileNamePYSecond,0);
ReleaseStringUTFChars(env,jfileName,filename);