カメラ/フォト(Intent)

(ブログ記事の一覧は「こちら」)

カメラの起動/撮影方法や、フォト(写真)データへのアクセス方法について学びましょう。
いずれもIntentクラスを使用します。カメラアプリ、フォトアプリにアクセスして、画像を取得することが可能です。
OSのバージョンによってプログラミングの方法が異なる場合があるので注意が必要です。

ここで学ぶこと

  • カメラの起動/撮影方法
  • フォト(写真)データへのアクセス方法

※ カメラの撮影のプログラムは、OS 6.0以降でのみ正常に動作することを確認しています。それ以前のOSについては調査中です。

例題

作成するもの

カメラアプリ、フォトアプリにアクセスして、画像を取得するサンプルを作成しましょう。

レイアウト

  • Button(R.id.button_Camera)
  • Button(R.id.button_Gallery)
  • ImageView(R.id. imageView_Picture)

プログラム

カメラアプリにアクセスするためには、撮影した写真を端末に保存するのためパーミッション(許可)を設定する必要があります。
AndroidManifest.xmlXMLで開き、uses-permissionの行を追加します。

<?xml version="1.0" encoding="utf-8"?>
<manifest package="[ This is the package name. ]"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        ...


必要となる定数、変数を宣言します。

public class MainActivity extends AppCompatActivity {

    public static final int REQUEST_CAMERA = 100;
    public static final int REQUEST_PHOTO = 101;

    private Uri mUriImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}

Uri(Uniform Resource Identifier)とは、「http://」や「https://」で始まるURL(Uniform Resource Locator)を含む、Webの情報をまとめたものです。


カメラアプリを起動するプログラムです。
Button(R.id.button_Camera)をクリックしたときに呼び出す箇所に記述します。

// 作成する画像ファイル名
String strFileName = "sample.jpg";

// Uriオブジェクトにセットする情報を設定
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, strFileName);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");

// Uriオブジェクトを生成
ContentResolver resolver = getContentResolver();
mUriImage = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

// カメラを起動
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mUriImage);
startActivityForResult(intent, REQUEST_CAMERA);


フォトアプリを起動するプログラムです。
Button(R.id.button_Gallery)をクリックしたときに呼び出す箇所に記述します。

Intent intent;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    // OS 4.4 より前
    intent = new Intent(Intent.ACTION_GET_CONTENT);
} else {
    // OS 4.4 以降
    intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
}
intent.setType("image/*");
startActivityForResult(intent, REQUEST_PHOTO);


カメラアプリで撮影、またはフォトアプリで選択した画像データは、onActivityResult関数で得ることができます。
(onActivityResult関数は、メニューの [Code] -[Override Methods...] から記述できます。)

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) {
        ImageView imageView = findViewById(R.id.imageView_Picture);

        if (requestCode == REQUEST_CAMERA) {
            imageView.setImageURI(mUriImage);
            
        } else if (requestCode == REQUEST_PHOTO) {
            if (data != null) {
                imageView.setImageURI(data.getData());
            }
        }
    }
}

実行、確認

カメラアプリで撮影、またはフォトアプリで選択した画像データが ImageViewに表示されることを確認してください。

課題1

例題で表示された画像はサイズが大きいため、端末のスペックによっては画面の横幅いっぱいに表示されます。
画像を縮小して表示する方法として、以下のLinearLayoutを使用した方法があります。

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_horizontal"
        android:weightSum="2">

        <ImageView
            android:id="@+id/imageView_Picture"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
    </LinearLayout>

上記の例は、画面の横幅の半分のサイズで縮小されて表示されます。実際に試してみてください。
また、縮小の割合が画面の横幅の 1/4 になるように修正してください。

課題2

※ 例題のカメラのプログラムが正常に動作する端末(OS 6.0以降)を持っている場合は、こちらの課題も行ってください。

カメラで撮影した画像ファイルに対して、他のファイル名と同じにならないように、画像ファイル名を指定して保存するように、プログラムを修正してください。

[ヒント]
一案として、ファイル名に現在の日付と時刻を加える方法が考えられます。
現在の日付と時刻を得るには、SimpleDateFormatクラスとDateクラスを使用します。以下も参考にしてください。

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.JAPAN);