過去にAndroidアプリで画像をシェアする実装をしていたけど、ここ最近ご無沙汰で昔のコードを探してみても file://〜
を使っていたり、android.support.v4.content.FileProvider
を使っていたり と、セキュリティ上の問題やAndroidX対応などで、そのまま使えるコードではなくなっていました。JavaからKotlinベースに書き換えたこともあって備忘録代わりに書き残しておきます。
Kotlinで、BitmapオブジェクトをJPEGにエンコードした上で、ShareCompatを使って他のアプリへ画像を共有します。ShareCompatは、iOSでの UIActivityViewController
に当たります。
Bitmapオブジェクトを保存して、他のアプリへ画像を共有する
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest ...> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application ...> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider> ... </application> </manifest>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-cache-path name="cache" path="." /> </paths>
最後に画像を編集するFragmentかなにかで共有処理を実行します。
private fun onShareImage() { val context = context ?: return val shareBitmap = bitmap ?: return //ファイルの作成(JPGで圧縮して書き込む) val file = File(context.externalCacheDir, "share_temp.jpeg") FileOutputStream(file).use { outputStream -> shareBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) outputStream.flush() } //共有用のURIを取得する val fileUri: Uri? = try { FileProvider.getUriForFile(context, context.packageName + ".fileprovider", file) } catch (e: IllegalArgumentException) { null } fileUri ?: run { // 「共有用のURLが取得できませんでした...」ダイアログとか出す return } //シェアダイアログを表示する val builder = ShareCompat.IntentBuilder.from(activity) builder.addStream(fileUri) .setType(context.contentResolver.getType(fileUri)) // image/jpeg val intent = builder.createChooserIntent().addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) intent.resolveActivity(context.packageManager)?.also { startActivity(intent); } }