The path to the full image is available from the
Intent's
extra with the
EXTRA_PICTURE_FILE_PATH
key. When the image capture intent returns control to your
Glassware, the image might not be fully written to file. Verify
that the image file exists or use a
FileObserver
to monitor its parent directory. When the full image is
available, load the file and use it in your Glassware.
privatestaticfinalintTAKE_PICTURE_REQUEST=1;privatevoidtakePicture(){Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);startActivityForResult(intent,TAKE_PICTURE_REQUEST);}@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){if(requestCode==TAKE_PICTURE_REQUEST && resultCode==RESULT_OK){StringthumbnailPath=data.getStringExtra(Intents.EXTRA_THUMBNAIL_FILE_PATH);StringpicturePath=data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH);processPictureWhenReady(picturePath);// TODO: Show the thumbnail to the user while the full picture is being// processed.}super.onActivityResult(requestCode,resultCode,data);}privatevoidprocessPictureWhenReady(finalStringpicturePath){finalFilepictureFile=newFile(picturePath);if(pictureFile.exists()){// The picture is ready; process it.}else{// The file does not exist yet. Before starting the file observer, you// can update your UI to let the user know that the application is// waiting for the picture (for example, by displaying the thumbnail// image and a progress indicator).finalFileparentDirectory=pictureFile.getParentFile();FileObserverobserver=newFileObserver(parentDirectory.getPath(),FileObserver.CLOSE_WRITE|FileObserver.MOVED_TO){// Protect against additional pending events after CLOSE_WRITE// or MOVED_TO is handled.privatebooleanisFileWritten;@OverridepublicvoidonEvent(intevent,Stringpath){if(!isFileWritten){// For safety, make sure that the file that was created in// the directory is actually the one that we're expecting.FileaffectedFile=newFile(parentDirectory,path);isFileWritten=affectedFile.equals(pictureFile);if(isFileWritten){stopWatching();// Now that the file is ready, recursively call// processPictureWhenReady again (on the UI thread).runOnUiThread(newRunnable(){@Overridepublicvoidrun(){processPictureWhenReady(picturePath);}});}}}};observer.startWatching();}}
Videos
To capture a video using the built-in Camera Glassware:
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-07-10 UTC."],[[["\u003cp\u003eThe Glass camera can be used to capture images and videos, and to display a preview stream for various use cases.\u003c/p\u003e\n"],["\u003cp\u003eYou can capture images and videos using the built-in camera activity or by building your own logic with the Android Camera API.\u003c/p\u003e\n"],["\u003cp\u003eWhen using the Android Camera API, temporarily release the camera when users press the hardware camera button to allow the Glass system to use it.\u003c/p\u003e\n"],["\u003cp\u003eTo capture images or videos using the built-in camera activity, use startActivityForResult() with the appropriate action and handle the results in onActivityResult().\u003c/p\u003e\n"]]],[],null,["# Camera\n\nYou can use the Glass camera to capture images and video and to also\ndisplay the camera's preview stream for a variety\nof different use cases.\n\nOverview\n--------\n\nYou have two options for capturing images or video:\n\n- Calling the built-in camera activity with [`startActivityForResult()`](//developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%20int)). Use this option when possible.\n- Building your own logic with the\n [Android Camera API](//developer.android.com/reference/android/hardware/Camera.html).\n Follow these guidelines if you are using this method:\n\n - Take a picture on a camera button click and a video on a long click, just like Glass does.\n - Indicate to the user whether a picture was taken or a video was recorded.\n - Keep the screen on during capture.\n\nSharing the camera with the Glass system\n----------------------------------------\n\nIf your Glassware uses the Android APIs to access the camera,\ntemporarily release the camera when possible if users press the hardware\ncamera button.\n\n1. Override the\n [`onKeyDown()`](//developer.android.com/reference/android/app/Activity.html#onKeyDown(int,%20android.view.KeyEvent))\n method in your activity and intercept\n [`KEYCODE_CAMERA`](//developer.android.com/reference/android/view/KeyEvent.html#KEYCODE_CAMERA)\n to handle camera button presses.\n\n2. Release the camera and return `false` to indicate that you did not consume the\n event so that the built-in Glass camera starts.\n\n| **Note:** If you return `true` from [`onKeyDown()`](//developer.android.com/reference/android/app/Activity.html#onKeyDown(int,%20android.view.KeyEvent)), your activity consumes the event and the Glass camera doesn't start. Do this only if there is no way to interrupt your activity's use of the camera (for example, if you are capturing continuous video).\n\n1. After the image or video capture takes place, Glass returns to your\n activity, where you can reclaim the camera in\n [`onResume()`](//developer.android.com/reference/android/app/Activity.html#onResume()).\n\n @Override\n public boolean onKeyDown(int keyCode, KeyEvent event) {\n if (keyCode == KeyEvent.KEYCODE_CAMERA) {\n // Stop the preview and release the camera.\n // Execute your logic as quickly as possible\n // so the capture happens quickly.\n return false;\n } else {\n return super.onKeyDown(keyCode, event);\n }\n }\n\n @Override\n protected void onResume() {\n super.onResume();\n // Re-acquire the camera and start the preview.\n }\n\nCapturing images or video\n-------------------------\n\n### Images\n\nTo capture an image using the built-in Camera Glassware:\n\n1. Call [`startActivityForResult(Intent, int)`](//developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%0Aint)) with the action set as [`ACTION_IMAGE_CAPTURE`](//developer.android.com/reference/android/provider/MediaStore.html#ACTION_IMAGE_CAPTURE).\n2. In [`onActivityResult(int, int, android.content.Intent)`](//developer.android.com/reference/android/app/Activity.html#onActivityResult(int,%20int,%20android.content.Intent)):\n 1. Ensure that the `requestCode` matches the request code used when starting the image capture intent.\n 2. Ensure that the `resultCode` matches [`RESULT_OK`](//developer.android.com/reference/android/app/Activity.html#RESULT_OK).\n 3. Obtain the path to the image's thumbnail from the [`Intent`](//developer.android.com/reference/android/content/Intent.html)'s extra with the [`EXTRA_THUMBNAIL_FILE_PATH`](/glass/develop/gdk/reference/com/google/android/glass/content/Intents#EXTRA_THUMBNAIL_FILE_PATH) key, if necessary.\n 4. The path to the full image is available from the [`Intent`](//developer.android.com/reference/android/content/Intent.html)'s extra with the [`EXTRA_PICTURE_FILE_PATH`](/glass/develop/gdk/reference/com/google/android/glass/content/Intents#EXTRA_PICTURE_FILE_PATH) key. When the image capture intent returns control to your Glassware, the image might not be fully written to file. Verify that the image file exists or use a [`FileObserver`](//developer.android.com/reference/android/os/FileObserver.html) to monitor its parent directory. When the full image is available, load the file and use it in your Glassware.\n\n private static final int TAKE_PICTURE_REQUEST = 1;\n\n private void takePicture() {\n Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);\n startActivityForResult(intent, TAKE_PICTURE_REQUEST);\n }\n\n @Override\n protected void onActivityResult(int requestCode, int resultCode, Intent data) {\n if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {\n String thumbnailPath = data.getStringExtra(Intents.EXTRA_THUMBNAIL_FILE_PATH);\n String picturePath = data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH);\n\n processPictureWhenReady(picturePath);\n // TODO: Show the thumbnail to the user while the full picture is being\n // processed.\n }\n\n super.onActivityResult(requestCode, resultCode, data);\n }\n\n private void processPictureWhenReady(final String picturePath) {\n final File pictureFile = new File(picturePath);\n\n if (pictureFile.exists()) {\n // The picture is ready; process it.\n } else {\n // The file does not exist yet. Before starting the file observer, you\n // can update your UI to let the user know that the application is\n // waiting for the picture (for example, by displaying the thumbnail\n // image and a progress indicator).\n\n final File parentDirectory = pictureFile.getParentFile();\n FileObserver observer = new FileObserver(parentDirectory.getPath(),\n FileObserver.CLOSE_WRITE | FileObserver.MOVED_TO) {\n // Protect against additional pending events after CLOSE_WRITE\n // or MOVED_TO is handled.\n private boolean isFileWritten;\n\n @Override\n public void onEvent(int event, String path) {\n if (!isFileWritten) {\n // For safety, make sure that the file that was created in\n // the directory is actually the one that we're expecting.\n File affectedFile = new File(parentDirectory, path);\n isFileWritten = affectedFile.equals(pictureFile);\n\n if (isFileWritten) {\n stopWatching();\n\n // Now that the file is ready, recursively call\n // processPictureWhenReady again (on the UI thread).\n runOnUiThread(new Runnable() {\n @Override\n public void run() {\n processPictureWhenReady(picturePath);\n }\n });\n }\n }\n }\n };\n observer.startWatching();\n }\n }\n\n### Videos\n\nTo capture a video using the built-in Camera Glassware:\n\n1. Call [`startActivityForResult(Intent, int)`](//developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%0Aint)) with the action set as [`ACTION_VIDEO_CAPTURE`](//developer.android.com/reference/android/provider/MediaStore.html#ACTION_VIDEO_CAPTURE).\n2. In [`onActivityResult(int, int, android.content.Intent)`](//developer.android.com/reference/android/app/Activity.html#onActivityResult(int,%20int,%20android.content.Intent)):\n 1. Ensure that the `requestCode` matches the request code used when starting the video capture intent.\n 2. Ensure that the `resultCode` matches [`RESULT_OK`](//developer.android.com/reference/android/app/Activity.html#RESULT_OK).\n 3. Obtain the path to the video's thumbnail from the [`Intent`](//developer.android.com/reference/android/content/Intent.html)'s extra with the [`EXTRA_THUMBNAIL_FILE_PATH`](/glass/develop/gdk/reference/com/google/android/glass/content/Intents#EXTRA_THUMBNAIL_FILE_PATH) key to display a preview if necessary.\n 4. The path to the recorded video is available from the [`Intent`](//developer.android.com/reference/android/content/Intent.html)'s extra with the [`EXTRA_VIDEO_FILE_PATH`](/glass/develop/gdk/reference/com/google/android/glass/content/Intents#EXTRA_VIDEO_FILE_PATH) key."]]