AndroidJNI媒体文件全盘扫描方案.docx
- 文档编号:12368219
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:14
- 大小:183.45KB
AndroidJNI媒体文件全盘扫描方案.docx
《AndroidJNI媒体文件全盘扫描方案.docx》由会员分享,可在线阅读,更多相关《AndroidJNI媒体文件全盘扫描方案.docx(14页珍藏版)》请在冰豆网上搜索。
AndroidJNI媒体文件全盘扫描方案
A*********Inc.Confidential
AndroidJNI媒体文件全盘扫描方案
变更说明
序号
版本
变更原因
变更内容
变更人
变更日期
备注
1
V0.1
初稿
初稿
叶蕾
11/16/2016
2
V0.2
初稿
初稿
叶蕾
01/10/2017
3
V0.3
初稿
初稿
叶蕾
02/13/2017
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
目录
1前言4
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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")==0||strcasecmp(endStr,"3gpp")==0||
strcasecmp(endStr,"3g2")==0||strcasecmp(endStr,"3gpp2")==0||strcasecmp(endStr,"mpeg")==0||
strcasecmp(endStr,"mkv")==0||strcasecmp(endStr,"rmvb")==0||strcasecmp(endStr,"rm")==0||
strcasecmp(endStr,"mov")==0||strcasecmp(endStr,"flv")==0||strcasecmp(endStr,"f4v")==0||
strcasecmp(endStr,"avi")==0||strcasecmp(endStr,"vob")==0||strcasecmp(endStr,"ts")==0||
/*strcasecmp(endStr,"asf")==0||strcasecmp(endStr,"wmv")==0||*/strcasecmp(endStr,"m4v")==0||
strcasecmp(endStr,"m2v")==0||strcasecmp(endStr,"mpe")==0||strcasecmp(endStr,"mpg")==0||
strcasecmp(endStr,"ogm")==0||strcasecmp(endStr,"ram")==0||strcasecmp(endStr,"divx")==0||
strcasecmp(endStr,"asx")==0||strcasecmp(endStr,"wm")==0){
returnTYPE_VIDEO;
}elseif(strcasecmp(endStr,"mp3")==0||strcasecmp(endStr,"wma")==0||strcasecmp(endStr,"ape")==0||
strcasecmp(endStr,"flac")==0||strcasecmp(endStr,"m4r")==0||strcasecmp(endStr,"wav")==0||
strcasecmp(endStr,"mp1")==0||strcasecmp(endStr,"mp2")==0||strcasecmp(endStr,"aac")==0||
/*strcasecmp(endStr,"ac3")==0||*/strcasecmp(endStr,"amr")==0||strcasecmp(endStr,"m4a")==0||
strcasecmp(endStr,"mid")==0||strcasecmp(endStr,"midi")==0||strcasecmp(endStr,"oga")==0||
strcasecmp(endStr,"ra")==0||strcasecmp(endStr,"mka")==0||strcasecmp(endStr,"dts")==0||
strcasecmp(endStr,"aiff")==0||strcasecmp(endStr,"m4a")==0||strcasecmp(endStr,"mmf")==0){
returnTYPE_AUDIO;
}elseif(strcasecmp(endStr,"png")==0||strcasecmp(endStr,"jpg")==0||strcasecmp(endStr,"bmp")==0||
strcasecmp(endStr,"jpeg")==0||strcasecmp(endStr,"gif")==0||strcasecmp(endStr,"ico")==0||
strcasecmp(endStr,"tag")==0){
returnTYPE_IMAGE;
}elseif(strcasecmp(endStr,"swap")==0){
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,'\0',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){
LOGI("RemovefilePath:
%s\n",filePath);
}else{
LOGE("FailedtoremovefilePath:
%s\n",filePath);
}
}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);
(*env)->DeleteLocalRef(env,filePathString);
(*env)->DeleteLocalRef(env,fileNameString);
(*env)->DeleteLocalRef(env,fileNamePYString);
(*env)->DeleteLocalRef(env,jniMediaBean);
}
}
3.4.5递归扫描的函数
intreadFileList(JNIEnv*env,jobjectthiz,constchar*basePath)
{
DIR*dir;
structdirent*ptr;
if(strcmp(basePath,"/mnt/sdcard/MediaCollect")==0||
strcmp(basePath,"/mnt/sdcard/autonavi")==0||
strcmp(basePath,"/mnt/sdcard/amapauto")==0||
strcmp(basePath,"/mnt/sdcard/iflytek")==0||
strcmp(basePath,"/mnt/sdcard/sogou")==0){
return0;
}
if((dir=opendir(basePath))==NULL){
LOGE("Opendirerror:
%s\n",basePath);
return-1;
}
while((ptr=readdir(dir))!
=NULL){
if(strcmp(ptr->d_name,".")==0||strcmp(ptr->d_name,"..")==0||
(strchr(ptr->d_name,'.')!
=NULL&&strcmp(ptr->d_name,strchr(ptr->d_name,'.'))==0)){///currentdirORparrentdir
continue;
}elseif(ptr->d_type==8){//file
//filePath
charfilePath[1000];
memset(filePath,'\0',sizeof(filePath));
strcpy(filePath,basePath);
strcat(filePath,"/");
strcat(filePath,ptr->d_name);
addToDb(env,thiz,filePath,ptr->d_name,0);
}elseif(ptr->d_type==10){//linkfile
LOGI("linkName:
%s/%s\n",basePath,ptr->d_name);
}elseif(ptr->d_type==4){//dir
chardirFilePath[1000];
memset(dirFilePath,'\0',sizeof(dirFilePath));
strcpy(dirFilePath,basePath);
strcat(dirFilePath,"/");
strcat(dirFilePath,ptr->d_name);
readFileList(env,thiz,dirFilePath);
}elseif(ptr->d_type==0){//unknown
charfileWhole[1000];
memset(fileWhole,'\0',sizeof(fileWhole));
strcpy(fileWhole,basePath);
strcat(fileWhole,"/");
strcat(fileWhole,ptr->d_name);
structstatstatbuf;
if(stat(fileWhole,&statbuf)==-1){//unknowerror
LOGI("unknowFile:
%s/%s\n",basePath,ptr->d_name);
continue;
}
if(S_ISREG(statbuf.st_mode)){//file
addToDb(env,thiz,fileWhole,ptr->d_name,0);
}elseif(S_ISDIR(statbuf.st_mode)){//dir
readFileList(env,thiz,fileWhole);
}
}else{
LOGE("Otherd_type:
%d-->linkName:
%s/%s\n",ptr->d_type,basePath,ptr->d_name);
}
}
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,"
scanJniClass=(*env)->FindClass(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);
charfileNamePY[1024];
memset(fileNamePY,'\0',sizeof(fileNamePY));
hztpy(filename,fileNamePY,1);
charfileNamePYSecond[1024];
memset(fileNamePYSecond,'\0',sizeof(fileNamePYSecond));
hztpy(filename,fileNamePYSecond,0);
strcat(fileNamePY,";;");
strcat(fileNamePY,fileNamePYSecond);
(*env)->ReleaseStringUTFChars(env,jfileName,filename);
return(*env)->NewStringUTF(env,fileNamePY);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AndroidJNI 媒体文件 全盘 扫描 方案