Adding csv file as input in my tflite model in Android Studio

Hello!
I am trying to use a csv file as a new input for my tflite model in Android Studio. To get the data, I download it using google drive using the code below:
package com.example.ui2

import android.Manifest
import android.app.Activity
import android.app.DownloadManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.widget.Button
import android.widget.TextView
import androidx.core.app.ActivityCompat
import com.example.ui2.ml.IrradWinter
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.api.Scope
import com.google.api.client.extensions.android.http.AndroidHttp
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
import com.google.api.client.json.gson.GsonFactory
import com.google.api.services.drive.Drive
import com.google.api.services.drive.DriveScopes
import kotlinx.android.synthetic.main.activity_main.*
import org.tensorflow.lite.DataType
import org.tensorflow.lite.support.tensorbuffer.TensorBuffer
import java.nio.ByteBuffer


class MainActivity : Activity(){
    var privateclient: GoogleSignInClient? = null
    var googleDriveServiceFunction: GoogleDriveServiceFunction? = null
    private val PICK_IMAGE_FROM_GALLERY_REQUEST_CODE = 300
    private var btnChooseFile: Button? = null
    private var btnSearchGD: Button? = null
    private var btnCreateFolder: Button? = null




    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener{
            download("https://drive.google.com/drive/u/0/folders/1aBy0WtyaETkfD3YxZo73iQaFa2aGzwY8")
        }
        requestStoragePremission()
        requestSignIn()
        getforcast.setOnClickListener{

            val model = IrradWinter.newInstance(this)


            val capacity = 4*24*5
            val byteBuffer: ByteBuffer = ByteBuffer.allocateDirect(capacity)
            val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 24, 5), DataType.FLOAT32)
            inputFeature0.loadBuffer(byteBuffer)

            val outputs = model.process(inputFeature0)
            val outputFeature0 = outputs.outputFeature0AsTensorBuffer
            val tv: TextView = findViewById(R.id.getforcast)
            val ans = (outputFeature0.getFloatValue(0))
            tv.setText(ans.toString())
        }
        }



private fun requestSignIn() {
        val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .requestScopes(
                Scope(DriveScopes.DRIVE_FILE),
                Scope(DriveScopes.DRIVE_APPDATA),
                Scope(DriveScopes.DRIVE)
            )
            .build()
        privateclient = GoogleSignIn.getClient(this, signInOptions)
        startActivityForResult(privateclient!!.signInIntent, REQUEST_SIGNIN_CODE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_SIGNIN_CODE && resultCode == RESULT_OK) {
            handleSignInIntent(data)
        }
    }

    private fun handleSignInIntent(data: Intent?) {
        GoogleSignIn.getSignedInAccountFromIntent(data)
            .addOnSuccessListener { googleSignInAccount: GoogleSignInAccount ->
                val credential = GoogleAccountCredential
                    .usingOAuth2(this, setOf(DriveScopes.DRIVE_FILE))
                credential.selectedAccount = googleSignInAccount.account
                drive(credential)
            }
            .addOnFailureListener { e: Exception -> e.printStackTrace() }
    }

    private fun drive(credential: GoogleAccountCredential?) {
        val googleDriveService = Drive.Builder(
            AndroidHttp.newCompatibleTransport(),
            GsonFactory(),
            credential
        )
            .setApplicationName("Appname")
            .build()
        googleDriveServiceFunction = GoogleDriveServiceFunction(googleDriveService)
    }

    companion object {
        private const val REQUEST_SIGNIN_CODE = 400
    }

    private fun requestStoragePremission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
                1
            )
        }
    }
    private fun download(url: String?) {
        val request = DownloadManager.Request(Uri.parse(url))
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOCUMENTS, "winter4city.csv")
        request.allowScanningByMediaScanner()
        val downloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
        downloadManager.enqueue(request)
    }
}

And this is my code that I got after I import the tflite in android studio: (it is in kotlin)

val model = Irrad5autumn.newInstance(context)

// Creates inputs for reference.
val inputFeature0 = TensorBuffer.createFixedSize(intArrayOf(1, 24, 5), DataType.FLOAT32)
inputFeature0.loadBuffer(byteBuffer)

// Runs model inference and gets result.
val outputs = model.process(inputFeature0)
val outputFeature0 = outputs.outputFeature0AsTensorBuffer

// Releases model resources if no longer used.
model.close()

How can I change the input from the file that I have downloaded in google drive?

1 Like

Hi, @Jay_Bhie_Santos

I apologize for the delayed response, I see you have implemented the code for downloading the csv file from Google drive and make sure that file is getting downloaded in the Assets folder and you can use opencsv library and to use it you’ll have to add that dependancy in build.gradle(app level) something like below:

dependencies {
    // CSV reader
    implementation 'com.opencsv:opencsv:4.6'
}

You’ll have to give permission to access that csv file so please add below code
in AndroidManifest.xml:

    <application
        android:requestLegacyExternalStorage="true"
        ...
val reader = CSVReader(
            getApplication<Application>().applicationContext.assets.open("file-name.csv")
                .reader()
        )
        val myEntries: List<Array<String>> = reader.readAll()

After that convert your data to ByteBuffer by doing something like below

fun floatArrayToBuffer(floatArray: FloatArray): FloatBuffer? {
        val byteBuffer: ByteBuffer = ByteBuffer
            .allocateDirect(floatArray.size * 4)

        byteBuffer.order(ByteOrder.nativeOrder())

        val floatBuffer: FloatBuffer = byteBuffer.asFloatBuffer()

        floatBuffer.put(floatArray) 
        floatBuffer.position(0)
        return floatBuffer
    }

Please refer this stackoverflow issue thread which may help you to solve your issue, if your issue still persists after trying with latest TFLite version please let us know with your Github repo( if possible).

If I have missed something here please let me know.

Thank you for your cooperation and patience.

1 Like