android中媒体扫描服务mediaScannerService

背景:
1、项目中遇到一个问题,在Android机顶盒中插入大数据移动硬盘后,按待机键,盒子待机了,但是却唤醒不了了,而且此时盒子串口是可以输入的。
2、分析后大概定位到时媒体扫描导致的问题,起初是这样想的,关掉这个服务?或者加快扫描的速度?
3、跟了代码后(packages\providers\MediaProvider\),结合现象,
(a)确实是因为媒体扫描的原因,但是会唤醒不了,那是因为扫描的时候,持有了一个PowerManager.WakeLock


    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();
        }
    }

(b)只有等到扫描结束,才会释放锁,才能真正待机(所以现象是串口可以输入,说明不是真的待下去了,这个可以手动试试这种现象,往/sys/power/wake_lock中写一个锁,不释放就可以试验了)。只有真的待机了,才能唤醒。

所以这个问题最后是干掉这个锁来解决问题的。(会不会造成数据库有影响,我还没试过=。=)

扯远了,在这个过程中,跟了下mediaScannerService的一些东西,想记录下。

标题 ##服务的启动

源码在packages\providers\MediaProvider\,查看AndroidManifest.xml,可以看到,注册了这些广播。


        <receiver android:name="MediaScannerReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_MOUNTED" />
                <data android:scheme="file" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
                <data android:scheme="file" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_SCANNER_SCAN_FILE" />
                <data android:scheme="file" />
            </intent-filter>
        </receiver>

MediaScannerReceiver很简单,除了MEDIA_SCANNER_SCAN_FILE外,在mount,unmount,boot这些情况下,都会去执行scan或者scanFile函数。从下面的代码可以看到,主要参数是传入了要扫描的路径,主要功能是启动了MediaScannerService。

    private void scan(Context context, String volume) {
        Bundle args = new Bundle();
        args.putString("volume", volume);
        context.startService(
                new Intent(context, MediaScannerService.class).putExtras(args));
    }    

    private void scanFile(Context context, String path) {
        Bundle args = new Bundle();
        args.putString("filepath", path);
        context.startService(
                new Intent(context, MediaScannerService.class).putExtras(args));
    }   

先睡觉,未完待续

你可能感兴趣的:(android,硬盘,媒体扫描)