PhotoByIntent

This is the app you get when you press the big blue “Download the Sample” button in Recording Videos Simply.

If the Intent that takes a still photo is carrying the MediaStore.ExtraOutput installed by dispatchTakePictureIntent, the image will be deposited into the specified file and the third parameter of onActivityResult will be null. If the Intent has no MediaStore.ExtraOutput, no file is written and the third parameter of onActivityResult will contain a thumbnail image.

Source code in PhotoByIntent.zip

  1. MainActivity.java
  2. AlbumStorageDirFactory.java is an abstract class with a method that returns the directory where files are stored.
  3. BaseAlbumDirFactory.java is the subclass of AlbumStorageDirFactory for SDK < 8, when photos were stored in a subdirectory of the dcim directory (Digital Camera Images).
  4. FroyoAlbumDirFactory.java is the subclass of AlbumStorageDirFactory for SDK ≥ 8.
  5. res/layout/activity_main.xml for portrait orientation.
  6. res/layout-land/activity_main.xml for landscape orientation. See Providing Alternative Resources.
  7. strings.xml
  8. AndroidManifest.xml has <uses-feature> and <uses-permission>.
  9. build.gradle (Module: app)

Create the project

Select the folder app/res in the Android Studio project view and pull down
File → New → Android resource directory
Resource type: layout
Under Avalable qualifiers, select Orientation. Press >>. Under Screen orientatation, select Landscape. Press OK.

Select the folder app/res/layout in the Android Studio project view and pull down
File → New → Layout resource file
File name: activity_main
Under Avalable qualifiers, select Orientation. Press >>. Under Screen orientatation, select Landscape. Note that the directory name has changed to layout-land. Press OK.

Things to try

  1. The VideoView was a black rectangle until I inserted the call to start in handleCameraVideo. Better yet, change
            mVideoView.start();
    
    to the following. Then you’ll be able to click on the black rectangle and get playback controls.
            mVideoView.setMediaController(new MediaController(this));
    

  2. The top (or only) line of text in all three buttons is at the same level. To get the top edge of all three buttons to be at the same level, add the attribute android:baselineAligned="false" to the horizontal LinearLayout.

  3. The ImageView is born with dimensions 0 × 0, because its width and height in activity_main.xml are wrap_content and wrap_content, and it has no content yet. If the first button we press is Take (big) Picture, the scaleFactor in setPic will be 1, setting the Bitmap and ImageView to the actual size of the image. If we then take a small picture, the Bitmap and ImageView will be set to a much smaller size. If we then take another big picture, the scaleFactor will be set to a larger number and the Bitmap and ImageView will be set to the small size. Correct this.

  4. Would getAlbumDir be easier to read if we rearranged it as follows? It still does exactly the same thing, and makes it easy to see that one of the Logs is missing.
        private File getAlbumDir() {
            if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
                return null;
            }
    
            File storageDir = mAlbumStorageDirFactory.getAlbumStorageDir(getAlbumName());
            if (storageDir == null) {
                return null;
            }
    
            if (!storageDir.mkdirs() && !storageDir.exists()) {
                Log.d("CameraSample", "failed to create directory");
                return null;
            }
    
            return storageDir;
        }