1 package com.android.gallery3d.data; 2 3 import android.annotation.TargetApi; 4 import android.content.Context; 5 import android.media.MediaScannerConnection; 6 import android.media.MediaScannerConnection.MediaScannerConnectionClient; 7 import android.mtp.MtpObjectInfo; 8 import android.net.Uri; 9 import android.os.Environment; 10 import android.util.Log; 11 import android.widget.Toast; 12 13 import com.android.gallery3d.R; 14 import com.android.gallery3d.common.ApiHelper; 15 import com.android.gallery3d.util.BucketNames; 16 import com.android.gallery3d.util.GalleryUtils; 17 18 import java.io.File; 19 import java.util.ArrayList; 20 import java.util.List; 21 22 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB_MR1) 23 public class MtpContext implements MtpClient.Listener { 24 private static final String TAG = "MtpContext"; 25 26 private ScannerClient mScannerClient; 27 private Context mContext; 28 private MtpClient mClient; 29 30 private static final class ScannerClient implements MediaScannerConnectionClient { 31 ArrayList<String> mPaths = new ArrayList<String>(); 32 MediaScannerConnection mScannerConnection; 33 boolean mConnected; 34 Object mLock = new Object(); 35 36 public ScannerClient(Context context) { 37 mScannerConnection = new MediaScannerConnection(context, this); 38 } 39 40 public void scanPath(String path) { 41 synchronized (mLock) { 42 if (mConnected) { 43 mScannerConnection.scanFile(path, null); 44 } else { 45 mPaths.add(path); 46 mScannerConnection.connect(); 47 } 48 } 49 } 50 51 @Override 52 public void onMediaScannerConnected() { 53 synchronized (mLock) { 54 mConnected = true; 55 if (!mPaths.isEmpty()) { 56 for (String path : mPaths) { 57 mScannerConnection.scanFile(path, null); 58 } 59 mPaths.clear(); 60 } 61 } 62 } 63 64 @Override 65 public void onScanCompleted(String path, Uri uri) { 66 } 67 } 68 69 public MtpContext(Context context) { 70 mContext = context; 71 mScannerClient = new ScannerClient(context); 72 mClient = new MtpClient(mContext); 73 } 74 75 public void pause() { 76 mClient.removeListener(this); 77 } 78 79 public void resume() { 80 mClient.addListener(this); 81 notifyDirty(); 82 } 83 84 @Override 85 public void deviceAdded(android.mtp.MtpDevice device) { 86 notifyDirty(); 87 showToast(R.string.camera_connected); 88 } 89 90 @Override 91 public void deviceRemoved(android.mtp.MtpDevice device) { 92 notifyDirty(); 93 showToast(R.string.camera_disconnected); 94 } 95 96 private void notifyDirty() { 97 mContext.getContentResolver().notifyChange(Uri.parse("mtp://"), null); 98 } 99 100 private void showToast(final int msg) { 101 Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show(); 102 } 103 104 public MtpClient getMtpClient() { 105 return mClient; 106 } 107 108 public boolean copyFile(String deviceName, MtpObjectInfo objInfo) { 109 if (GalleryUtils.hasSpaceForSize(objInfo.getCompressedSize())) { 110 File dest = Environment.getExternalStorageDirectory(); 111 dest = new File(dest, BucketNames.IMPORTED); 112 dest.mkdirs(); 113 String destPath = new File(dest, objInfo.getName()).getAbsolutePath(); 114 int objectId = objInfo.getObjectHandle(); 115 if (mClient.importFile(deviceName, objectId, destPath)) { 116 mScannerClient.scanPath(destPath); 117 return true; 118 } 119 } else { 120 Log.w(TAG, "No space to import " + objInfo.getName() + 121 " whose size = " + objInfo.getCompressedSize()); 122 } 123 return false; 124 } 125 126 public boolean copyAlbum(String deviceName, String albumName, 127 List<MtpObjectInfo> children) { 128 File dest = Environment.getExternalStorageDirectory(); 129 dest = new File(dest, albumName); 130 dest.mkdirs(); 131 int success = 0; 132 for (MtpObjectInfo child : children) { 133 if (!GalleryUtils.hasSpaceForSize(child.getCompressedSize())) continue; 134 135 File importedFile = new File(dest, child.getName()); 136 String path = importedFile.getAbsolutePath(); 137 if (mClient.importFile(deviceName, child.getObjectHandle(), path)) { 138 mScannerClient.scanPath(path); 139 success++; 140 } 141 } 142 return success == children.size(); 143 } 144 } 145