android中媒体扫描服务mediaScannerService
16lz
2021-01-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)); }
先睡觉,未完待续
更多相关文章
- Android(安卓)PocketSphinx离线语音识别集成总结
- 知乎 Android(安卓)客户端三方库敏感代码扫描机制 - FindDanger
- Android(安卓)sdcard媒体文件更新(程序控制刷新MediaStore数据库)
- SB程序媛学习笔记--Android(安卓)zxing实现二维码开发
- Android(安卓)USB 扫码枪获取扫描内容
- Android实现深度链接(APP外带动态参数唤醒APP,并跳转指定页面,APP
- 纪念一下坑爹的蓝牙扫描枪连接(Android外接输入设备)
- Android(安卓)基于百度语音的语音交互功能(推荐)
- 扒一扒Android应用的续命大法