android framework MediaScanner等sd卡u盘扫描流程简要跟踪分析

本文简要跟踪分析了Android系统中MediaScanner组件的工作流程,涉及MediaScanner.java、MediaScannerService.java、MediaProvider.java及MediaScannerReceiver.java等关键类,以及在C++层的实现android_media_MediaScanner.cpp。通过对这些组件的深入理解,可以了解到Android设备如何扫描并处理SD卡和U盘中的媒体文件。
摘要由CSDN通过智能技术生成
涉及到的几个类文件:
  1. MediaScanner.java
  2. MediaScannerService.java
  3. MediaProvider.java
  4. MediaScannerReceiver.java
  5. android_media_MediaScanner.cpp
当插入sd卡或者插入U盘时,系统会对其进行文件扫描(音乐,视频,图片等),以及音乐播放器中对音乐文件的扫描获取各种信息也是借助于这几个文件来实现扫描功能的。
下面就针对这几个类源码跟踪一下。
MediaScannerReceiver.java 该类是extends BroadCastReceiver,自定义广播类,接收开机广播ACTION_BOOT_COMPLETED以及ACTION_MEDIA_MOUNTED  ,ACTION_MEDIA_SCANNER_SCAN_FILE
   
   
   
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
final Uri uri = intent.getData();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
// Scan both internal and external storage
//外部存储以及内部存储都扫描
scan(context, MediaProvider.INTERNAL_VOLUME);
scan(context, MediaProvider.EXTERNAL_VOLUME);
 
} else {
if (uri.getScheme().equals("file")) {
// handle intents related to external storage
#################################注意这部分内容
String path = uri.getPath();
// mnt/sdcard/ /storage/usbdisk
String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
String legacyPath = Environment.getLegacyExternalStorageDirectory().getPath();
 
try {
//diff : getPath getAbsolutePath
// recomended use getCanonicalPath()
path = new File(path).getCanonicalPath();
} catch (IOException e) {
Log.e(TAG, "couldn't canonicalize " + path);
return;
}
if (path.startsWith(legacyPath)) {
path = externalStoragePath + path.substring(legacyPath.length());
}
############################################
//eg: action: android.intent.action.MEDIA_MOUNTED path: /storage/usbdisk
Log.d(TAG, "action: " + action + " path: " + path);
if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
// scan whenever any volume is mounted .Scan externalStorage
scan(context, MediaProvider.EXTERNAL_VOLUME);
} else if (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) &&
path != null && path.startsWith(externalStoragePath + "/")) {
//scan a single folder's files in externalStorage .
//扫描某个特定的文件目录
scanFile(context, path);
}
}
}
MediaScannerReceiver的广播是从MediaService发送过来的,接下来他会去调用scan方法扫描。
MediaScannerReceiver::scan()
   
   
   
private void scan(Context context, String volume) { //volume: internal 或者 external
Bundle args = new Bundle();
args.putString("volume", volume);
context.startService( //启动MediaScannerService
new Intent(context, MediaScannerService.class).putExtras(args));
}
因此,接下来我们进入MediaScannerService Service中, MediaScannerService extends Service implements Runnable 实现了Runnable接口,因此我们可以猜测后面的扫描在run方法中进行,否则会阻塞了主线程。
Service 从首次创建到启动需要经历: onCreate() ---- onStartCommand() ...  方法
MediaScannerService::onCreate()
   
   
   
@Override
public void onCreate()
{ #################
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
#################保持屏幕亮屏,当android.process.media进程在干活的时候,告诉cpu,你不能熄火
StorageManager storageManager = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值