19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ServiceConnection;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.IMediaScannerListener;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.IMediaScannerService;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
32b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * MediaScannerConnection provides a way for applications to pass a
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * newly created or downloaded media file to the media scanner service.
34b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * The media scanner service will read metadata from the file and add
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the file to the media content provider.
36b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen * The MediaScannerConnectionClient provides an interface for the
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * media scanner service to return the Uri for a newly scanned file
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the client of the MediaScannerConnection class.
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MediaScannerConnection implements ServiceConnection {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "MediaScannerConnection";
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Context mContext;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MediaScannerConnectionClient mClient;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private IMediaScannerService mService;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private boolean mConnected; // true if connect() has been called since last disconnect()
48b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
4930c918ce7fbe171944b28fc91b3f22b3d631872dGlenn Kasten    private final IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void scanCompleted(String path, Uri uri) {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MediaScannerConnectionClient client = mClient;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (client != null) {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                client.onScanCompleted(path, uri);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
59e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * Interface for notifying clients of the result of scanning a
60e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * requested media file.
61e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     */
62b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen    public interface OnScanCompletedListener {
63e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        /**
64e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn         * Called to notify the client when the media scanner has finished
65e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn         * scanning a file.
66e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn         * @param path the path to the file that has been scanned.
67b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         * @param uri the Uri for the file if the scanning operation succeeded
68b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         * and the file was added to the media database, or null if scanning failed.
69b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         */
70e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        public void onScanCompleted(String path, Uri uri);
71e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    }
72b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
73e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * An interface for notifying clients of MediaScannerConnection
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when a connection to the MediaScanner service has been established
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and when the scanning of a file has completed.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
78b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen    public interface MediaScannerConnectionClient extends OnScanCompletedListener {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
80b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         * Called to notify the client when a connection to the
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * MediaScanner service has been established.
82b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         */
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onMediaScannerConnected();
84b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called to notify the client when the media scanner has finished
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * scanning a file.
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param path the path to the file that has been scanned.
89b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         * @param uri the Uri for the file if the scanning operation succeeded
90b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         * and the file was added to the media database, or null if scanning failed.
91b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen         */
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onScanCompleted(String path, Uri uri);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Constructs a new MediaScannerConnection object.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param context the Context object, required for establishing a connection to
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the media scanner service.
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param client an optional object implementing the MediaScannerConnectionClient
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * interface, for receiving notifications from the media scanner.
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MediaScannerConnection(Context context, MediaScannerConnectionClient client) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mClient = client;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Initiates a connection to the media scanner service.
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link MediaScannerConnectionClient#onMediaScannerConnected()}
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be called when the connection is established.
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void connect() {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mConnected) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Intent intent = new Intent(IMediaScannerService.class.getName());
116f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen                intent.setComponent(
117f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen                        new ComponentName("com.android.providers.media",
118f7bcf1951c598604d312600d1efe5734646dc5a4Marco Nelissen                                "com.android.providers.media.MediaScannerService"));
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mConnected = true;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Releases the connection to the media scanner service.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void disconnect() {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mConnected) {
13143a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                if (false) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.v(TAG, "Disconnecting from Media Scanner");
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mContext.unbindService(this);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (IllegalArgumentException ex) {
13743a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                    if (false) {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Log.v(TAG, "disconnect failed: " + ex);
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mConnected = false;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
145b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns whether we are connected to the media scanner service
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return true if we are connected, false otherwise
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized boolean isConnected() {
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (mService != null && mConnected);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Requests the media scanner to scan a file.
156b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen     * Success or failure of the scanning operation cannot be determined until
157e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * {@link MediaScannerConnectionClient#onScanCompleted(String, Uri)} is called.
158b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen     *
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param path the path to the file to be scanned.
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param mimeType  an optional mimeType for the file.
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If mimeType is null, then the mimeType will be inferred from the file extension.
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     public void scanFile(String path, String mimeType) {
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mService == null || !mConnected) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new IllegalStateException("not connected to MediaScannerService");
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
16943a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                if (false) {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.v(TAG, "Scanning file " + path);
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mService.requestScanFile(path, mimeType, mListener);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
17443a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato                if (false) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Log.d(TAG, "Failed to scan file " + path);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
180b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
181e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    static class ClientProxy implements MediaScannerConnectionClient {
182e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        final String[] mPaths;
183e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        final String[] mMimeTypes;
184b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen        final OnScanCompletedListener mClient;
185e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        MediaScannerConnection mConnection;
186e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        int mNextPath;
187b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
188b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen        ClientProxy(String[] paths, String[] mimeTypes, OnScanCompletedListener client) {
189e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            mPaths = paths;
190e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            mMimeTypes = mimeTypes;
191e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            mClient = client;
192e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        }
193b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
194e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        public void onMediaScannerConnected() {
195e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            scanNextPath();
196e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        }
197b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
198e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        public void onScanCompleted(String path, Uri uri) {
199e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            if (mClient != null) {
200e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                mClient.onScanCompleted(path, uri);
201e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            }
202e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            scanNextPath();
203e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        }
204b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
205e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        void scanNextPath() {
206e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            if (mNextPath >= mPaths.length) {
207e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                mConnection.disconnect();
208e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn                return;
209e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            }
210e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            String mimeType = mMimeTypes != null ? mMimeTypes[mNextPath] : null;
211e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            mConnection.scanFile(mPaths[mNextPath], mimeType);
212e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn            mNextPath++;
213e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        }
214e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    }
215b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
216e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    /**
217e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * Convenience for constructing a {@link MediaScannerConnection}, calling
218e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * {@link #connect} on it, and calling {@link #scanFile} with the given
219e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * <var>path</var> and <var>mimeType</var> when the connection is
220e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * established.
221e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * @param context The caller's Context, required for establishing a connection to
222e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * the media scanner service.
223b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen     * Success or failure of the scanning operation cannot be determined until
224e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * {@link MediaScannerConnectionClient#onScanCompleted(String, Uri)} is called.
225e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * @param paths Array of paths to be scanned.
226e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * @param mimeTypes Optional array of MIME types for each path.
227e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * If mimeType is null, then the mimeType will be inferred from the file extension.
228e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * @param callback Optional callback through which you can receive the
229e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * scanned URI and MIME type; If null, the file will be scanned but
230e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     * you will not get a result back.
2311e88cf0796c8b15952b7d6b3160d0d097e857f15Ryan Lothian     * @see #scanFile(String, String)
232e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn     */
233e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    public static void scanFile(Context context, String[] paths, String[] mimeTypes,
234b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen            OnScanCompletedListener callback) {
235e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        ClientProxy client = new ClientProxy(paths, mimeTypes, callback);
236e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        MediaScannerConnection connection = new MediaScannerConnection(context, client);
237e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        client.mConnection = connection;
238e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn        connection.connect();
239e83cefcef07f9ac025642c1ffec76b4c7ab39cf2Dianne Hackborn    }
240b7c8c76180dc1abbf55c734ab121a7a2469060f6Ray Chen
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Part of the ServiceConnection interface.  Do not call.
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onServiceConnected(ComponentName className, IBinder service) {
24543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato        if (false) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.v(TAG, "Connected to Media Scanner");
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService = IMediaScannerService.Stub.asInterface(service);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mService != null && mClient != null) {
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mClient.onMediaScannerConnected();
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Part of the ServiceConnection interface.  Do not call.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onServiceDisconnected(ComponentName className) {
26043a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato        if (false) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.v(TAG, "Disconnected from Media Scanner");
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (this) {
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mService = null;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
268