はじめに
FlutterでAndroidとiOSでファイルアクセスしたくなったので、動かしながら調べてみました。
まだしっかりと調べてないところもあるので内容を更新するかも。
パスの取得方法
アプリケーション用のパスを利用する場合は path_provider
path_provider で取得されるパスはアプリケーション専用のパスを取得できます。
ほかのアプリケーションから参照することはできません。
ただし、パーミッションをAndroidManifest.xmlに設定する必要はありません。
以下のコマンドでプラグインを導入します。
flutter pub add path_provider
使い方は簡単で、以下のように利用します。
var appDocDir = await getApplicationDocumentsDirectory();
File targetPath = File("${appDocDir.path}/test.txt");
Method | Android | iOS |
---|---|---|
getApplicationDocumentsDirectory() | /data/user/0/<パッケージ名>/app_flutter/ | /var/mobile/Containers/Data/Application/[UUID]/Documents/ |
getApplicationSupportDirectory() | /data/user/0/<パッケージ名>/files/ | /var/mobile/Containers/Data/Application/[UUID]/Library/Application Support/ |
getDownloadsDirectory() | Androidは未対応 | /var/mobile/Containers/Data/Application/[UUID]/Downloads |
getExternalCacheDirectories() | /storage/emulated/0/Android/data/<パッケージ名>/cache/ | iOSは未対応 |
getExternalStorageDirectory | /storage/emulated/0/Android/data/<パッケージ名>/files/ | iOSは未対応 |
getExternalStorageDirectories({StorageDirectory? type})
type | Android | iOS |
---|---|---|
StorageDirectory.alarms | /storage/emulated/0/Android/data/<パッケージ名>/files/alarms/ | iOSは未対応 |
StorageDirectory.dcim | /storage/emulated/0/Android/data/<パッケージ名>/files/dcim/ | iOSは未対応 |
StorageDirectory.documents | /storage/emulated/0/Android/data/<パッケージ名>/files/documents/ | iOSは未対応 |
StorageDirectory.downloads | /storage/emulated/0/Android/data/<パッケージ名>/files/downloads/ | iOSは未対応 |
StorageDirectory.movies | /storage/emulated/0/Android/data/<パッケージ名>/files/movies/ | iOSは未対応 |
StorageDirectory.music | /storage/emulated/0/Android/data/<パッケージ名>/files/music/ | iOSは未対応 |
StorageDirectory.notifications | /storage/emulated/0/Android/data/<パッケージ名>/files/notifications/ | iOSは未対応 |
StorageDirectory.pictures | /storage/emulated/0/Android/data/<パッケージ名>/files/pictures/ | iOSは未対応 |
StorageDirectory.podcasts | /storage/emulated/0/Android/data/<パッケージ名>/files/podcasts/ | iOSは未対応 |
StorageDirectory.ringtones | /storage/emulated/0/Android/data/<パッケージ名>/files/ringtones/ | iOSは未対応 |
ユーザーがアクセス可能なパスを取得するなら external_path
このライブラリで取得できるパスはAndroid 13では android.permission.MANAGE_EXTERNAL_STORAGE を指定しないとアクセスできないっぽいです。
Android 9ではandroid.permission.READ_EXTERNAL_STORAGE、android.permission.WRITE_EXTERNAL_STORAGEアクセス可能。
ちなみにAndroid専用なのでiOSでは使えないです。
iOSで動かすと
MissingPluginException(No implementation found for method getExternalStoragePublicDirectory on channel external_path)
ってエラーになります。
以下のコマンドでプラグインを導入します。
flutter pub add permission_handler
flutter pub add external_path
AndroidManifest.xmlに以下を追加
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_MEDIA_IMAGE"/>
<uses-permission android:name="android.permission.WRITE_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.WRITE_MEDIA_AUDIO"/>
<application
・・・略・・・
android:requestLegacyExternalStorage="true"/>
Parameter | Android | iOS |
---|---|---|
ExternalPath.DIRECTORY_ALARMS | /storage/emulated/0/Alarms/ | iOSは未対応 |
ExternalPath.DIRECTORY_AUDIOBOOKS | /storage/emulated/0/Audiobooks/ | iOSは未対応 |
ExternalPath.DIRECTORY_DCIM | /storage/emulated/0/DCIM/ | iOSは未対応 |
ExternalPath.DIRECTORY_DOCUMENTS | /storage/emulated/0/Documents/ | iOSは未対応 |
ExternalPath.DIRECTORY_DOWNLOADS | /storage/emulated/0/Download/ | iOSは未対応 |
ExternalPath.DIRECTORY_MOVIES | /storage/emulated/0/Movies/ | iOSは未対応 |
ExternalPath.DIRECTORY_MUSIC | /storage/emulated/0/Music/ | iOSは未対応 |
ExternalPath.DIRECTORY_NOTIFICATIONS | /storage/emulated/0/Notifications/ | iOSは未対応 |
ExternalPath.DIRECTORY_PICTURES | /storage/emulated/0/Pictures/ | iOSは未対応 |
ExternalPath.DIRECTORY_PODCASTS | /storage/emulated/0/Podcasts/ | iOSは未対応 |
ExternalPath.DIRECTORY_RINGTONES | /storage/emulated/0/Ringtones/ | iOSは未対応 |
ExternalPath.DIRECTORY_SCREENSHOTS | /storage/emulated/0/Screenshots/ | iOSは未対応 |
画像の保存は image_gallery_saver
gallery_saver もあるが、image_gallery_saver のほうが融通が利くのでこちらを使うのがよさそう。
とりあえず、これで保存はできる。