[android]ギャラリーもしくはカメラから画像を持ってくる

#はじめに
　　　　javaの基本的な理解はできている
　　　　androidStudioの導入が完了している
同じく、開発初心者による備忘録のような形になります。
[Day1.AndroidStudioにおけるプロジェクトの作り方](http://qiita.com/BD1-FM/items/f9caa43b2d5510ddcfe4)
[Day2.Androidアプリケーションの構成](http://qiita.com/BD1-FM/items/c5ed161feec1fdf92796)
[Day3.アプリケーションのレイアウト](http://qiita.com/Yuki_Yamada/items/eb4a25cedca2ff8078fd)
[Day4.onClickListenerの実装とその後の処理](http://qiita.com/Yuki_Yamada/items/758bcce58801c12cd4d5)
[Day5.Activityのライフサイクル](http://qiita.com/Yuki_Yamada/items/5906bca15b312de4479d)
[Day6.xmlで枠を指定する](http://qiita.com/Yuki_Yamada/items/15fc68dc88b57734149b)
[Day7.SDカードのpathの取得](http://qiita.com/Yuki_Yamada/items/122e6adb368c357cde74)

#ギャラリーもしくはカメラから画像を持ってくる
よくある処理だと思うので備忘録的に書き記しておきます。
御託はいいからコードをよこせという人は一番下まで飛ばしちゃってください。


##つまったポイント
SDKのversionが19以上以下で処理が変わることに気づくのが遅かった


#各種Intentの用意
##カメラのIntent

```java:.java
        String photoName = System.currentTimeMillis() + ".jpg";
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Images.Media.TITLE, photoName);
        contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        m_uri = getContentResolver()
                .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

        Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, m_uri);
```

カメラのほうは特に詰まることなく記述できました。
説明する箇所もないかと思います。

##ギャラリー（ドキュメント）のIntent
余談ですがこのドキュメントというのわかりずらいので変えてほしいですね
上で一度触れていますがSDKversionが19以上の時とそれより下の時に呼び出す[intent.]が違います。具体的に見ていただくのが一番早いと思いますのでコードを下に記します。

```java:.java
 Intent intentGallery;
        if (Build.VERSION.SDK_INT < 19) {
            intentGallery = new Intent(Intent.ACTION_GET_CONTENT);
            intentGallery.setType("image/*");
        } else {
            intentGallery = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intentGallery.addCategory(Intent.CATEGORY_OPENABLE);
            intentGallery.setType("image/jpeg");
        }
```

##createChooserについて
Intentのメソッドの一つにcreateChooserがあります。
暗示的Intentを使用する際createChooserを使用しないとデフォルトのダイアログが出てきます。これはよく見る「常にこのアプリを使用する」のチェックボックス付のダイアログです。もし、createChooserを使った場合これがなくなります。ちなみに、startActivityには対応していますがstartServiceには対応してないので注意してください。
また、ダイアログ上部の文も変えることができるという利点（？）があります。
もちろん必須メソッドではないです。

```java:.java
        Intent intent = Intent.createChooser(intentCamera, "画像の選択");
        intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {intentGallery});
        startActivityForResult(intent, REQUEST_CHOOSER);
```

createChooserを用いてintentを持たせておき(ここではカメラのintentを）、そこにputExtraで「EXTRA_INITIAL_INTENTS」(ギャラリーのintentを）を与えています。
そしてそれをstartActivityForResultで起動します。

##startActivityForResultについて
移動先Acitivtyから値を返してもらいたいときに使います。
呼び出されるメソッドは「onActivityResult」です。具体的に呼び出されるタイミングとしては移動先Activityがfinish()されたときです。
引数は

```java:.java
startActivityForResult(Intent intent,int requestCode);
onActivityResult(int requestCode,int resultCode,Intent data);
```

###onActivityResult
requestCodeはstartActivityForResultの第二引数がそのまま入ります。これをswitch文で分けることで処理を分けれます。
resultCode起動先のActivity.setResultの第一引数です。

#コードを残して終了

```java:.java
public class mainActivity extends ActionBarActivity {

    private Uri m_uri;
    private static final int REQUEST_CHOOSER = 1000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setViews();
    }
    private void setViews(){
        Button button = (Button)findViewById(R.id.buttonPanel);
        button.setOnClickListener(button_onClick);
    }
    private View.OnClickListener button_onClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showGallery();
        }
    };

    private void showGallery() {

        //カメラの起動Intentの用意
        String photoName = System.currentTimeMillis() + ".jpg";
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Images.Media.TITLE, photoName);
        contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        m_uri = getContentResolver()
                .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

        Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, m_uri);

        // ギャラリー用のIntent作成
        Intent intentGallery;
        if (Build.VERSION.SDK_INT < 19) {
            intentGallery = new Intent(Intent.ACTION_GET_CONTENT);
            intentGallery.setType("image/*");
        } else {
            intentGallery = new Intent(Intent.ACTION_OPEN_DOCUMENT);
            intentGallery.addCategory(Intent.CATEGORY_OPENABLE);
            intentGallery.setType("image/jpeg");
        }
        Intent intent = Intent.createChooser(intentCamera, "画像の選択");
        intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] {intentGallery});
        startActivityForResult(intent, REQUEST_CHOOSER);
    }

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

        if(requestCode == REQUEST_CHOOSER) {

            if(resultCode != RESULT_OK) {
                // キャンセル時
                return ;
            }

            Uri resultUri = (data != null ? data.getData() : m_uri);

            if(resultUri == null) {
                // 取得失敗
                return;
            }

            // ギャラリーへスキャンを促す
            MediaScannerConnection.scanFile(
                    this,
                    new String[]{resultUri.getPath()},
                    new String[]{"image/jpeg"},
                    null
            );

            // 画像を設定
            ImageView imageView = (ImageView)findViewById(R.id.imageView);
            imageView.setImageURI(resultUri);
        }
    }
}


以上です。