android中媒体扫描服务mediaScannerService

来源:互联网 发布:网络借贷不还会坐牢吗 编辑:程序博客网 时间:2024/05/19 17:26

背景:
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));    }   

先睡觉,未完待续

0 0
原创粉丝点击