1
votes

I try to create file in google drive app specific folder. I create OAuth 2.0 Client IDs in google developer and enable drive api and also add scopes in OAuth consent screen. App is successful sign in google account. it use below code to create file in appDataFolder but it create file in My Drive section. File is created in My Drive section but file id is also getting null.

File is created using AsyncTask.

    class BackUpActivity : AppCompatActivity() {
private lateinit var googleDriveFile: File
private var mediaContent: FileContent? = null
private var rawTextFile: java.io.File? = null
private var fileMetadata: File? = null
var METADATA_FILE_PARENT = "appDataFolder"
var METADATA_FILE_TYPE = "text/plain"

private var fileList: FileList? = null
private var googleDriveService: Drive? = null
private val REQUEST_CODE_SIGN_IN: Int = 1
private lateinit var onBackupProcess: BackupRestoreProgress


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

    onBackupProcess = BackupRestoreProgress(this)
    checkLastSignIn()

    button.setOnClickListener {
        createFileInAppFolder(onBackupProcess, googleDriveService!!, this)
    }
}

private fun checkLastSignIn() {
    val googleSignInAccount = GoogleSignIn.getLastSignedInAccount(this)
    if (googleSignInAccount == null) {
        requestSignIn()
        return
    }
    setCredentials(googleSignInAccount)
    listFilesFromAppFolder(onBackupProcess)
}

/**
 * Starts a sign-in activity using [.REQUEST_CODE_SIGN_IN].
 */
private fun requestSignIn() {
    Toast.makeText(this, "Start sign in, pls wait ...", Toast.LENGTH_LONG).show()

    val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestScopes(
            Scope(DriveScopes.DRIVE_FILE),
            Scope(DriveScopes.DRIVE_APPDATA))
        .requestEmail()
        .build()
    val client = GoogleSignIn.getClient(this, signInOptions)

    startActivityForResult(client.signInIntent, REQUEST_CODE_SIGN_IN)
}


public override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
    when (requestCode) {
        REQUEST_CODE_SIGN_IN -> {
            handleSignInResult(resultData!!)
        }
    }
    super.onActivityResult(requestCode, resultCode, resultData)
}

/**
 * Handles the `result` of a completed sign-in activity initiated from [ ][.requestSignIn].
 */
private fun handleSignInResult(result: Intent) {
    GoogleSignIn.getSignedInAccountFromIntent(result)
        .addOnSuccessListener { googleAccount ->
            setCredentials(googleAccount)
        }
        .addOnFailureListener { exception -> throw exception }
}


fun setCredentials(googleSignInAccount: GoogleSignInAccount) {
    val credential = GoogleAccountCredential.usingOAuth2(
        this, listOf(
            DriveScopes.DRIVE_FILE,
            DriveScopes.DRIVE_APPDATA
        )
    )
    credential.selectedAccount = googleSignInAccount.account
    googleDriveService =
        Drive.Builder(AndroidHttp.newCompatibleTransport(), GsonFactory(), credential)
            .setApplicationName("Docscanner")
            .build()
    Toast.makeText(this, "Sign in successful", Toast.LENGTH_LONG).show()
}

@SuppressLint("StaticFieldLeak")
private fun listFilesFromAppFolder(
    backupRestoreProgress: BackupRestoreProgress
) {
    object : AsyncTask<Void?, Void?, Void?>() {

        override fun onPreExecute() {
            backupRestoreProgress.setMessage("Fetching backups...")
            backupRestoreProgress.showDialog()
            super.onPreExecute()
        }

        override fun doInBackground(vararg voidArr: Void?): Void? {
            return try {
                val list: Drive.Files.List =
                    googleDriveService!!.files().list()
                fileList = list.setQ("mimeType ='$METADATA_FILE_TYPE'")
                    .setSpaces(METADATA_FILE_PARENT)
                    .setFields("files(id, name,size,createdTime,modifiedTime)")
                    .execute() as FileList
                null
            } catch (e: IOException) {
                Log.d(TAG, "doInBackground: IOException ${e.message}")
                null
            }


        }

        override fun onPostExecute(voidR: Void?) {
            super.onPostExecute(voidR)
            backupRestoreProgress.dismissDialog()
            if (fileList != null && fileList!!.files != null) {
                Log.d(TAG, "onPostExecute: size ${fileList!!.size}")
                for (i in fileList!!.files.indices) {
                    val file2: File = fileList!!.files[i]
                    val name: String = file2.name
                    val id: String = file2.id
                    Log.d(TAG, "onPostExecute: $name id = $id")
                }
            }

        }
    }.execute(*arrayOfNulls<Void>(0))
}

@SuppressLint("StaticFieldLeak")
fun createFileInAppFolder(
    backupRestoreProgress: BackupRestoreProgress,
    drive: Drive,
    backUpActivity: BackUpActivity
) {
    object : AsyncTask<Void?, Void?, Void?>() {
        override fun onPreExecute() {
            backupRestoreProgress.setMessage("Uploading to drive...")
            backupRestoreProgress.showDialog()
            fileMetadata = File()
            fileMetadata!!.name = "test-text"
            fileMetadata!!.parents = Collections.singletonList(METADATA_FILE_PARENT)
            rawTextFile = getRawFile()
            Log.d(TAG, "onPreExecute: ${rawTextFile!!.path}")
            mediaContent = FileContent(METADATA_FILE_TYPE, rawTextFile)
            super.onPreExecute()
        }


        private fun getRawFile(): java.io.File {
            var inputStream = backUpActivity.resources.openRawResource(R.raw.demo)
            var file = java.io.File(filesDir, "text");
            var outputStream = FileOutputStream(file);

            var read = 0;
            val buffer = ByteArray(8 * 1024)

            while (inputStream.read(buffer).also { read = it } != -1) {
                outputStream.write(buffer, 0, read)
            }
            outputStream.close();
            inputStream.close();

            return file
        }

        override fun doInBackground(vararg params: Void?): Void? {
            return try {
                 googleDriveFile =
                    drive.files().create(fileMetadata, mediaContent)
                        .execute() as File

                Log.d(TAG, "doInBackground: id ${googleDriveFile.id}")
                null
            } catch (e: IOException) {
                e.printStackTrace()
                null
            }
        }

        override fun onPostExecute(voidR: Void?) {
            backupRestoreProgress.dismissDialog()
            super.onPostExecute(voidR)
            Handler(Looper.getMainLooper()).postDelayed({
                Log.d(TAG, "onPostExecute: id ${googleDriveFile.id}")
            },3000)
        }


    }.execute(*arrayOfNulls<Void>(0))
}

}

Basically I add four scope in google api console.

  1. https://www.googleapis.com/auth/drive.appdata
  2. https://www.googleapis.com/auth/drive.file
  3. https://www.googleapis.com/auth/drive.install
  4. https://www.googleapis.com/auth/drive
1
ok problem is solve its a issue of proguard rules check this answser stackoverflow.com/a/56466256/7265720Dishant Patel

1 Answers

0
votes

create in My drive section with “Untitile” file name

File upload / create / update is done in two parts. First you upload the metadata followed by the file stream itself. The metadata includes things like the name of the file, the folder (parents) that you would like to create it in. Without setting the metadata your file will be uploaded as untitled.

File fileMetadata = new File();
fileMetadata.setName("photo.jpg");
fileMetadata.setParents(Collections.singletonList("appDataFolder"));
java.io.File filePath = new java.io.File("files/photo.jpg");
FileContent mediaContent = new FileContent("image/jpeg", filePath);
File file = driveService.files().create(fileMetadata, mediaContent)
    .setFields("id")
    .execute();
System.out.println("File ID: " + file.getId());