7 package com.google.appinventor.components.runtime;
9 import android.Manifest;
10 import android.app.Activity;
11 import android.content.ContentValues;
12 import android.content.Intent;
13 import android.net.Uri;
14 import android.os.Build;
15 import android.os.Environment;
16 import android.provider.MediaStore;
17 import android.util.Log;
32 import java.util.Date;
45 @DesignerComponent(version = YaVersion.CAMERA_COMPONENT_VERSION,
46 description =
"A component to take a picture using the device's camera. " +
47 "After the picture is taken, the name of the file on the phone " +
48 "containing the picture is available as an argument to the " +
49 "AfterPicture event. The file name can be used, for example, to set " +
50 "the Picture property of an Image component.",
51 category = ComponentCategory.MEDIA,
53 iconName =
"images/camera.png")
55 @UsesPermissions(permissionNames =
"android.permission.WRITE_EXTERNAL_STORAGE, android.permission.READ_EXTERNAL_STORAGE," +
56 "android.permission.CAMERA")
60 private static final String CAMERA_INTENT =
MediaStore.ACTION_IMAGE_CAPTURE;
61 private static final String CAMERA_OUTPUT =
MediaStore.EXTRA_OUTPUT;
63 private Uri imageFile;
67 private int requestCode;
70 private boolean useFront;
74 private boolean havePermission =
false;
84 super(container.
$form());
85 this.container = container;
98 public
boolean UseFront() {
111 @
SimpleProperty(description =
"Specifies whether the front-facing camera should be used (when available). "
112 +
"If the device does not have a front-facing camera, this option will be ignored "
113 +
"and the camera will open normally.")
114 public
void UseFront(
boolean front) {
126 if (!havePermission) {
129 Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE) {
131 public void onGranted() {
132 me.havePermission = true;
138 String state = Environment.getExternalStorageState();
139 if (Environment.MEDIA_MOUNTED.equals(state)) {
140 Log.i(
"CameraComponent",
"External storage is available and writable");
143 if (!directory.exists()) {
146 File image =
new File(QUtil.getExternalStorageDir(form),
147 "Pictures/app_inventor_" +
new Date().getTime()
149 imageFile = Uri.fromFile(image);
151 ContentValues values =
new ContentValues();
152 values.put(MediaStore.Images.Media.DATA, imageFile.getPath());
153 values.put(MediaStore.Images.Media.MIME_TYPE,
"image/jpeg");
154 values.put(MediaStore.Images.Media.TITLE, imageFile.getLastPathSegment());
156 if (requestCode == 0) {
157 requestCode = form.registerForActivityResult(
this);
161 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
162 imageUri = container.
$context().getContentResolver().insert(
163 MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
165 imageUri = NougatUtil.getPackageUri(form, image);
167 Intent intent =
new Intent(CAMERA_INTENT);
168 intent.putExtra(CAMERA_OUTPUT, imageUri);
173 intent.putExtra(
"android.intent.extras.CAMERA_FACING", 1);
176 container.
$context().startActivityForResult(intent, requestCode);
177 }
else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
178 form.dispatchErrorOccurredEvent(
this,
"TakePicture",
179 ErrorMessages.ERROR_MEDIA_EXTERNAL_STORAGE_READONLY);
181 form.dispatchErrorOccurredEvent(
this,
"TakePicture",
182 ErrorMessages.ERROR_MEDIA_EXTERNAL_STORAGE_NOT_AVAILABLE);
188 Log.i(
"CameraComponent",
189 "Returning result. Request code = " + requestCode +
", result code = " + resultCode);
190 if (requestCode == this.requestCode && resultCode == Activity.RESULT_OK) {
191 File image =
new File(imageFile.getPath());
192 if (image.length() != 0) {
193 scanFileToAdd(image);
194 AfterPicture(imageFile.toString());
196 deleteFile(imageFile);
198 if (data !=
null && data.getData() !=
null) {
199 Uri tryImageUri = data.getData();
200 Log.i(
"CameraComponent",
"Calling Camera.AfterPicture with image path "
201 + tryImageUri.toString());
202 AfterPicture(tryImageUri.toString());
204 Log.i(
"CameraComponent",
"Couldn't find an image file from the Camera result");
205 form.dispatchErrorOccurredEvent(
this,
"TakePicture",
211 deleteFile(imageFile);
221 private void scanFileToAdd(
File image) {
222 Intent mediaScanIntent =
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
224 mediaScanIntent.setData(contentUri);
225 container.
$context().getApplicationContext().sendBroadcast(mediaScanIntent);
228 private void deleteFile(Uri fileUri) {
229 File fileToDelete =
new File(fileUri.getPath());
231 if (fileToDelete.delete()) {
232 Log.i(
"CameraComponent",
"Deleted file " + fileUri.toString());
234 Log.i(
"CameraComponent",
"Could not delete file " + fileUri.toString());
236 }
catch (SecurityException e) {
237 Log.i(
"CameraComponent",
"Got security exception trying to delete file "
238 + fileUri.toString());