Sling Academy
Home/Kotlin/Creating a File Explorer App with Kotlin

Creating a File Explorer App with Kotlin

Last updated: December 05, 2024

In the realm of Android app development, creating a custom File Explorer app is an exciting project to demonstrate your understanding of Kotlin and Android SDK. In this guide, we'll build a basic file explorer app using Kotlin, step-by-step.

Prerequisites

Before we begin, you should have a basic understanding of:

  • Kotlin programming language
  • Android development environment setup (Android Studio, SDKs, etc.)

Setting Up Your Project

Start by creating a new Android project in Android Studio with an Empty Activity, and configure it with Kotlin. Ensure that your app has the necessary permissions to read and write files in AndroidManifest.xml:


<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Also, don't forget to handle runtime permission requests for versions above Android M to ensure the app functions well on all devices.

Creating the Layout

In activity_main.xml, define a simple layout with a RecyclerView to display the files and a TextView to show the current path:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/currentPath"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Path"
        android:padding="16dp"
        android:textSize="16sp" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/currentPath" />

</RelativeLayout>

Implementing File Browsing

Next, implement the functionality to explore the device's file system. We will use the File class in Kotlin to navigate directories. Let's start by populating our RecyclerView with file data:


import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.io.File

class MainActivity : AppCompatActivity() {

    private lateinit var filesAdapter: FilesAdapter
    private lateinit var recyclerView: RecyclerView
    private lateinit var currentPathTextView: TextView
    private var filesList: List = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        currentPathTextView = findViewById(R.id.currentPath)

        recyclerView.layoutManager = LinearLayoutManager(this)
        filesAdapter = FilesAdapter(filesList) { file ->
            if (file.isDirectory) {
                updateFileList(file)
            }
        }
        recyclerView.adapter = filesAdapter

        updateFileList(File("/")) // Start browsing from root
    }

    private fun updateFileList(directory: File) {
        supportActionBar?.title = directory.path
        currentPathTextView.text = directory.path
        filesList = directory.listFiles()?.toList() ?: listOf()
        filesAdapter.updateFiles(filesList)
    }
}

In this setup, we configure a RecyclerView with a custom adapter to display either files or folders. Tapping on a folder item causes the file list to update, reflecting the contents of the selected directory.

Creating a RecyclerView Adapter

We must now define FilesAdapter to bind file data to our RecyclerView items:


import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import java.io.File

class FilesAdapter(private var files: List, private val onClick: (File) -> Unit) :
    RecyclerView.Adapter<FilesAdapter.FileViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(android.R.layout.simple_list_item_1, parent, false)
        return FileViewHolder(view)
    }

    override fun onBindViewHolder(holder: FileViewHolder, position: Int) {
        val file: File = files[position]
        holder.bind(file, onClick)
    }

    override fun getItemCount() = files.size

    fun updateFiles(files: List) {
        this.files = files
        notifyDataSetChanged()
    }

    class FileViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val fileNameView: TextView = itemView.findViewById(android.R.id.text1)

        fun bind(file: File, onClick: (File) -> Unit) {
            fileNameView.text = file.name
            itemView.setOnClickListener { onClick(file) }
        }
    }
}

This adapter creates a list where each item represents a file or directory. Classes provided by Kotlin help succinctly define and update our views with the right data.

Testing Your Application

Build and run your application on an Android device or emulator. You should see the root directory displayed along with its contents. Furthermore, you can tap folders to delve deeper into the file system hierarchy. Handling file actions like viewing or editing further enhances the application, making it more robust.

Expanding this File Explorer app with features such as searching, file operations, or integrations (like cloud storage) are excellent opportunities for further development.

Kotlin's concise syntax and Android's powerful libraries make developing a File Explorer app both a learning experience and a testament to your growing mobile development skills. Happy coding!

Next Article: Building a Log File Reader in Kotlin

Previous Article: Using Kotlin Libraries for Advanced File Processing (`Apache Commons`, `Okio`)

Series: Kotlin - File & OS

Kotlin

You May Also Like

  • How to Use Modulo for Cyclic Arithmetic in Kotlin
  • Kotlin: Infinite Loop Detected in Code
  • Fixing Kotlin Error: Index Out of Bounds in List Access
  • Setting Up JDBC in a Kotlin Application
  • How to Work with APIs in Kotlin
  • What is the `when` Expression in Kotlin?
  • Writing a Script to Rename Multiple Files Programmatically in Kotlin
  • Using Safe Calls (`?.`) to Avoid NullPointerExceptions in Kotlin
  • Chaining Safe Calls for Complex Operations in Kotlin
  • Using the Elvis Operator for Default Values in Kotlin
  • Combining Safe Calls and the Elvis Operator in Kotlin
  • When to Avoid the Null Assertion Operator (`!!`) in Kotlin
  • How to Check for Null Values with `if` Statements in Kotlin
  • Using `let` with Nullable Variables for Scoped Operations in Kotlin
  • Kotlin: How to Handle Nulls in Function Parameters
  • Returning Nullable Values from Functions in Kotlin
  • Safely Accessing Properties of Nullable Objects in Kotlin
  • How to Use `is` for Nullable Type Checking in Kotlin
  • Combining Safe Calls with Collections in Kotlin