Search code examples
androidencryptiongoogle-drive-api

How to upload encrypted image file on google drive from android using Google Drive API


I want to upload the encrypted image file from Android to a user-specific google drive, Also want to Decrypt the image while loading in-app.


Solution

  • Use the following function It will upload encrypted image file on google drive and also downloading the decryption image save it to the app private files folder.

    suspend fun uploadFileToGDrive(path: String?, suffix: String?): String {
        getDriveService()?.let { googleDriveService ->
            try {
                if (path != null) {
                    Log.e("pathGD", path)
                }
    
                googleDriveService.fetchOrCreateAppFolder(
                    context.getString(R.string.application_folder),
                    preferenceHelper
                )
                val encryptedData = ImageCrypto().encryptFile("$path")
                Log.e("encryptedData", encryptedData)
    
                val actualFile = File(encryptedData)
                if (!actualFile.exists()) error("File $actualFile not exists.")
                val gFile = com.google.api.services.drive.model.File()
                // gFile.name = actualFile.name
                val formatter = SimpleDateFormat("yyyyMMddHHmmss")
                var dateString = formatter.format(Date())
    
                gFile.name = dateString + suffix
                gFile.parents = listOf(preferenceHelper.getFolderId())
              
                val fileContent = FileContent("image/jpeg", actualFile)
                val create = googleDriveService.files().create(gFile, fileContent)
                    .setFields("id, parents")
                    .execute()
                driveFilePathId = create.id
    
            } catch (exception: Exception) {
                exception.printStackTrace()
            }
        } ?: ""
       Toast.makeText(context, "Please Log In first!", LENGTH_LONG).show()
        return driveFilePathId
    }
    

    and I have uploaded encryption and decryption image using AES on my github profile. Please check.

    https://github.com/meshramaravind/FileEncryptedAES

    And when you display image from google drive. you need to download the image using decryption.

    First download the image from google drive function call.

     fun downloadFileFromGDrive(id: String) {
        getDriveService()?.let { googleDriveService ->
            CoroutineScope(Dispatchers.IO).launch {
                Log.e("idDownload", id)
                val file = File(context.filesDir, "${id}.jpg")
                if(!file.exists()) {
                    try {
                        val gDriveFile = googleDriveService.Files().get(id).execute()
                        createDirectoryAndSaveImagePackage(gDriveFile.id)
                    } catch (e: Exception) {
                        println("!!! Handle Exception $e")
                    }
                }
            }
        } ?: ""
        //Toast.makeText(context, "Please Log In first!", LENGTH_SHORT).show()
    }
    

    and save it to the app private files folder:

     fun createDirectoryAndSaveImagePackage(id: String?) {
        getDriveService()?.let { googleDriveService ->
            CoroutineScope(Dispatchers.IO).launch {
                val file = File(context.filesDir, "${id}.jpg")
                Log.e("fileEncryptedDirGD", "$file")
                try {
                    val outputStream = FileOutputStream(file)
                    googleDriveService.files()[id]
                        .executeMediaAndDownloadTo(outputStream)
                    if (id != null) {
                        googleDriveService.readFile(id)
                    }
                    val decryptedDataDir = ImageCrypto().decryptFile("$file")
                    Log.e("decryptedDataDir", decryptedDataDir)
                    outputStream.flush()
                    outputStream.close()
    
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }
    
    
      and display image jetpack compose.
    

    fun displayImage() {

    val fileGD = File(context.filesDir, "${it1}.jpg") if (fileGD.exists()) { val decryptedData2 = ImageCrypto().decryptFile("$fileGD")

                                           val painterBitmap = rememberImagePainter(
                                            data = File(decryptedData2),
                                            builder = {
                                                crossfade(500)
                                            })
    
                                        val painterState = painterBitmap.state
    
                                        val painter =
                                            rememberImagePainter(
                                                data = File(decryptedData2),
                                                builder = {
                                                    placeholder(R.drawable.placeholder)
                                                    error(R.drawable.placeholder)
                                                })
    
    
                                        if (painterState is ImagePainter.State.Loading) {
                                            CircularProgressIndicator(
                                                modifier = Modifier.align(Alignment.Center),
                                                color = MaterialTheme.colors.secondary
                                            )
    
                                        } else {
    
                                            Image(
                                                painter = painter,
                                                contentScale = ContentScale.Inside,
                                                modifier = Modifier
                                                    .width(200.dp)
                                                    .height(100.dp)
                                                    .padding(PADDING / 2),
                                                contentDescription = null,
                                            )
                                        }
                                       }
                                       }