How to open a CSV file from Android App
September 28, 2018
In this tutorial, we will look at how to open a CSV file from Android App and display the CSV data on App.
Git Hub Project
The complete project can be cloned from here.
Example CSV Files
Prerequisites
- Android Eumulator or Physical device
- Android Studio
- Kotlin Programming
Reference
Overview
In this tutorial, we will open a CSV file using Android storage access framework. Then read the content of the CSV file and load the data to display on the App.
Dependencies
Here we don’t need any extra dependencies. However, minSdkVersion
must be at least 21
in order to use Android storage access framework.
Screenshot
Main Activity
At line 24, we use setOnClickListener
to send Intent
to open the Android built-in UI picker to open a file. Note that we are using Intent.ACTION_OPEN_DOCUMENT
and Intent.CATEGORY_OPENABLE
so that we can interactively browse through all the files that are openable
. But we are limiting the openable files by using intent.type = "text/*"
at line 27 so that we can only open text file.
Once the file is selected by a user, the function onActivityResult
at line 32 will be invoked. Using the Uri from the incoming intent, we use readCsv
function at line 40 to load a list of String
. Once the string data is extracted from the CSV file, we use joinToString
function to display on text view mTextViewCsvResult
.
You can assign any number to READ_REQUEST_CODE
. Doesn’t has to be 123
in this example. But when you have multiple intents (eg. open image files, open PDF files) then you need to assign a unique number to each intent and act on it based on that number.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package aknay.readcsv
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Button
import android.widget.TextView
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
class MainActivity : AppCompatActivity() {
private lateinit var mTextViewCsvResult: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mTextViewCsvResult = findViewById(R.id.textView_csvResult)
findViewById<Button>(R.id.button_loadCsv)?.setOnClickListener {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "text/*"
startActivityForResult(intent, READ_REQUEST_CODE)
}
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
resultData?.let { intent ->
mTextViewCsvResult.text = readCSV(intent.data).joinToString(separator = "\n")
}
}
}
@Throws(IOException::class)
fun readCSV(uri: Uri): List<String> {
val csvFile = contentResolver.openInputStream(uri)
val isr = InputStreamReader(csvFile)
return BufferedReader(isr).readLines()
}
companion object {
const val READ_REQUEST_CODE = 123
}
}
XML Layout
We don’t have much to explain here. Just take note of the android:id
for MainActivity
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView_csvResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The result will be displayed here."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_loadCsv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Load CSV File" />
</android.support.constraint.ConstraintLayout>