【Androidアプリ】外部アプリと連携してファイルを転送する方法

2021年1月22日

はじめに

お世話になります、hosochinです
最近家でラーメン二郎ごっこやってお腹ぶっ壊しました

さて、今回はAndroidアプリについてです
少し前に作っていたAndroidアプリで、zipファイルを外部アプリ(mail、Lineとか)使って転送する機能を実装しようとして、ハマったのでそのメモになります
結論としては、Android7から『file://』による指定ができなくなったため、fileproviderでuriを作る必要がありました

サンプルコード

  • AndroidManifest.xml
<application>
<!-- providerの設定 -->
<!-- android:grantUriPermissionsをtrueにして外部からのファイルへのアクセスを許可する -->
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true"> 
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider" />
    </provider>
</application>
  • MainActivity.kt
// zipファイルのパス
val exportDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val zipFilePath = exportDir.path + "/sample.zip"

val intent = Intent()
intent.type = "application/zip"
intent.action = Intent.ACTION_SEND
intent.putExtra(
    Intent.EXTRA_STREAM, FileProvider.getUriForFile(
        this, applicationContext.packageName + ".provider"
        , File(zipFilePath)
    )
)
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
  • res/xml/file_provider.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <external-path name="external_storage_directory" path="." />
</resources>
  • external-path
    • Environment.getExternalStorageDirectory()の下に対象ファイルがあるため、external-pathを設定
  • name
    • 適当
  • path
    • Environment.getExternalStorageDirectory()直下を指定するため.を設定

まとめ

どうやらキモは file_provider.xml っぽい
転送したい対象のファイルの場所によってxmlの書き方も変わるので以下にまとめておきます

  • Context.getFilesDir()
    ファイルがfiles/アプリの内部ストレージ領域のサブディレクトリ内にある場合
    <cache-path name = " name " path = " path " />
  • getCacheDir()
    ファイルがアプリの内部ストレージ領域のキャッシュサブディレクトリ内にある場合
    <cache-path name = " name " path = " path " />
  • Environment.getExternalStorageDirectory()
    ファイルが外部ストレージ領域内にある場合
    <external-files-path name = " name " path = " path " />
  • Context.getExternalFilesDir(null)
    ファイルがアプリの外部ストレージ領域内にある場合
    <external-cache-path name = " name " path = " path " />
  • Context.getExternalCacheDir()
    ファイルがアプリの外部キャッシュ領域内にある場合
    <external-media-path name = " name " path = " path " />

技術Android,Kotlin

Posted by hosochin