7 package com.google.appinventor.components.runtime;
9 import android.Manifest;
10 import android.app.Activity;
11 import android.content.ContentResolver;
12 import android.content.Intent;
13 import android.net.Uri;
14 import android.provider.MediaStore;
15 import android.util.Log;
16 import android.webkit.MimeTypeMap;
31 import java.io.IOException;
32 import java.util.Arrays;
33 import java.util.Comparator;
44 @DesignerComponent(version = YaVersion.IMAGEPICKER_COMPONENT_VERSION,
45 description =
"A special-purpose button. When the user taps an image picker, the " +
46 "device's image gallery appears, and the user can choose an image. After an image is " +
47 "picked, it is saved, and the <code>Selected</code> " +
48 "property will be the name of the file where the image is stored. In order to not " +
49 "fill up storage, a maximum of 10 images will be stored. Picking more images " +
50 "will delete previous images, in order from oldest to newest.",
51 category = ComponentCategory.MEDIA)
53 @UsesPermissions(permissionNames =
"android.permission.WRITE_EXTERNAL_STORAGE")
57 private static final String LOG_TAG =
"ImagePicker";
60 private static final String imagePickerDirectoryName =
"/Pictures/_app_inventor_image_picker";
63 private static final String FILE_PREFIX =
"picked_image";
66 private static int maxSavedFiles = 10;
69 private String selectionURI;
72 private String selectionSavedImage =
"";
75 private boolean havePermission =
false;
89 @
SimpleProperty(description =
"Path to the file containing the image that was selected.",
92 return selectionSavedImage;
97 return new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.INTERNAL_CONTENT_URI);
102 if (!havePermission) {
106 public void HandlePermissionResponse(String permission,
boolean granted) {
108 havePermission =
true;
130 if (
requestCode == this.requestCode && resultCode == Activity.RESULT_OK) {
131 Uri selectedImage = data.getData();
132 selectionURI = selectedImage.toString();
133 Log.i(LOG_TAG,
"selectionURI = " + selectionURI);
137 MimeTypeMap mime = MimeTypeMap.getSingleton();
138 String extension =
"." + mime.getExtensionFromMimeType(cR.getType(selectedImage));
139 Log.i(LOG_TAG,
"extension = " + extension);
143 saveSelectedImageToExternalStorage(extension);
148 private void saveSelectedImageToExternalStorage(String extension) {
151 Manifest.permission.WRITE_EXTERNAL_STORAGE);
157 selectionSavedImage =
"";
160 File tempFile =
null;
164 tempFile = MediaUtil.copyMediaToTempFile(
container.
$form(), selectionURI);
165 }
catch (IOException e) {
166 Log.i(LOG_TAG,
"copyMediaToTempFile failed: " + e.getMessage());
168 ErrorMessages.ERROR_CANNOT_COPY_MEDIA, e.getMessage());
173 Log.i(LOG_TAG,
"temp file path is: " + tempFile.getPath());
175 copyToExternalStorageAndDeleteSource(tempFile, extension);
178 private void copyToExternalStorageAndDeleteSource(File source, String extension) {
182 String fullDirname = QUtil.getExternalStoragePath(
container.
$form()) + imagePickerDirectoryName;
183 File destDirectory =
new File(fullDirname);
186 destDirectory.mkdirs();
187 dest = File.createTempFile (FILE_PREFIX, extension, destDirectory);
189 selectionSavedImage = dest.getPath();
192 Log.i(LOG_TAG,
"saved file path is: " + selectionSavedImage);
194 FileUtil.copyFile(source.getAbsolutePath(), dest.getAbsolutePath());
196 Log.i(LOG_TAG,
"Image was copied to " + selectionSavedImage);
201 }
catch(IOException e) {
202 String err =
"destination is " + selectionSavedImage +
": " +
"error is " + e.getMessage();
203 Log.i(LOG_TAG,
"copyFile failed. " + err);
205 ErrorMessages.ERROR_CANNOT_SAVE_IMAGE, err);
206 selectionSavedImage =
"";
213 trimDirectory(maxSavedFiles, destDirectory);
217 private void trimDirectory(
int maxSavedFiles, File directory) {
219 File[] files = directory.listFiles();
221 Arrays.sort(files,
new Comparator<File>(){
222 public int compare(File f1, File f2)
224 return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
227 int excess = files.length - maxSavedFiles;
228 for (
int i = 0; i < excess; i++) {