MediaScan流程(二)MediaScannerService

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/5.1.1_r1/com/android/providers/media/MediaScannerService.java#MediaScannerService

onCreate()

public void onCreate()
    {
        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        StorageManager storageManager = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
        mExternalStoragePaths = storageManager.getVolumePaths();

        // Start up the thread running the service.  Note that we create a
        // separate thread because the service normally runs in the process's
        // main thread, which we don't want to block.
        Thread thr = new Thread(null, this, "MediaScannerService");
        thr.start();
    }

获取 mExternalStoragePaths,  此即为扫描外部设备时的扫描路径

启动新线程处理耗时操作.(创建 ServiceHandler实例)

onStartCommand()

public int onStartCommand(Intent intent, int flags, int startId)
    {
        while (mServiceHandler == null) {
            synchronized (this) {
                try {
                    wait(100);
                } catch (InterruptedException e) {
                }
            }
        }

        if (intent == null) {
            Log.e(TAG, "Intent is null in onStartCommand: ",
                new NullPointerException());
            return Service.START_NOT_STICKY;
        }

        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent.getExtras();
        mServiceHandler.sendMessage(msg);

        // Try again later if we are killed before we can finish scanning.
        return Service.START_REDELIVER_INTENT;
    }

获取startIntent包含的数据,并发送广播

ServiceHandler--handleMessage()

Bundle arguments = (Bundle) msg.obj;
String filePath = arguments.getString("filepath");

try {
	if (filePath != null) {
		IBinder binder = arguments.getIBinder("listener");
		IMediaScannerListener listener = 
				(binder == null ? null : IMediaScannerListener.Stub.asInterface(binder));
		Uri uri = null;
		try {
			uri = scanFile(filePath, arguments.getString("mimetype"));
		} catch (Exception e) {
			Log.e(TAG, "Exception scanning file", e);
		}
		if (listener != null) {
			listener.scanCompleted(filePath, uri);
		}
	} else {
若 filePath不为空,即需要扫描的是单个文件,调用scanFile()
private Uri scanFile(String path, String mimeType) {
	String volumeName = MediaProvider.EXTERNAL_VOLUME;
	openDatabase(volumeName);
	MediaScanner scanner = createMediaScanner();
	try {
		// make sure the file path is in canonical form
		String canonicalPath = new File(path).getCanonicalPath();
		return scanner.scanSingleFile(canonicalPath, volumeName, mimeType);
	} catch (Exception e) {
		Log.e(TAG, "bad path " + path + " in scanFile()", e);
		return null;
	}
}

创建 scanner,调用 scanner.scanSingleFile()

String volume = arguments.getString("volume");
String[] directories = null;

if (MediaProvider.INTERNAL_VOLUME.equals(volume)) {
	// scan internal media storage
	directories = new String[] {
			Environment.getRootDirectory() + "/media",
			Environment.getOemDirectory() + "/media",
	};
}
else if (MediaProvider.EXTERNAL_VOLUME.equals(volume)) {
	// scan external storage volumes
	directories = mExternalStoragePaths;
}

if (directories != null) {
	if (false) Log.d(TAG, "start scanning volume " + volume + ": "
			+ Arrays.toString(directories));
	scan(directories, volume);
	if (false) Log.d(TAG, "done scanning volume " + volume);
}
若需要扫描的是设备,内部设备扫描 
Environment.getRootDirectory() + "/media",
Environment.getOemDirectory() + "/media",

外部设备扫描 onCreate()中获取的 mExternalStoragePaths

调用scan() 

private void scan(String[] directories, String volumeName) {
	Uri uri = Uri.parse("file://" + directories[0]);
	// don't sleep while scanning
	mWakeLock.acquire();

	try {
		ContentValues values = new ContentValues();
		values.put(MediaStore.MEDIA_SCANNER_VOLUME, volumeName);
		Uri scanUri = getContentResolver().insert(MediaStore.getMediaScannerUri(), values);

		sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_STARTED, uri));

		try {
			if (volumeName.equals(MediaProvider.EXTERNAL_VOLUME)) {
				openDatabase(volumeName);
			}

			MediaScanner scanner = createMediaScanner();
			scanner.scanDirectories(directories, volumeName);
		} catch (Exception e) {
			Log.e(TAG, "exception in MediaScanner.scan()", e);
		}

		getContentResolver().delete(scanUri, null, null);

	} finally {
		sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_FINISHED, uri));
		mWakeLock.release();
	}
}

调用scanner.scanDirectories();

 

 

转载于:https://my.oschina.net/u/2287911/blog/735788

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值