このページを正しく表示するにはJavascriptを有効にしてください。
Viewのキャプチャを画像化してインテントでシェアする
AndroidのViewを画像として保存してシェアしたい時の実装方法。
割とよく使うのにあまりまとめられてないのでまとめておきます。
Kotlinのコードで紹介するので、Javaの方は適宜読み替えてください。
## 手順
* Viewをキャプチャする
* キャプチャしたものを画像に保存する
* 保存した画像をシェアIntentに渡す
## Viewをキャプチャする
```kotlin
view.isDrawingCacheEnabled = true
view.destroyDrawingCache()
val bmp = view.drawingCache
```
キャプチャしたいViewに対して上記を行うだけでbitmapとして取得できます。簡単ですね。キャプチャできるのは実行したViewとその子Viewの描画内容のみです。FrameLayoutでたまたま重なっているViewや、背景にあるViewは取得できません。Backgroundが存在しないViewは背景が透明色となります。
## キャプチャしたものを画像に保存する
画像をシェアするためにはBitmapを一旦保存する必要があります。Intentにバイナリをそのまま渡すことは出来ません。
また画像は他のアプリからも見える位置に置く必要があります。
アプリのキャッシュ領域等ではダメでした。
なので画像の保存先は必然的にメディアフォルダやSD上に書き出す必要がある(=相応のPermissionが必要)…と思っていたのですが、この前解決策を見つけました。
[http://stackoverflow.com/questions/9049143/android-share-intent-for-a-bitmap-is-it-possible-not-to-save-it-prior-sharing](http://stackoverflow.com/questions/9049143/android-share-intent-for-a-bitmap-is-it-possible-not-to-save-it-prior-sharing)
ContentProviderを使って画像を提供してあげればよいみたいです。言われてみれば納得ですが、シェアする目的でContentProviderを使うのは考えが及ばなかったです。
これを使うことで変なパーミッションを使う事無く画像のシェアが可能になります。
```kotlin
val cachePath = File(context.cacheDir, "images")
cachePath.mkdirs()
val filePath = File(cachePath, "Hogehoge.png")
val fos = FileOutputStream(filePath.absolutePath)
bitmap.compress(Bitmap.CompressFormat.PNG, 95, fos)
fos.close()
val contentUri = FileProvider.getUriForFile(context, "$packageName.fileprovider", filepath)
```
CacheDirに`images/`という階層を作って、その中にPNGで画像を保存します。
そして保存したパスからContentProviderのURIを生成します。
このURIをIntentに渡せばシェアが出来ます。
```xml
# Manifest.xml
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
```
ManifestにProviderを使う宣言と、
```xml
# res/xml/filepaths.xml
```
filepathを定義するxmlも忘れずに用意しておきましょう。
## 保存した画像をシェアIntentに渡す
```
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
shareIntent.setDataAndType(contentUri, contentResolver.getType(contentUri))
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri)
shareIntent.putExtra(Intent.EXTRA_TEXT, "Viewをシェアするテスト!")
startActivity(Intent.createChooser(shareIntent, "アプリを選ぶ")))
```
先ほどのContentUriをExtraにセットしてIntentを起動してあげれば無事、他のアプリに画像をシェアすることが出来ます。