Android Media Scanner Mechanism Analyze

 

Architecture

Android Media Scanner Mechanism Analyze_第1张图片

Figure2-1

 

AsFigure 2-1. MediaScannerReciver start up at anytime where receiveintent ACTION_BOOT_COMPLETED, ACTION_MEDIA_MOUNTED orACTION_MEDIA_SCANNER_SCAN_FILE. Cause on that spend long time to process the media metadata, so that MediaScannerReceiver will call upMediaScannerService.

MediaScannerServiceinvoke a public class which named MediaScanner to do the scan work,MediaScanner handle the media database with a public class whichnamed MediaProvider

MediaScannerReciversupport two types of the folder:

    1.internalvolume, point to $(ANDROID_ROOT)/media.

    2.Externalvolume, point $(EXTERNAL_STORAGE).

ScannerAction

ACTION_BOOT_COMPLETED

publicstatic final String ACTION_BOOT_COMPLETED

BroadcastAction: This is broadcast once, afterthe system has finished booting. It can be used to performapplication-specific initialization, such as installing alarms. Youmust hold theRECEIVE_BOOT_COMPLETED permissionin order to receive this broadcast.

Thisis a protected intent that can only be sent by the system.

ConstantValue: "android.intent.action.BOOT_COMPLETED"

 

ACTION_MEDIA_MOUNTED

publicstatic final String ACTION_MEDIA_MOUNTED

BroadcastAction: External media is present and mounted at its mount point. Thepath to the mount point for the removed media is contained in theIntent.mData field. The Intent contains an extra with name"read-only" and Boolean value to indicate if the media wasmounted read only.

ConstantValue: "android.intent.action.MEDIA_MOUNTED"

 

ACTION_MEDIA_SCANNER_SCAN_FILE.

publicstatic final String ACTION_MEDIA_SCANNER_SCAN_FILE

BroadcastAction: Request the media scanner to scan a file and add it to themedia database. The path to the file is contained in the Intent.mDatafield.

ConstantValue: "android.intent.action.MEDIA_SCANNER_SCAN_FILE"

 

 

AndroidMedia Scanner Receiver

Wecan find the source file with pathanydroid/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java

 

publicclass MediaScannerReceiver extends BroadcastReceiver

{

@Override

publicvoid onReceive(Context context, Intent intent) {

......

if(action.equals(Intent.ACTION_BOOT_COMPLETED)) {

//scan internal storage

scan(context,MediaProvider.INTERNAL_VOLUME);

}else {

if(uri.getScheme().equals("file")) {

//handle intents related to external storage

Stringpath = uri.getPath();

if(action.equals(Intent.ACTION_MEDIA_MOUNTED) &&

externalStoragePath.equals(path)){

scan(context,MediaProvider.EXTERNAL_VOLUME);

}else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&

path!= null && path.startsWith(externalStoragePath + "/")){

scanFile(context,path);

}

}

}

}

privatevoid scan(Context context, String volume) {

Bundleargs = new Bundle();

args.putString("volume",volume);

context.startService(

newIntent(context, MediaScannerService.class).putExtras(args));

}

privatevoid scanFile(Context context, String path) {

Bundleargs = new Bundle();

args.putString("filepath",path);

context.startService(

newIntent(context, MediaScannerService.class).putExtras(args));

}

}

Android Media Scanner Mechanism Analyze_第2张图片

Figure4-1

Asthe source codes, and Figure 4-1, there are two different mediadatabase in the system, oneis the internal storage , the other is the external storage. Finally,they call the method startService() to start the MediaScannerService.

 

AndroidMedia Scanner Service

Wecan find the source file with path/android/packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerService.java.

 

publicvoid onCreate()

{

......

Threadthr = new Thread(null, this, "MediaScannerService");

thr.start();

}

 

publicint onStartCommand(Intent intent, int flags, int startId)

{

......

Messagemsg = mServiceHandler.obtainMessage();

......

mServiceHandler.sendMessage(msg); returnService.START_REDELIVER_INTENT;

}

 

publicvoid run()

{

......

mServiceHandler= new ServiceHandler();

......

}

 

privatefinal class ServiceHandler extends Handler

{

......

@Override

publicvoid handleMessage(Message msg)

{

......

if(filePath != null) {

......

Uriuri = scanFile(filePath, arguments.getString("mimetype"));

......

}

else{

......

scan(directories,volume);

......

}

}

}

 

privatevoid scan(String[] directories, String volumeName) {

......

MediaScannerscanner = createMediaScanner();

scanner.scanDirectories(directories,volumeName);

......

}

 

privateUri scanFile(String path, String mimeType) {

......

MediaScannerscanner = createMediaScanner();

returnscanner.scanSingleFile(path, volumeName, mimeType);

}

 

 

Android Media Scanner Mechanism Analyze_第3张图片

Figure5-1

 

Androidapplication maybe block with invoking service, generic create a thread to run at the backend. First, media service call onCreate() tostart the service if it is not exist, then create a thread and runthread.start() to call the runnable method which has implemented withthe run(). In the run(), invoke a internal class named ServiceHandlerto scan file. In the method scan() and scanFile(), they all invoke apublic class named MediaScanner whom has method namedcreateMediaScanner() to process metadata and media dabase.

 

AndroidMedia Scanner

Wecan find the relate files with pathandroid/frameworks/base/media/java/android/media,

 

Android Media Scanner Mechanism Analyze_第4张图片

 

Figure6-1

 

javacodes

file://android/frameworks/base/media/java/android/media/MediaScanner.java

publicvoid scanDirectories(String[] directories, String volumeName) {

......

for(int i = 0; i < directories.length; i++) {

processDirectory(directories[i],MediaFile.sFileExtensions, mClient);

}

......

}

}

 

publicvoid scanFile(String path, long lastModified, long fileSize) {

//This is the callback funtion from native codes.

//Log.v(TAG, "scanFile: "+path);

doScanFile(path,null, lastModified, fileSize, false);

}

publicvoid scanFile(String path, String mimeType, long lastModified, longfileSize) {

doScanFile(path,mimeType, lastModified, fileSize, false);

}

 

publicUri doScanFile(String path, String mimeType, long lastModified, longfileSize, boolean scanAlways) {

......

if(isMetadataSupported(mFileType) ) {

processFile(path,mimeType, this);

}else if (MediaFile.isImageFileType(mFileType)) {

//we used to compute the width and height but it's not worth it

}

result= endFile(entry, ringtones, notifications, alarms, music, podcasts);

......

}

 

privateUri endFile(FileCacheEntry entry, boolean ringtones, booleannotifications,

boolean alarms,boolean music, boolean podcasts)

throwsRemoteException {

 

......

mMediaProvider.insert(...)// mMediaProvider.update(...)

......

}

 

privatenative void processDirectory(String path, String extensions,MediaScannerClient client);

privatenative void processFile(String path, String mimeType,MediaScannerClient client);

 

 

 

c++codes

file://android/frameworks/base/media/jni/android_media_MediaScanner.cpp

staticvoid

android_media_MediaScanner_processDirectory(JNIEnv*env, jobject thiz, jstring path, jstring extensions, jobjectclient)

{

MediaScanner *mp =(MediaScanner *)env->GetIntField(thiz, fields.context);

......

MyMediaScannerClientmyClient(env, client);

mp->processDirectory(pathStr,extensionsStr, myClient, ExceptionCheck, env);

......

}

 

staticvoid

android_media_MediaScanner_processFile(JNIEnv*env, jobject thiz, jstring path, jstring mimeType, jobject client)

{

MediaScanner *mp =(MediaScanner *)env->GetIntField(thiz, fields.context); ......

MyMediaScannerClientmyClient(env, client);

mp->processFile(pathStr,mimeTypeStr, myClient);

......

}

 

file://android/external/opencore/android/mediascanner.cpp

status_tMediaScanner::processDirectory(const char *path, const char*extensions,

MediaScannerClient&client, ExceptionCheck exceptionCheck, void* exceptionEnv)

{

......

result= doProcessDirectory(pathBuffer, pathRemaining, extensions, client,exceptionCheck, exceptionEnv);

......

}

 

status_tMediaScanner::doProcessDirectory(char *path, int pathRemaining, constchar* extensions,

MediaScannerClient&client, ExceptionCheck exceptionCheck, void* exceptionEnv)

{

......

client.scanFile(path,statbuf.st_mtime, statbuf.st_size);

......

}

 

status_tMediaScanner::processFile(const char *path, const char* mimeType,MediaScannerClient& client)

{

status_t result =PVMFSuccess;

interror = 0;

InitializeForThread();

OSCL_TRY(error,

client.setLocale(mLocale);

client.beginFile();

//LOGD("processFile%s mimeType: %s/n", path, mimeType);

const char* extension =strrchr(path, '.');

if (extension &&

(strcasecmp(extension,".mp3") == 0 || strcasecmp(extension, ".aac") ==0)) {

// Both mp3 and aacfiles use ID3 tags to hold metadata

result =parseID3Tag(path, client);

} else if (extension &&

(strcasecmp(extension,".mp4") == 0 || strcasecmp(extension, ".m4a") ==0 ||

strcasecmp(extension,".3gp") == 0 || strcasecmp(extension, ".3gpp") ==0 ||

strcasecmp(extension,".3g2") == 0 || strcasecmp(extension, ".m4b") ==0 ||

strcasecmp(extension,".3gpp2") == 0)) {

result =parseMP4(path, client);

} else if (extension &&strcasecmp(extension, ".ogg") == 0) {

result =parseOgg(path, client);

} else if (extension &&

(strcasecmp(extension,".mid") == 0 || strcasecmp(extension, ".smf") ==0 ||

strcasecmp(extension,".imy") == 0)) {

result =parseMidi(path, client);

} else if (extension &&

(strcasecmp(extension,".wma") == 0 || strcasecmp(extension, ".wmv") ==0 ||

strcasecmp(extension,".asf") == 0 || strcasecmp(extension, ".amr") ==0 ||

strcasecmp(extension,".wav") == 0 || strcasecmp(extension, ".awb") ==0)) {

result =parseASF(path, client);

} else {

result =PVMFFailure;

}

client.endFile();

);

OSCL_FIRST_CATCH_ANY(error,LOGV("OSCL_LEAVE happened in processFile Exit withfailure");return PVMFFailure);

return result;

}

 

 

AsFigure 6-1, If scanDirectory() has called by MediaScannerService, itwill invoke c++ llibrary libmedia_jni method processDiretorys() byJNI mechanism, then processDiretorys() invoke JAVA classMyMediaScannerClient by JNI, Finaly, endFile() use to insert orupdate the database.

 

 

你可能感兴趣的:(android,String,File,Path,extension,notifications)