AndroidはCSVをサポートしていないので導入は避けようという資料
いまプライベートで作っているアプリでCSVインポート機能を実装しようとして、「これは安易に導入しちゃだめだな…」と感じたのでまとめた資料です。
公式SDK(API33時点)のCSV対応状況について
現時点で公式SDKはCSVファイルの読み込みに対応していません。
また、ストレージアクセスフレームワーク(SAF)を使ってファイルを読み込もうとした場合、typeを text/csv
にするとCSVファイルがそもそも選択できません。
text/*
にしてテキストファイルというくくりでSAFを呼び出す必要があります。
AndroidのCSV読み込みライブラリについて
Android用に最適化されたCSVの読み込みライブラリはないようです。 opencsvやCommons CSVあたりが現実的な選択肢になりそうです。
手動で読み込みを行いたい場合
上記に書いた、SAFでファイルを読み込んで、特定のClassにパースして返すまでのサンプルコードです。
private val openCsvFileResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data?.data?.let {
val stringBuilder = StringBuilder()
contentResolver.openInputStream(it)?.use { inputStream ->
BufferedReader(InputStreamReader(inputStream)).use { reader ->
var line: String? = reader.readLine()
while (line != null) {
stringBuilder.append("$line\n")
line = reader.readLine()
}
}
}
convertCsvTextToItems(stringBuilder.toString())
}
}
}
private fun openCsvFileForPicker() {
val intent = Intent(Intent.ACTION_GET_CONTENT, null).apply {
type = "text/*"
}
openCsvFileResult.launch(intent)
}
private fun convertCsvTextToItems(text: String): List<Item> {
val textLines = text.split("\r\n", "\r", "\n")
val items = textLines
.map {
val data = it.split(",")
// TODO: Itemに変換
}
return items
}
ただ、このコードは問題点があります。
- 選択したファイルがCSVファイルであることを前提にしている
- 区切り文字がカンマ前提となっている
- 1行目からデータが書かれていることを前提としている
そもそもCSVファイルの仕様はどうなっているのか
CSVファイルの仕様はRFC 4180で書かれています。
RFC 4180: Common Format and MIME Type for Comma-Separated Values (CSV) Files
RFC 4180では区切り文字がカンマであり、改行コードはCRLFであることが定義されていますが、ヘッダ行の存在や各項目をダブルクォーテーションで囲むかは自由とされています。
そのため、「最低限RFC 4180に対応したCSVのみ読み込みます」とした場合でも、これらの対応をコードに落とし込む必要があります。
CSVがダメなら何を使うか
どうしてもテキストファイルでデータを読み込みたいなら、JSONファイルに変換したものを読み込めばよいのではないでしょうか。 JSONならKotlin SerializationやMoshiやGsonなどのAndroid対応ライブラリが用意されているので、読み込みはめちゃくちゃ楽になるはずです。
個人的結論
- 完全に決められた形式のCSVファイル(たとえば自社コンテンツのインポートファイルなど)だけを読み込ませるなら、まあ良し
- この場合エラーハンドリングはちゃんとやっておくこと
- 何かしらのテキストデータを読み込ませる機能を使いたいなら、まだJSONファイルの方が個人的によい
- どうしても使いたいなら、opencsvやCommon CSVを使う
yamacraftを支援する
記事への感謝や応援を、コーヒー1杯分の支援で行うことができます。支援を受けると、さらに頑張って記事を書くようになります。