1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.media; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.Intent; 22import android.content.ServiceConnection; 23import android.media.IMediaScannerListener; 24import android.media.IMediaScannerService; 25import android.net.Uri; 26import android.os.IBinder; 27import android.os.RemoteException; 28import android.util.Config; 29import android.util.Log; 30 31 32/** 33 * MediaScannerConnection provides a way for applications to pass a 34 * newly created or downloaded media file to the media scanner service. 35 * The media scanner service will read metadata from the file and add 36 * the file to the media content provider. 37 * The MediaScannerConnectionClient provides an interface for the 38 * media scanner service to return the Uri for a newly scanned file 39 * to the client of the MediaScannerConnection class. 40 */ 41public class MediaScannerConnection implements ServiceConnection { 42 43 private static final String TAG = "MediaScannerConnection"; 44 45 private Context mContext; 46 private MediaScannerConnectionClient mClient; 47 private IMediaScannerService mService; 48 private boolean mConnected; // true if connect() has been called since last disconnect() 49 50 private IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() { 51 public void scanCompleted(String path, Uri uri) { 52 MediaScannerConnectionClient client = mClient; 53 if (client != null) { 54 client.onScanCompleted(path, uri); 55 } 56 } 57 }; 58 59 /** 60 * An interface for notifying clients of MediaScannerConnection 61 * when a connection to the MediaScanner service has been established 62 * and when the scanning of a file has completed. 63 */ 64 public interface MediaScannerConnectionClient { 65 /** 66 * Called to notify the client when a connection to the 67 * MediaScanner service has been established. 68 */ 69 public void onMediaScannerConnected(); 70 71 /** 72 * Called to notify the client when the media scanner has finished 73 * scanning a file. 74 * @param path the path to the file that has been scanned. 75 * @param uri the Uri for the file if the scanning operation succeeded 76 * and the file was added to the media database, or null if scanning failed. 77 */ 78 public void onScanCompleted(String path, Uri uri); 79 } 80 81 /** 82 * Constructs a new MediaScannerConnection object. 83 * @param context the Context object, required for establishing a connection to 84 * the media scanner service. 85 * @param client an optional object implementing the MediaScannerConnectionClient 86 * interface, for receiving notifications from the media scanner. 87 */ 88 public MediaScannerConnection(Context context, MediaScannerConnectionClient client) { 89 mContext = context; 90 mClient = client; 91 } 92 93 /** 94 * Initiates a connection to the media scanner service. 95 * {@link MediaScannerConnectionClient#onMediaScannerConnected()} 96 * will be called when the connection is established. 97 */ 98 public void connect() { 99 synchronized (this) { 100 if (!mConnected) { 101 Intent intent = new Intent(IMediaScannerService.class.getName()); 102 mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); 103 mConnected = true; 104 } 105 } 106 } 107 108 /** 109 * Releases the connection to the media scanner service. 110 */ 111 public void disconnect() { 112 synchronized (this) { 113 if (mConnected) { 114 if (Config.LOGV) { 115 Log.v(TAG, "Disconnecting from Media Scanner"); 116 } 117 try { 118 mContext.unbindService(this); 119 } catch (IllegalArgumentException ex) { 120 if (Config.LOGV) { 121 Log.v(TAG, "disconnect failed: " + ex); 122 } 123 } 124 mConnected = false; 125 } 126 } 127 } 128 129 /** 130 * Returns whether we are connected to the media scanner service 131 * @return true if we are connected, false otherwise 132 */ 133 public synchronized boolean isConnected() { 134 return (mService != null && mConnected); 135 } 136 137 /** 138 * Requests the media scanner to scan a file. 139 * @param path the path to the file to be scanned. 140 * @param mimeType an optional mimeType for the file. 141 * If mimeType is null, then the mimeType will be inferred from the file extension. 142 * Success or failure of the scanning operation cannot be determined until 143 * {@link MediaScannerConnectionClient#onScanCompleted(String, Uri)} is called. 144 */ 145 public void scanFile(String path, String mimeType) { 146 synchronized (this) { 147 if (mService == null || !mConnected) { 148 throw new IllegalStateException("not connected to MediaScannerService"); 149 } 150 try { 151 if (Config.LOGV) { 152 Log.v(TAG, "Scanning file " + path); 153 } 154 mService.requestScanFile(path, mimeType, mListener); 155 } catch (RemoteException e) { 156 if (Config.LOGD) { 157 Log.d(TAG, "Failed to scan file " + path); 158 } 159 } 160 } 161 } 162 163 /** 164 * Part of the ServiceConnection interface. Do not call. 165 */ 166 public void onServiceConnected(ComponentName className, IBinder service) { 167 if (Config.LOGV) { 168 Log.v(TAG, "Connected to Media Scanner"); 169 } 170 synchronized (this) { 171 mService = IMediaScannerService.Stub.asInterface(service); 172 if (mService != null && mClient != null) { 173 mClient.onMediaScannerConnected(); 174 } 175 } 176 } 177 178 /** 179 * Part of the ServiceConnection interface. Do not call. 180 */ 181 public void onServiceDisconnected(ComponentName className) { 182 if (Config.LOGV) { 183 Log.v(TAG, "Disconnected from Media Scanner"); 184 } 185 synchronized (this) { 186 mService = null; 187 } 188 } 189} 190