Android多媒体扫描

packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerReceiver.java
负责接收外界发来的请求扫描

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

启动服务
packages/providers/MediaProvider/src/com/android/providers/media/MediaScannerService.java

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

工作线程

    public void run()
    {
   
        // reduce priority below other background threads to avoid interfering
        // with other services at boot time.
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
                Process.THREAD_PRIORITY_LESS_FAVORABLE);
        Looper.prepare();

        mServiceLooper = Looper.myLooper();
        mServiceHandler = new ServiceHandler();

        Looper.loop();
    }
    @Override
    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;
    }

handler处理消息

    private final class ServiceHandler extends Handler
    {
   
        @Override
        public void handleMessage(Message msg)
        {
   
            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 {
   
                    String volume = arguments.getString("volume");
                    String[] directories = null;
                    
                    if (MediaProvider.INTERNAL_VOLUME.equals(volume)) {
   
                        // scan internal media storage
                        directories = new String[] {
   
                                Environment.getRootDirectory() + "/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);
                    }
                }
            } catch (Exception e) {
   
                Log.e(TAG, "Exception in handleMessage", e);
            }

            stopSelf(msg.arg1);
        }
    };
    static final String INTERNAL_VOLUME = "internal";//内部
    static final String EXTERNAL_VOLUME = "external";//外部

获取文件夹路径后扫描

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

创建MediaScanner

    private MediaScanner createMediaScanner() {
   
        MediaScanner scanner = new MediaScanner(this);
        Locale locale = getResources().getConfiguration().locale;
        if (locale != null) {
   
            String language = locale.getLanguage();
            String country = locale.getCountry();
            String localeString = null;
            if (language != null) {
   
                if (country != null) {
   
                    scanner.setLocale(language + "_" + country);
                } else {
   
                    scanner.setLocale(language);
                }
            }    
        }
        
        return scanner;
    }

frameworks/base/media/java/android/media/MediaScanner.java
主要扫描工作

public void scanDirectories(String[] directories, String volumeName) {
   
        try {
   
            long start = System.currentTimeMillis();
            initialize(volumeName);
            prescan(null, true);
            long prescan = System.currentTimeMillis();

            if (ENABLE_BULK_INSERTS) {
   
                // create MediaInserter for bulk inserts
                mMediaInserter = new MediaInserter(mMediaProvider, mPackageName, 500);
            }

            for (int i = 0; i < directories.length; i++) {
   
                processDirectory(directories[i]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值