MediaScannerReceiver
16lz
2021-12-04
源码android/packages/apps/providers/media/src/com/android/providers/media/MediaScannerReceiver.java
package com.android.providers.media;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import java.io.File;
public class MediaScannerReceiver extends BroadcastReceiver
{
private final static String TAG = "MediaScannerReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Uri uri = intent.getData();
String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
// scan internal storage
scan(context, MediaProvider.INTERNAL_VOLUME);
// scan external storage if it is mounted
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
scan(context, MediaProvider.EXTERNAL_VOLUME);
}
} else {
if (uri.getScheme().equals("file")) {
// handle intents related to external storage
String path = uri.getPath();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)) {
scan(context, MediaProvider.EXTERNAL_VOLUME);
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null && path.startsWith(externalStoragePath + "/")) {
scanFile(context, path);
}
}
}
}
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));
}
}
从上面的源码可以总结以下几点:
1,action.equals(Intent.ACTION_BOOT_COMPLETED)
每当机器boot完之后就会发出Intent.ACTION_BOOT_COMPLETED,而在MediaScannerReceiver 接到该Action之后就对Internal 和External(若Sdcard挂载了)扫描,将其数据扫描到对应的数据库。所以你在开发的时候,每次开模拟器或手机你注意Logcat信息,就可以发现:scanner Internal Volumn...等等相关信息
2,uri.getScheme().equals("file")
除了接受机器boot完的Action要去扫描,还接受了以file中的两种扫描:扫描External和扫描一个文件:
1)
action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)[/color])
scan(context, MediaProvider.EXTERNAL_VOLUME);
2)
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null[/color] && path.startsWith(externalStoragePath + "/")) {
scanFile(context, path)
我们可以找到android自带ap的里运用了这种,就是Deve Tool里的Media Scanner,其扫描Sdcard:
其源码:apps›Development›src›com›android›development›MediaScannerActivity.java
package com.android.providers.media;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import java.io.File;
public class MediaScannerReceiver extends BroadcastReceiver
{
private final static String TAG = "MediaScannerReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Uri uri = intent.getData();
String externalStoragePath = Environment.getExternalStorageDirectory().getPath();
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
// scan internal storage
scan(context, MediaProvider.INTERNAL_VOLUME);
// scan external storage if it is mounted
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
scan(context, MediaProvider.EXTERNAL_VOLUME);
}
} else {
if (uri.getScheme().equals("file")) {
// handle intents related to external storage
String path = uri.getPath();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)) {
scan(context, MediaProvider.EXTERNAL_VOLUME);
} else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null && path.startsWith(externalStoragePath + "/")) {
scanFile(context, path);
}
}
}
}
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));
}
}
从上面的源码可以总结以下几点:
1,action.equals(Intent.ACTION_BOOT_COMPLETED)
每当机器boot完之后就会发出Intent.ACTION_BOOT_COMPLETED,而在MediaScannerReceiver 接到该Action之后就对Internal 和External(若Sdcard挂载了)扫描,将其数据扫描到对应的数据库。所以你在开发的时候,每次开模拟器或手机你注意Logcat信息,就可以发现:scanner Internal Volumn...等等相关信息
2,uri.getScheme().equals("file")
除了接受机器boot完的Action要去扫描,还接受了以file中的两种扫描:扫描External和扫描一个文件:
1)
action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)[/color])
scan(context, MediaProvider.EXTERNAL_VOLUME);
2)
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null[/color] && path.startsWith(externalStoragePath + "/")) {
scanFile(context, path)
我们可以找到android自带ap的里运用了这种,就是Deve Tool里的Media Scanner,其扫描Sdcard:
其源码:apps›Development›src›com›android›development›MediaScannerActivity.java
package com.android.development;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.BroadcastReceiver;import android.net.Uri;import android.os.Environment;import android.widget.TextView;public class MediaScannerActivity extends Activity{ public MediaScannerActivity() { } /** Called when the activity is first created or resumed. */ @Override public void onResume() { super.onResume(); setContentView(R.layout.media_scanner_activity); [color=red]IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_STARTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); intentFilter.addDataScheme("file"); registerReceiver(mReceiver, intentFilter)[/color]; sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); mTitle = (TextView) findViewById(R.id.title); mTitle.setText("Sent ACTION_MEDIA_MOUNTED to trigger the Media Scanner."); } /** Called when the activity going into the background or being destroyed. */ @Override public void onPause() { super.onPause(); unregisterReceiver(mReceiver); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { mTitle.setText("Media Scanner started scanning " + intent.getData().getPath()); } else if (intent.getAction().equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { mTitle.setText("Media Scanner finished scanning " + intent.getData().getPath()); } } }; private TextView mTitle;}
更多相关文章
- 大虾们的 android 浅谈
- android几种开源项目源码地址
- Android录音下————AudioRecord源码分析
- Android查看外部依赖jar的源码'Android(安卓)Private Libraries'
- 【Android(安卓)开发】: Android(安卓)消息处理机制之四: Androi
- Android扫描条形码实现
- Android(安卓)JNI打印c\c++日志信息
- Android小项目合集(经典教程)包含十五个Android开发应用实例
- android 开发资源